I am having some trouble getting my board to perform the function I want it to perform. This is a project I have due in a few days, and I have hit a wall I just can't seem to get past. Now, I will say the issue is definitely in the way I coded the program, but I don't really know enough about Arduino (and coding) to understand why it is not working. My board is properly hooked up to use 3LEDs, a speaker, a photoresistor, and an ultrasonic sensor (detects distances). My Arduino program takes serial input from a GUI that I created in MATLAB. I have verified the MATLAB code is good, and the serial port is communicating properly. I have made an alarm that goes off when light or motion is detected. It has 3 basic functions:
- Set the alarm
- Turn off the alarm
- "snooze" which just delays for 5 minutes and then the alarm goes off
The snooze and turn off alarm parts of my code are working great, but the set alarm is where I am having trouble. The snooze option sets off the yellow LED to verify it is on "snooze". The red LED comes on when the alarm is currently going off. The green LED comes on when the alarm is set. When I try to activate the "Set Alarm" function, which is case 'O' in a switch case, the light does come on, but the sensors are not picking up any input as far as I can tell. Again I have verified the pins and everything are set up correctly as I have isolated those and verified they work. I have a suspicion that the problem is because I have the sensors initialed within the switch case of the "Set Alarm" (case 'O', not 0). I don't really know how to get the sensors to run continually within that switch case until the "turn alarm off" case is activated. I need the sensors to be activated/reset by "Set Alarm" case.
**I am also new to this forum so please let me know if I am missing anything!
here is my code:
void setup()
{
Serial.begin(115200);
pinMode(12,OUTPUT); //RED
pinMode(13,OUTPUT); //GREEN
pinMode(14,OUTPUT); //YELLOW
pinMode(16,OUTPUT); //SPEAKER
pinMode(4,INPUT); //Echo
pinMode(2,OUTPUT); //Trig
}
void loop()
{
if(Serial.available() >0)
{
char b = Serial.read();
switch(b)
{
//Turn Alarm off
case 'A' :
{
digitalWrite(12,LOW);//red off
digitalWrite(13,LOW); // green off
digitalWrite(14,LOW); //yellow off
noTone(16);
delay(500);
}
break;
// Set alarm
case 'O' :
{
int light;
light = analogRead(0);
unsigned long distance;
digitalWrite(2,LOW);
delayMicroseconds(2);
digitalWrite(2,HIGH);
delayMicroseconds(10);
digitalWrite(2,LOW);
distance = pulseIn(4,HIGH);
distance = distance/58; //centimeters
delay(500);
digitalWrite(12,LOW); //red off
digitalWrite(14,LOW); //yellow off
digitalWrite(13,HIGH); //green on
if (light < 400)
{
digitalWrite(12,HIGH);//red on
digitalWrite(13,LOW); // green off
digitalWrite(14,LOW); //yellow off
tone(16,832);
delay(500);
}
if (distance < 50)
{
digitalWrite(12,HIGH);//red on
digitalWrite(13,LOW); // green off
digitalWrite(14,LOW); //yellow off
tone(16,832);
delay(500);
}
}
break;
// snooze option
case 'Z' :
{
digitalWrite(14,HIGH); //yellow on
digitalWrite(12,LOW); //red off
digitalWrite(13,LOW); // green off
noTone(16);
delay(300000UL);
digitalWrite(12,HIGH); //red on
digitalWrite(13,LOW); // green off
digitalWrite(14,LOW); //yellow off
tone(16,832);
delay(500);
}
break;
}
}
}
Any help would be very much appreciated!
-
Hi Geraldo and welcome to Arduino Stack Excange. Please take the tour and read all the way to the bottom to earn your first badge. Your code appears to missing the top section with your includes and global variable declaration. Could you please check and add it.sa_leinad– sa_leinad2021年04月26日 05:09:54 +00:00Commented Apr 26, 2021 at 5:09
-
Please use the Auto Format to format your code. In the Arduino IDE, go to Tools > Auto Format or use the keyboard shortcut Ctrl + T.sa_leinad– sa_leinad2021年04月26日 05:19:46 +00:00Commented Apr 26, 2021 at 5:19
2 Answers 2
The most simplest way to troubleshoot a program is to add Serial.println();
statements everywhere. For example you could add Serial.println("Setting Alarm");
in the first line of the case for setting the alarm.
You will notice that the set alarm code only runs once through, instead of continously. You should use the case to set a mode or a state in where the sensors are checked continously.
First I would create a variable called setAlarmMode
and set it to false
.
setAlarmMode = false;
Then I would remove the reading of sensors from the case statement and instead set setAlarmMode
to true
.
// Set alarm
case 'O' :
{
Serial.println("Setting Alarm");
// Set the LEDs for the mode
digitalWrite(12, LOW); //red off
digitalWrite(14, LOW); //yellow off
digitalWrite(13, HIGH); //green on
setAlarmMode = true;
}
break;
Now I would insert this code outside of the if (Serial.available() > 0)
code block:
// Read sensors
if (setAlarmMode == true)
{
Serial.println("Reading sensors");
int light;
light = analogRead(0);
Serial.print("Light sensor value: ");
Serial.print(light);
unsigned long distance;
// Do trigger pulse
digitalWrite(2, LOW);
delayMicroseconds(2);
digitalWrite(2, HIGH);
delayMicroseconds(10);
digitalWrite(2, LOW);
distance = pulseIn(4, HIGH);
distance = distance / 58; //centimeters
Serial.print(" Distance sensor value: ");
Serial.println(distance);
if (light < 400)
{
Serial.println("Light below threshold");
setAlarmMode = false;
activateAlarm();
}
if (distance < 50)
{
Serial.println("Distance below threshold");
setAlarmMode = false;
activateAlarm();
}
delay(500);
}
I have also created a function to hold the common code of showing the alarm:
void activateAlarm(void)
{
digitalWrite(12, HIGH); //red on
digitalWrite(13, LOW); // green off
digitalWrite(14, LOW); //yellow off
tone(16, 832);
delay(500);
}
-
1Thank you so much for your help! I really appreciate it. The program works great now.Geraldo– Geraldo2021年04月26日 11:52:16 +00:00Commented Apr 26, 2021 at 11:52
The problem is that, if you enter 'O', you go thorugh the set alarm case only once. If no alarm was triggered, it just falls through the if statements and is then back in the main loop. In that main loop, you only check for your sensors, if something was entered to the serial console. That means if you do not enter anything during a loop, nothing happens.
The solution to this would be to implement a finite state machine. That means you use a state variable for the switch case. You then update your state based on the state and the external conditions. In your case you can just update the state using user input.
I changed your code a bit for a possible (but bad) implementation. I did not verify or check for errors. I recommend using a more solid implementation, if you plan to build upon this code for more complex behavior.
char state = 'A'; //initialize state in Off state
char b; // make user input variable global
void setup()
{
Serial.begin(115200);
pinMode(12, OUTPUT); //RED
pinMode(13, OUTPUT); //GREEN
pinMode(14, OUTPUT); //YELLOW
pinMode(16, OUTPUT); //SPEAKER
pinMode(4, INPUT); //Echo
pinMode(2, OUTPUT); //Trig
}
void loop()
{
if (Serial.available() > 0)
{
b = Serial.read();
}
// close user input section
switch (state) // run switch case every loop
{
//Turn Alarm off
case 'A' :
{
digitalWrite(12, LOW); //red off
digitalWrite(13, LOW); // green off
digitalWrite(14, LOW); //yellow off
noTone(16);
delay(500);
}
break;
// Set alarm
case 'O' :
{
int light;
light = analogRead(0);
unsigned long distance;
digitalWrite(2, LOW);
delayMicroseconds(2);
digitalWrite(2, HIGH);
delayMicroseconds(10);
digitalWrite(2, LOW);
distance = pulseIn(4, HIGH);
distance = distance / 58; //centimeters
delay(500);
digitalWrite(12, LOW); //red off
digitalWrite(14, LOW); //yellow off
digitalWrite(13, HIGH); //green on
if (light < 400)
{
digitalWrite(12, HIGH); //red on
digitalWrite(13, LOW); // green off
digitalWrite(14, LOW); //yellow off
tone(16, 832);
delay(500);
}
if (distance < 50)
{
digitalWrite(12, HIGH); //red on
digitalWrite(13, LOW); // green off
digitalWrite(14, LOW); //yellow off
tone(16, 832);
delay(500);
}
}
break;
// snooze option
case 'Z' :
{
digitalWrite(14, HIGH); //yellow on
digitalWrite(12, LOW); //red off
digitalWrite(13, LOW); // green off
noTone(16);
delay(300000UL);
digitalWrite(12, HIGH); //red on
digitalWrite(13, LOW); // green off
digitalWrite(14, LOW); //yellow off
tone(16, 832);
delay(500);
}
break;
}
state = b; // update state based on input
}
Explore related questions
See similar questions with these tags.