0

PROBLEM STATEMENT:

  1. A circuit is measuring various parameters (Temperature, Humidity, etc.) through sensors connected to it continuously.
  2. When a Push Button is Pressed and Hold for 2 seconds in between the Arduino should enter into Setup mode.(I have used IF loop and millis() function to achieve this )
  3. In Setup mode there are 6 screens which will appear one after one.
  4. Once Arduino enters into Setup mode Switch case 0 (screen1) should appear (I have used serial monitor for the same).
  5. Now if I press the same push button and released within a moment the next Switch case 1 (screen2) should appear.
  6. Step 5 will be repeated till Switch case 5 (screen6).
  7. After Switch case 5 the loop rolls over to Switch case 0 (SCREEN1) then Switch case 1, Switch case 2, so on.
  8. If in between above Switch Case loop Push Button is Presses and Hold for 2 seconds the Switch case loop must get terminated and the Arduino should go back to MAIN LOOP() where it is measuring the sensor parameter.
  9. Again if the push button is Pressed and Hold for 2 seconds in between sensing process the Arduino should enter into Setup mode.

CONSIDERATIONS:

  1. Push Button is connected to Pin2 of Arduino (ACTIVE LOW)
  2. The input at Pin2 is considered as interrupt so that Arduino provides service to any moment of the time.
  3. Arduino serial monitor is used to demo the Screen1-Screen6 as output.
  4. 0.1uf Capacitor is used across the Push Button for debounce considerations. And 10K, 0.25W resistor is connected from VCC to Pin no.2
  5. The code for sensing parameters (Temperature, Humidity, etc.) is yet to be written.

ACHIEVEMENT: Upto Point No. 7 of PROBLEM STATEMENT the code is working fine.

BUG: If I press Push Button for 2 seconds in SWITCH CASE loop, Arduino is going out of the SWITCH CASE and going into MAIN LOOP() but again coming back to SWITCH CASE() loop. It should ask again to press Push Button for 2 Seconds to enter into Setup Mode.

const int btn = 2;     
const int ledPin =  13;     
int selector = 0;
boolean  volatile wait = false; 
const unsigned long event=2000;
unsigned long previous1=0;
unsigned long current1=0;
unsigned long sum1=0;
unsigned long previous2=0;
unsigned long current2=0;
unsigned long sum2=0;
bool buttonPress = false;
void setup() 
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(btn, INPUT);
attachInterrupt(digitalPinToInterrupt(btn),decoder,CHANGE);
}

void loop() 
{
  if (digitalRead(btn) ==LOW && !buttonPress) 
  {
    previous1 = millis();
    buttonPress = true;
  }
  else if (digitalRead(btn) == HIGH && buttonPress) 
  {
    current1 = millis();
    sum1=current1-previous1;
    Serial.println(sum1);
    Serial.println("SUM1");  
    if (sum1>=event)

       {  BREAK1:
          doSwitchCase();
          selector++;
          goto BREAK1; 
          if (selector >6) 
              {
                  selector = 0;
                  delay(500);
              }
        }
        buttonPress = false;
  }
  wait = true;
  interrupts();

}

void decoder() 
{
 noInterrupts();
 wait = false;
}


void doSwitchCase() 
{
  switch(selector) 
  {
  case 0:
    Serial.println("SCREEN1");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
    break;

  case 1:
    Serial.println("SCREEN2");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
    break;

  case 2:
   Serial.println("SCREEN3");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
   break;

  case 3:
   Serial.println("SCREEN4");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
   break;

  case 4:
   Serial.println("SCREEN5");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }   
   break;

  case 5:
  Serial.println("SCREEN6");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
  break;  
  }
}
1

One note before NEVER use goto in C++ its bad style and makes in an object oriented language to 99.9% no sense. To enter the switch case after a2 second press you have just to enter one statement t omy original proposal.I did not read your code as it gets unreadable the more functionality you want to add. Think about refactoring it or you will run out of luck to get help (as nobody tortues himself with caotic code of others:

const int btn = 2;
const int ledPin =  13;
int selector = 0;
const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;  // debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

bool buttonPress = false;
bool inMenu = false;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(btn, INPUT);
  }

void loop() {
  if (digitalRead(btn) == LOW && !buttonPress ) {
    buttonPressStart = millis();
    buttonPress = true;
  }
  // The routine is only triggered if a previous pressing took place, otherwise it's ignored
  else if (digitalRead(btn) == HIGH && buttonPress) {
    if (millis() - buttonPressStart > buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Long press: ");
      Serial.println(millis() - buttonPressStart);
      buttonPress = false;
      inMenu = false;
    }
    if (millis() - buttonPressStart < buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && !inMenu) {    // HERE IS A CHANGE
      Serial.print("First long press ");    // HERE IS A CHANGE
      inMenu = true;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Short press: ");
      Serial.println(millis() - buttonPressStart);
      doSwitchStatement();
      selector++;
      if (selector > 6) {
        selector = 0;
        delay(500);
      }
      buttonPress = false;
    }
  }
  // Here you could do other stuff as it is non blocking
}
doSwitchStatement(){...}// Stays the same as yours

I just changed 1 statement (and 1 debug msg) to achieve what you want see // HERE IS A CHANGE

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.