2

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:

  1. Set the alarm
  2. Turn off the alarm
  3. "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!

2
  • 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
    Apr 26 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
    Apr 26 at 5:19
1

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);
}
1
  • 1
    Thank you so much for your help! I really appreciate it. The program works great now.
    – Geraldo
    Apr 26 at 11:52
2

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

}

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.