A advanced Arduino calculator?

So I thought about a new project: make an "advanced" calculator since online there are plenty of tutorials of simple ones. I have done already the circuit and I have only some problems with the code since this is only my third project on Arduino and I don't  know programming in C. So basically: when I switch on the device it shows me a long text which I can scroll using a pair of pushbuttons(when the text can't scroll anymore a led switches on). When I push them contemporanealy the device switches to calculator. And this is the code I made (I know there are plenty of errors):

#include <Keypad.h>
#include <LiquidCrystal.h>

long num1,num2 ;
double total;
char operation,button;

const byte ROWS = 4;
const byte COLS = 4;

char keys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','*'},
  {'C','0','=','/'}
};
byte rowPins[ROWS] = {A0,A1,A2,A3}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A4,A5,0,1}; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// === CONSTANTS AND GLOBALS ===
// -- PINS --
const int PIN_LCD_LED = 6;  // analog

const int PIN_ERR_LED = 7;  // digital
const int PIN_BUTTON1 = 8;  // digital
const int PIN_BUTTON2 = 9;  // digital

// -- LCD --
// PIN 12   -> RS
// PIN 11   -> Enable
// PINS 2-5 -> D4-7
LiquidCrystal lcd(12, 11, 2, 3, 4, 5);
// number of columns in the LCD
const int LCD_COLS = 16;
// LCD brightness [0, 255]
const int LCD_BRIGHTNESS = 128;
// LCD ON or OFF
int state_lcd = LOW;
// start position for text
int lcd_start = 0;

// -- LED --
// LOW -> LED is OFF - HIGH -> LED is ON
int state_led = LOW;
// stores time when turned LED on
unsigned long t0_led;
// timeout to turn the LED off
const int LED_TIMEOUT = 500;

// -- text to print --
// ASSUMPTION: text always longer than LCD_COLS, if not add a check in loop
const char TEXT[] = "After trying Helloworld I made this more advanced version...";
const int TEXT_LEN = (sizeof(TEXT) / sizeof(char)) - 1;
const int LCD_LIMIT = TEXT_LEN - LCD_COLS;
// === CONSTANTS AND GLOBALS END ===

// === INITIALIZATION ===
void setup()
{
  // -- SET DIGITAL PINS --
  pinMode(PIN_BUTTON1, INPUT);
  pinMode(PIN_BUTTON2, INPUT);

  pinMode(PIN_ERR_LED, OUTPUT);

  // -- SET UP LCD --
  lcd.begin(16,2);
  lcd.noDisplay();
  digitalWrite(PIN_LCD_LED, state_lcd);

  // ERROR LED is off when starting
  digitalWrite(PIN_ERR_LED, state_led);
  // -- read buttons --
  int state_button1 = digitalRead(PIN_BUTTON1);
  int state_button2 = digitalRead(PIN_BUTTON2);

    // pushed button 1 -> try to scroll left or turn LED on if can't
    if(HIGH == state_button1)
    {
      if(lcd_start > 0)
      {
        lcd_start--;

        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);

        delay(200);
      }
      else
      {
        state_led = HIGH;
        digitalWrite(PIN_ERR_LED, state_led);

        t0_led = millis();
      }
    }

    // pushed button 2 -> try to scroll right or turn LED on if can't
    if(HIGH == state_button2)
    {
      if(lcd_start < LCD_LIMIT)
      {
        lcd_start++;

        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);

        delay(200);
      }
      else
      {
        state_led = HIGH;
        digitalWrite(PIN_ERR_LED, state_led);

        t0_led = millis();
      }
    }

    // -- print text on the LCD --
    for(int i = 0; i < LCD_COLS; i++)
    {
      lcd.setCursor(i, 0);
      lcd.print(TEXT[lcd_start + i]);
    }

    // ERROR LED is ON
    if(HIGH == state_led)
    {
      unsigned long td = millis() - t0_led;

      // LED has been ON for more than LED_TIMEOUT ms. -> turn it OFF
      if(td > LED_TIMEOUT)
      {
        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);
      }
    }
  }

  // normally 20FPS
 

// === INITIALIZATION END ===

// === MAIN LOOP ===
void loop()
{
  // == LCD STILL OFF ==
  if(HIGH == state_lcd)
  {
    // pushing both buttons -> turn LCD on
    int state_button1 = digitalRead(PIN_BUTTON1);
    int state_button2 = digitalRead(PIN_BUTTON2);
   
    if(HIGH == state_button1 && HIGH == state_button2)
    {
      analogWrite(PIN_LCD_LED, LCD_BRIGHTNESS);

      lcd.display();

      state_lcd = HIGH;

      delay(250);
    }
  }
 
  else  // == LCD ON ==
  {
    // Loops are convenient for reading key press from keypad
    while(1) // First loop. Here we read keypad and compose our first number. It does so untill we press operation button and break's out of loop or 'C' and it starts from beginning of this loop
    {

       
        button = customKeypad.getKey(); // Button read
        if (button=='C') // If user wants to resset while he is writing first number
        {
          num1=0;
          num2=0;
          total=0;
          operation=0;
          lcd.clear();
        }
       
        if (button >='0' && button <='9') // If user pressed numeric value, 1 character at a time.
        {
          num1 = num1*10 + (button -'0'); // Our numeric values are 0-9 witch means they are in first decade, when we multiply with 10 we basicaly add zero after number,
          // than we add a new number entered to that zero spot. As for (button -'0') this is simple ASCII table "trick" 0...9 in ASCII table are 48 ... 57,
          // so by subtracting '0' from any of them we get their value in decade system ex. char '5' = 53 in decade numeric system minus 48 for zero char gives us value of actual 5,
          // if our previous number was ex. 25 we get 250 by multiplying it with 10 and then we add 5 and we get 255 witch gets printed on LCD.
          lcd.setCursor(0,0); // Select first row on lcd
          lcd.print(num1); // Print current number1
        }
        if (num1 !=0 && (button=='-' || button=='+' || button=='*' || button=='/')) // If user is done inputing numbers
        {
          operation = button; // operation remembers what mathematical operation user wants on numbers
          lcd.setCursor(0,1); // set cursor to row 2
          lcd.print(operation); // print our operator
          break;
        }

    }
   
    while(1) // Second while loop, it loops untill user has pressed '=' or 'C'. so it either prints total or ressets program
    {
        if (button =='C'){break;} // This covers case where user pressed operator and still wants to reset
        button = customKeypad.getKey();
        if (button=='C') // Making sure user wants to reset at anytime
        {
          num1=0;
          num2=0;
          total=0;
          operation=0;
          lcd.clear();
          break;
        }
        if (button >='0' && button <='9') // Getting chars from keypad for number 2
        {
          num2 = num2*10 + (button -'0');
          lcd.setCursor(1,1);
          lcd.print(num2);
        }
        if (button == '=' && num2 !=0)// If button pressed was '=' its the end of the road. Calls domath() subroutine does calculation and print our results
        {
          domath();
                  
          break; 
        }
    }
    while(1)
    {
      // After all is done this loop waits for 'C' key to be pressed so it can reset program and start over.
      if (button =='C'){break;} // This line is side effect of previous loop since if user pressed 'C' it breaks out of previous loop and continues here.So we need to break this one aswell or user would need to press 'C' 2 times
      button = customKeypad.getKey();
      if (button =='C')
        {
           lcd.clear();
           lcd.setCursor(0,0);
           num1=0;
           num2=0;
           total=0;
           operation=0;
           break;
        }
    }

}
void domath() // Simple switch case to pick what operation to do, based on button pressed by user.
{
  switch(operation)
    {
      case '+': // Addition
          total = num1+num2;
          break;
     
      case '-': // Subtraction
          total = num1-num2;
          break;
     
      case '/': // Division. Could add error for division by zero, or change line in second loop where it waits for '=' char to if (button == '=' && num2 != 0) this will halt program untill num2 is not zero and then continue
          total = (float)num1/(float)num2;
          break;
     
      case '*': // Multiplication
          total = num1*num2;
          break;
         
    }
    // Based on case selected print our total and
    lcd.setCursor(0,1);
    lcd.print('=');
    lcd.setCursor(1,1);
    lcd.print(total);
  
   }

}

// === MAIN LOOP END ===


Waiting your answers,
Cristian

Picture of A advanced Arduino calculator?
thomasmckenna6 months ago

I think it will not be easy to do)

steveastrouk6 months ago

This is what happens when you copy code with no understanding. Work your way through it one line at a time and see how it hangs together. See if there are any further comments on All About Circuits, where the whole project has been taken from.

Downunder35m6 months ago

And what would be your question or problem?

IlirD2 (author)  Downunder35m6 months ago

The code. Can you help me fixing the errors. There's not any problem for the time.Waiting your answers