If statement does not work in Switch case

Hi everybody, I am doing this project about a exercise counter with different modes such as push-up and planking. These two modes can be selected via an MIT application which connects to the arduino uno board through bluetooth connection.

The problem I am facing is that the application is able to select the modes and display the initial texts, however, it does not continue to count the push-up. The items used are arduino uno, HC-05 bluetooth device, HC-SR04 ultrasonic sensor and a LCD I2C. Any advices on this issue?

#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); 
SoftwareSerial BT(0,1);                                       //TX, RX respectively for bluetooth connected to RX and TX pin on arduino board
const int trigPin = 8; //set pins for the ultrasonic sensor, button, buzzer and LCD
const int echoPin = 9;
const int buttonPin = 2;
const int buzzer = 13;

int value;        //for switch case
long signalDuration; //defining signalDuration as long as it can potentially store a large number
int signalDistance; //distance detected by sensor
int a; //number of counts
int z = 1;
int x = 1;
int buttonState = 0;
int GREEN = 5;
int YELLOW = 3;
int RED = 4;
int DELAY_GREEN = 5000;
int DELAY_YELLOW = 2000;
int DELAY_RED = 5000;

void setup() 
{
  Serial.begin(9600); // begin in 9600 baud 
  BT.begin(9600); //initialise BT module
  pinMode(trigPin, OUTPUT); //set pin modes
  pinMode(echoPin, INPUT);
  pinMode(buttonPin, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(YELLOW, OUTPUT);
  pinMode(RED, OUTPUT);
  lcd.init();
  lcd.backlight();
  lcd.begin (16,2);
  red_light();
}

void green_light()
{
  digitalWrite(GREEN, HIGH);
  digitalWrite(YELLOW, LOW);
  digitalWrite(RED, LOW);
}

void yellow_light()
{
  digitalWrite(GREEN, LOW);
  digitalWrite(YELLOW, HIGH);
  digitalWrite(RED, LOW);
}

void yellow_blink()
{
  digitalWrite(YELLOW,HIGH);
  delay(300);
  digitalWrite(YELLOW,LOW);
  delay(100);
}


void red_light()
{
  digitalWrite(GREEN, LOW);
  digitalWrite(YELLOW, LOW);
  digitalWrite(RED, HIGH);
}

void loop() 
{
  digitalWrite(trigPin, LOW); // send out an ultra sonic sound for 10 microseconds and measure the time it took for the sound to go from the trigpin to the echo pin
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  signalDuration = pulseIn(echoPin, HIGH);
  signalDistance = signalDuration * 0.034/2; //convert the time the signal took to travel to distance in cm
  
  buttonState = digitalRead(buttonPin); //these lines of code resets every integer and the lcd to the original state by the press of a button
  if (buttonState == HIGH) 
  {
    a = 0; //no. of push up counts
    z = 1;
    x = 1;
    tone(buzzer, 1000); // Send 1KHz sound signal...
    delay(100);        // ...for 1 sec
    noTone(buzzer);     // Stop sound...
    delay(100);        // ...for 1sec
    Serial.println(a);
    BT.println("Reset");
    BT.println("Count:");
    BT.println(a);
    lcd.clear ();
    lcd.setCursor(3,0);
    lcd.print("Reset"); 
    lcd.setCursor(3,1);
    lcd.print("Count:");
    lcd.setCursor(10,1);
    lcd.print(a);
    digitalWrite(RED,LOW);
    delay(100);
    digitalWrite(RED,HIGH);
    delay(300);
    digitalWrite(RED,LOW);
    delay(100);
    digitalWrite(RED,HIGH);
    delay(300);
    digitalWrite(RED,LOW);
  
  } 

  if (Serial.available() > 0) 
  {
    value = Serial.read();
    
     switch (value) 
     {
      case '1':                            //push-up mode 
    BT.println("Push-Up Mode Selected");
    BT.println("Begin in:");
    delay(1000);
    BT.println("3");
    delay(1000);
    BT.println("2");
    delay(1000);
    BT.println("1");
    delay(1000);
    BT.println("Go!");
  
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Push-Up Selected");
    delay(1000);
    lcd.clear();
    lcd.print("Begin in:");
    lcd.setCursor(0,1);
    lcd.print("3");
    delay(1000);
    lcd.clear();
    lcd.print("2");
    delay(1000);
    lcd.clear();
    lcd.print("1");
    delay(1000);
    lcd.clear();
    lcd.print("Go!");
    
    if (signalDistance < 12 ) //counts a push-up is distance detected is below 12cm
   {
    a ++; //print a point if a pushup has been done
    Serial.println(a);
    BT.println("Push-Up");
    BT.println("Counts:");
    BT.println(a);
    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("Push-Up");
    lcd.setCursor(3,1);
    lcd.print("Counts: ");
    lcd.setCursor(10,1);
    lcd.print(a);
    yellow_blink(); 
  }
  
  
     if (a == (1 * x) && z == (1 * x)) //this if statement plays a sound for every pushup
  { 
  tone(buzzer, 10000); // Send 1KHz sound signal...
  delay(100);        // ...for 1 sec
  noTone(buzzer);     // Stop sound...
  delay(100);        // ...for 1sec
    z ++;
    x ++;
  }

   while (signalDistance <= 12) 
   { //if the distance stays smaller then twelve for a while, this piece of code makes sure that only one point is given for one pushup
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      signalDuration = pulseIn(echoPin, HIGH);
      signalDistance = signalDuration * 0.034/2;
      delay(100);
   }
   while (signalDistance >= 13 && signalDistance <= 35) 
   { //prevents ultrasonic sensor from accidentally counting more as the distance fluctuates between 12cm
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      signalDuration = pulseIn(echoPin, HIGH);
      signalDistance = signalDuration * 0.034/2;
      delay(100);
   }
   break;
  }
  }
 

}

int or text....

I think switch works with INT only.

hi yes, i have initialised " int value;"

It’s perfectly fine as a char

ok dont used "1" only 1

No, not 1, not "1"… ‘1‘ was spot on…(the character 1 in ASCII)

For the rest OP Don’t post snippets (Snippets R Us!)

yes this works. However, the issue is that it stops working at the if statement.

 if (signalDistance < 12 ) //counts a push-up is distance detected is below 12cm
   {
    a ++; //print a point if a pushup has been done
    Serial.println(a);
    BT.println("Push-Up");
    BT.println("Counts:");
    BT.println(a);
    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("Push-Up");
    lcd.setCursor(3,1);
    lcd.print("Counts: ");
    lcd.setCursor(10,1);
    lcd.print(a);
    yellow_blink(); 
  }

As I said Don’t post snippets (Snippets R Us!)

yes i've posted the full code in the OP above

OP is you (Original Poster)
If there is only one case, the switch is overkill. Use an if

Once you exit the case you won’t go back in unless there is a new ’1’ coming through Serial, is that intended?

As for now, I only have the codes for a single case. The other cases i am still working on it.

The main problem now is that the code does not work after printing the LCD display. Meaning, it stops working at the if(signalDistance < 12).

Answer this

yes friend

So your BT sends 1 over and over again?

It only sends 1 if i press the button in the application.

So isn’t that a problem for your code

Run it manually and see how the serial available will get in your way as the loop() loops

1 Like

This may help:

I can see why you want to use the switch-case structure, as you have lots of different modes.

I'd recommend you break your code up into functional modules, eg

void countPushup()
{
    a ++; //print a point if a pushup has been done
    Serial.println(a);
    BT.println("Push-Up");
    BT.println("Counts:");
    BT.println(a);
    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("Push-Up");
    lcd.setCursor(3,1);
    lcd.print("Counts: ");
    lcd.setCursor(10,1);
    lcd.print(a);
    yellow_blink(); 
  }
1 Like