IF (analogRead, voltage) statement within switch..case not working

Hi everyone, I'm working on my first switch..case statement after learning that you can't call two functions that run multiple outputs simultaneously, at different rates. I have a potentiometer outputting to analog pin A0, and I've been reading the serial monitor to confirm that the voltage into A0 is increasing and decreasing properly as I adjust the pot from end to end. The LED on pin 8 will not illuminate when I exceed the value in my if statement. I've tried "if(voltage > 1)" as well as "if(voltage > 0.0), and "case 2" does not seem to trigger. I'm only outputting to one pin (pin 8) for now, just to make sure I can get the code right before moving on to implementing millis() and timing for multiple outputs. Here is what I'm using for now:

void setup() {

  Serial.begin(9600);

}


void loop() {

byte theState=1;

int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);

switch (theState)
 {
  case 1:
    Serial.println(voltage);

    if(voltage > 0){
    
 theState = 2;
    }

    break;

   case 2:

   digitalWrite(8,HIGH);
   delay(5000);

   break;

 }

}

I tested the code in a more basic code before writing it in a state code, and the below code did trigger the LED on pin 8 just fine if the condition was met, so the IF statement does seem to work just fine outside of the switch..case scenario:

void loop() {

  int sensorValue = analogRead(A0);

  float voltage = sensorValue * (5.0 / 1023.0);


  if(voltage > 1.0)
  {
  digitalWrite(8,HIGH);
  delay(5000);
  }
}

Since the above IF statement works, and from what I've read, IF statements do work just fine in switch..case code, does anyone know what I may be doing wrong?? Thanks a bunch!!

-Andrew

AGrayson84:
Hi everyone, I'm working on my first switch..case statement after learning that you can't call two functions that run multiple outputs simultaneously, at different rates. I have a potentiometer outputting to analog pin A0, and I've been reading the serial monitor to confirm that the voltage into A0 is increasing and decreasing properly as I adjust the pot from end to end. The LED on pin 8 will not illuminate when I exceed the value in my if statement. I've tried "if(voltage > 1)" as well as "if(voltage > 0.0), and "case 2" does not seem to trigger. I'm only outputting to one pin (pin 8) for now, just to make sure I can get the code right before moving on to implementing millis() and timing for multiple outputs. Here is what I'm using for now:

void setup() {

Serial.begin(9600);

}

void loop() {

byte theState=1;

int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);

switch (theState)
{
 case 1:
   Serial.println(voltage);

if(voltage > 0){
   
theState = 2;
   }

break;

case 2:

digitalWrite(8,HIGH);
  delay(5000);

break;

}

}





I tested the code in a more basic code before writing it in a state code, and the below code [u]did[/u] trigger the LED on pin 8 just fine if the condition was met, so the IF statement does seem to work just fine outside of the switch..case scenario:



void loop() {

int sensorValue = analogRead(A0);

float voltage = sensorValue * (5.0 / 1023.0);

if(voltage > 1.0)
 {
 digitalWrite(8,HIGH);
 delay(5000);
 }
}





Since the above IF statement works, and from what I've read, IF statements do work just fine in switch..case code, does anyone know what I may be doing wrong?? Thanks a bunch!!

-Andrew

Try this out :slight_smile:
added the keyword static in the variable theState so it wouldn't forget the value alternatively you could make theState global.

void setup() {
  Serial.begin(9600);
}

void loop() {
  static byte theState = 1;

  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);

  switch (theState)
  {
    case 1:
      Serial.println(voltage);
      if (voltage > 0) {
        theState = 2;
      }
      break;

    case 2:
      digitalWrite(8, HIGH);
      delay(5000);
      break;
  }
}

Z

Thanks so much Z!!!!!!!!!! That was exactly what I needed-- the LED on pin 8 lit right up!

Sadly for me, the case statement did not work as expected. I was hoping that once the condition in case 1 was no longer true, case 2 would exit. What is happening is I'm apparently stuck in case 2 regardless of whether or not the voltage returns to 0, or even below "1.0" if I re-write the condition to "if(voltage > 1.0)".

Would you happen to mind suggesting what I may need to do in order to return to case 1, once the condition in case 1 is no longer true? Thanks again, I really appreciate the help you just gave me!! :slight_smile:

-Andrew

Would you happen to mind suggesting what I may need to do in order to return to case 1, once the condition in case 1 is no longer true?

You have to reset theState variable back to 1. Entering case 1 has nothing to do with the code inside of case 1. When do you want to turn the led off?

case 2:
      digitalWrite(8, HIGH);
      delay(5000);
      digitalWrite(8, LOW);
      theState = 1;
      break;

Thank you very much cattledog! Your revision to my case 2 has me just one last step away from doing what I would like! I tried it out and noticed the LED does turn off after 5 seconds if the condition is met and immediately is no longer met, but if the condition exists for more than a millisecond (say 3000 milliseconds or 3 seconds) the LED does not stay lit for the entire 5 seconds.

What I would definitely like is for the LED to stay one while the condition in case 1 is true, but also stay on for 5 seconds after the condition is no longer true, before returning to case 1 where it checks for the condition (again).

Sorry for not mentioning that previously, I didn't realize it wouldn't work out that way with how I had things, but thank you again for the help :slight_smile: If you happen to know what I need to do to get the LED to stay lit for 5 seconds after the condition in case 1 is no longer true once the condition has been met I'd definitely appreciate it!

I think I was able to put something together that seems to work:

void loop() {
  static byte theState = 1;

  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);

  switch (theState)
  {
    case 1:
    Serial.println(voltage);
      if (voltage > 1.0) {
        theState = 2;
      }
      break;

    case 2:
    Serial.println(voltage);
      digitalWrite(8, HIGH);
      delay(0);
    if (voltage > 1.0) {
      theState = 2;
    }
    else {

      theState = 3;
    }
      break;

    case 3:
    Serial.println(voltage);
      digitalWrite(8, HIGH);
      delay(5000);
      digitalWrite(8, LOW);
      theState = 1;
      break;
  }
}

I was hoping to not have to call the IF statements again like I did in case 2, though, since I'll eventually have a bunch of conditions in case 1. Is this the most efficient, cleanest way to do what I want? If so, I suppose I can write a function for the conditions and just call the conditions over again a little easier. Not sure if that is going to interfere with the timing of the outputs when I start using millis() for the outputs at different rates for the 5 second duration, but I'll probably find out when I get there haha.

AGrayson84:
Thank you very much cattledog! Your revision to my case 2 has me just one last step away from doing what I would like! I tried it out and noticed the LED does turn off after 5 seconds if the condition is met and immediately is no longer met, but if the condition exists for more than a millisecond (say 3000 milliseconds or 3 seconds) the LED does not stay lit for the entire 5 seconds.

What I would definitely like is for the LED to stay one while the condition in case 1 is true, but also stay on for 5 seconds after the condition is no longer true, before returning to case 1 where it checks for the condition (again).

Sorry for not mentioning that previously, I didn't realize it wouldn't work out that way with how I had things, but thank you again for the help :slight_smile: If you happen to know what I need to do to get the LED to stay lit for 5 seconds after the condition in case 1 is no longer true once the condition has been met I'd definitely appreciate it!

Trying to understand your desired sequence.
I'm thinking you would like to turn the led on above 1 volt and keep it on for 5 additional seconds after voltage drops below 1 volt.

This might help, it uses blink without delay timers to simplify your task.
(Not sure what baud rate you use so I guessed and set the serial port to 115200)

static unsigned long OnDelay;
unsigned long TimeOn = 5000; // 5 Seconds
void setup() {
  Serial.begin(115200);
  Serial.println("Testing");
  pinMode(8,OUTPUT);
  digitalWrite(8, LOW);// Shut off the output
  OnDelay = 0 - TimeOn; // Initialize OnDelay to be in the past so Timeout has occured and pin 8 is forced low
}

void loop() {
  static byte theState = 1;
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);

  if (voltage > 1.0){
    OnDelay = millis(); //Set the timer and keep it at start until voltage drops below 1 then the 5 seconds starts
// this will trigger the else portion of the blink without delay timer below
  }

// modified blink without delay timer
  if ( millis() - OnDelay >= (TimeOn)) { // if this is true then we are past our TimeOn Delay time 5 Seconds
    digitalWrite(8, LOW);// Shut off the output once time is up
  } else {
    digitalWrite(8, HIGH);// Before time is up Turin it on
  }

  // Debug Spam Timer Serial print takes time and can cause troubles in some cases. so we will limit the output to a reasonable level
  static unsigned long SpamTimer;
  if ((millis() - SpamTimer) >= (100)) { // see whats happening 10 times a second
    SpamTimer = millis();
    Serial.print(millis() - OnDelay); // Time used in miliseconds
    Serial.print(" ");
    Serial.print(voltage);
    Serial.print(" ");
    Serial.println(digitalRead(8)); // Lets take a look at digital pin 8 
  }
}

Thanks once again Z!! Yep you hit the nail on the head with what I was looking to achieve.... the reason for continuing to illuminate the LED for 5 seconds, after the condition is no longer true, is for me to have time to notice the LED and realize there was a problem, if though it is not a problem anymore. Just in case the condition is only met for a very brief time (milliseconds). I tried your code and it worked like a charm.... thanks so much for your help, and thanks to cattledog as well.... I really appreciate your guys' time and assistance!!!

-Andrew