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
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!!
-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 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 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