Arduino calculator with potentiometer and button(richshield)

Hello, I got a task to build a calculator, which devides, subtracts, adds and times the numbers between -10 and 10 using a potentiometer to select them and a button to switch between 4 modes:
1 mode - pick a number using the potentiometer and store its value
2 mode - pick an operator( ‘a’ (add), ‘s’ (subtract), ‘t’ (times), ‘d’ (divide)) using the potentiometer and store it
3 mode - pick a second number and store it
4 mode - do the calculation and display the result

I believe that I am using an arduino uno and a rich shield with a 4-digit display, potentiometer, 2 buttons, 4 leds and some other stuff.
I have been working on it for 2 days and got hardstuck on the following:
So, our teacher told us to use sequence state pattern, but when I tried it , it wasn’t very successful, so I wrote some code and managed to get mode 1 working but the problem is that in order to work the if-statement should be outside the button-if-statement, and when I try to go back to the button the state becomes 0 again and it sends me back to mode1 but without this state I can’t even run mode1, so I just can’t figure out how to switch between modes, I either skip mode1 and go to mode2 directly ot jsut stuck to mode1 only. I know that I should use this sequence state patter but can’t figure out exactly how I should do it. This is my first post on the forum and also my first arduino task. I would be very thankful for any tipps that you, guys, can give me!!

Here is my code:

#include <DHT11.h>
#include <Display.h>
#include <TM1637Display.h>



const int number1;//imput
const int number2;//input
float result;//output
const int POTPIN = A0;//potentionmeter
const int LED_RED = 4;//red led
const int LED_GREEN = 5;//green led
const int LED_BLUE = 6;//blue led
const int LED_YELLOW = 7;//yellow led
const int BUTTON = 9;//left button
int lastButtonState = HIGH;
int state = -1;

void setup() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_YELLOW, OUTPUT);
  pinMode(POTPIN, INPUT);

  Display.clear();
  Serial.begin(9600);

}


void loop() {
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if ( buttonState == LOW)//mode 1
    {

      Display.show("____");
      digitalWrite(LED_RED, HIGH);
      digitalWrite(LED_GREEN, HIGH);
      digitalWrite(LED_BLUE, HIGH);
      digitalWrite(LED_YELLOW, HIGH);
      delay(2000);
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_BLUE, LOW);
      digitalWrite(LED_YELLOW, LOW);
      delay(1000);
      digitalWrite(LED_BLUE, HIGH);
      state = 0;
      if (state == 1)//mode 2
      {
        digitalWrite(LED_BLUE, HIGH);
        state = 2;

      }
    }

    lastButtonState = buttonState;

  }
  if (state  == 0 )
  {
    int value = analogRead(POTPIN);//read the potentiometer
    int number_1 = map(value, 0, 1023, -10, 10);//map the values
    Display.show(number_1);
    

  }
  
  else if (buttonState ==  LOW) {//button pressed again

     state = 1;

  }

  if (state == 2 )
  {
    int value = analogRead(POTPIN);
    int percentage = map(value, 0, 1023, 0, 100);
    if ( percentage <= 25)
    {
      Display.show("a");

    }
    else if ( percentage > 25 && percentage <= 50)
    {

      Display.show("s");
    }
    else if (percentage > 50 && percentage <= 75)
    {
      Display.show("t");

    }
    else
    {
      Display.show("d");

    }

  }

}
      state = 0;
      if (state == 1)//mode 2

How could 'state' ever equal one, immediately after being set to zero?

Here is the thing mate, I tried writing:

state = 0;
      if (state == 0){//mode1
      Display.show("____");
      digitalWrite(LED_RED, HIGH);
      digitalWrite(LED_GREEN, HIGH);
      digitalWrite(LED_BLUE, HIGH);
      digitalWrite(LED_YELLOW, HIGH);
      delay(2000);
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_BLUE, LOW);
      digitalWrite(LED_YELLOW, LOW);
      delay(1000);
      digitalWrite(LED_BLUE, HIGH);
      int value = analogRead(POTPIN);//read the potentiometer
      int number_1 = map(value, 0, 1023, -10, 10);//map the values
      Display.show(number_1);
      state = 1;
}else{
  if (state == 1){//mode 2
      ....
      
      state = 2;
  }
}....

but when I do that it reads the potentiometer only 1 time when I press the button and I can't change the value of number_1, so my teacher told me to get it in a seperate if-statement, when I do that it works find but I just don't get how to get back to the button and continue with the other modes. I am doing somethign fundamentally wrong and I know it but I don't know how to fix it.

adbspoti: but when I do that it reads the potentiometer only 1 time when I press the button and I can't change the value of number_1, so my teacher told me to get it in a seperate if-statement, when I do that it works find but I just don't get how to get back to the button and continue with the other modes. I am doing somethign fundamentally wrong and I know it but I don't know how to fix it.

You are going about it wrong. The button should only change the mode, then you can make the mode processing code separate. That way you can stay in a mode as long as you need to.

Does each LED represent a mode?

Here is how I would do the loop processing. You can fill in the blanks:

void loop() 
{
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if (buttonState == LOW)
    {
      // Go to next state
      state++;
      state %= 4;
    }
    delay(50); //debounce
    lastButtonState = buttonState;
  }
  
  switch (state)
  {
    case 0:
      // mode 0 processing
      break;
      
    case 1:
      // mode 1 processing
      break;
      
    case 2:
      // mode 2 processing
      break;
      
    case 3:
      // mode 3 processing
      break;
  }
}

Yeah exactly! I figured this, but can you tell me how exactly do I make the button switch modes and how do I get into a mode when I want to write the code for it? I mean I can write:

if(state == 0) { the things that should happen in mode1

} if(state == 1) { things for mode2

}

That's if each mode is represented by a state, but once again I am not sure how to make the button switch them. Otherwise yeah, I understand very clearly what you want me to do. I will be very thankful if you can help me with this.

adbspoti: Yeah exactly! I figured this, but can you tell me how exactly do I make the button switch modes and how do I get into a mode when I want to write the code for it? I mean I can write: That's if each mode is represented by a state, but once again I am not sure how to make the button switch them. Otherwise yeah, I understand very clearly what you want me to do. I will be very thankful if you can help me with this.

I updated my post with the code. You may not have seen it.

Ahh I see it now, so my question is:

Can I replace this:

void loop()
{
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if (buttonState == LOW)
    {
      // Go to next state
      state++;
      state %= 4;
    }
    delay(50); //debounce
    lastButtonState = buttonState;
  }

with this:

void loop()
{
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if (buttonState == LOW)
    {
      if (state == 0) {
        
        state = 1;
      } else {
        if (state == 1) {

          state = 2;
        } else {
          if (state == 2) {

            state = 3;
          }
        }
        else {
          if (state == 3) {

            state = 0;

          }
        }
      }


    }

  }
  delay(50); //debounce
  lastButtonState = buttonState;
}

and if I write this, would I be able to change the modes with one push of the button?

You could replace all that elaboration with

state++;
if (state > 3) state = 0;

adbspoti: Ahh I see it now, so my question is:

Can I replace this:

void loop()
{
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if (buttonState == LOW)
    {
      // Go to next state
      state++;
      state %= 4;
    }
    delay(50); //debounce
    lastButtonState = buttonState;
  }

with this:

void loop()
{
  int buttonState = digitalRead(BUTTON);
  if ( buttonState != lastButtonState)
  {
    if (buttonState == LOW)
    {
      if (state == 0) {
        
        state = 1;
      } else {
        if (state == 1) {

         state = 2;        } else {          if (state == 2) {

           state = 3;          }        }        else {          if (state == 3) {

           state = 0;

         }        }      }

   }

 }  delay(50); //debounce  lastButtonState = buttonState; }

and if I write this, would I be able to change the modes with one push of the button?

Yes you can replace it but it will have exactly the same effect. Either way you can change modes by pushing the button once.

aarg: You could replace all that elaboration with

state++;
if (state > 3) state = 0;

or

      state++;
      state %= 4;

Alright mate, I will try some stuff out and will ask if I need further help. Thank you very much for the assistance! It's appreciated.

adbspoti: Alright mate, I will try some stuff out and will ask if I need further help. Thank you very much for the assistance! It's appreciated.

No problem. It is easier to test the program in small pieces. I would just put the button code to change the state and display the state. Once that works then add the switch statement to process that slowly adding functionality to the states testing a little bit at a time.

ToddL1962:
or

      state++;

state %= 4;

or

      state++;
      state &= 3;