Go Down

Topic: [Solved]Why is the button stopping my loop (Read 827 times) previous topic - next topic

Ockay16

Nov 07, 2017, 01:45 pm Last Edit: Nov 10, 2017, 02:13 pm by Ockay16
Hello guys, I'm pretty new to Arduino and have only completed the projects within my book and also a few on my own.
I've been searching a solution for my issue but couldn't find someone having the same problem, even though I'm pretty sure it's something really simple based on a function I must be using incorrectly.

I'm trying to create a car alarm system that if you open a door will flash the hazard lights after 4 minutes then make the horn go off after 5 minutes and then cut the fuel pomp (with a latching relay) after 6 minutes unless you press a hidden button.

After looking for similar needs I could come to the following code which is almost OK but I realized that if you push the button simulating the door switch at any moment, the sequence will stop.

If someone could tell me what I did wrong that would be very kind :)

Pierre

Code: [Select]

//Global Variables
const int doorSwitch = 2; // door switch linked to input 2
const int button1 = 3; // button 1 linked to input 3
const int button2 = 4; // button 2 linked to input 4
const int LED = 13; // to ON LED
const int hazard = 12; // to hazard lights
const int horn = 11; // to car horn
const int relay = 10; // to latchning relay (cuts off fuel pump)
int hornState = LOW;
 
unsigned long alarmOnMillis; // when alarm was activated
unsigned long hazardTurnOnDelay = 3000; // wait to turn on hazard after alarm activated
unsigned long hornTurnOnDelay = 4000; // wait to turn on horn after alarm activated
unsigned long relayTurnOnDelay = 5000; // wait to activat relay after alarm activated
unsigned long previousMillis = 0;
long interval = 500;           // horn ON and OFF interval
bool hazardOn = false; // 
bool hornOn = false; //
bool relayOn = false; //
bool alarmOn = false; //
 
void setup() {
 pinMode(doorSwitch, INPUT);
 pinMode(hazard, OUTPUT);
 pinMode(LED,OUTPUT);
 pinMode(horn,OUTPUT);
 pinMode(relay,OUTPUT);
 pinMode(button1,INPUT);
 pinMode(button2, INPUT);

}
 
void loop() {
 unsigned long currentMillis = millis();
if (digitalRead(doorSwitch) == HIGH){ // door switche pressed
  alarmOn = true;                     // alarm is ON
  alarmOnMillis = currentMillis;      // start timing for futur events
}
 if (alarmOn) {
        digitalWrite(LED,HIGH);       // alarm status LED turns ON
        hazardOn = true;              // hazard code activated
        hornOn = true;                // horn code activated
        relayOn = true;               // relay code activated
       }
       else{                          // if alarm is deactivated by button 2 (see above)
        (digitalWrite(LED,LOW));      // shuts done everything
        hazardOn = false;
        (digitalWrite(hazard,LOW));
        hornOn = false;
        (digitalWrite(horn,LOW));
        relayOn = false;
        (digitalWrite(relay,LOW));
       }
 
 if (hazardOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= hazardTurnOnDelay) {
                                      // check if hazard delay has passed
     digitalWrite(hazard, HIGH);      // when yes, starts hazard
   }
 }

if (hornOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= hornTurnOnDelay) {
                                      // check if horn delay has passed
    if (currentMillis - previousMillis >= interval) {
                                      // if yes, starts horn ON and OFF depending on interval
    previousMillis = currentMillis;

                                      // if horn is off turn it on and vice-versa:
    if (hornState == LOW) {
      hornState = HIGH;
    } else {
      hornState = LOW;
    }

                                      // set the horn with the hornState of the variable:
    digitalWrite(horn, hornState);
   }
}
}

if (relayOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= relayTurnOnDelay) {
                                      // check if relay delay has passed
     digitalWrite(relay, HIGH);       // starts relay
   }
}
 
 if (digitalRead(button1) == HIGH) {  // check if button 1 is pressed
  alarmOn = false;                    // turn off alarm
 }
}

DVDdoug

#1
Nov 07, 2017, 04:54 pm Last Edit: Nov 07, 2017, 05:01 pm by DVDdoug
Maybe the switch is wired wrong and you're shorting-out the power?  Maybe the switch wiring or the logic is backwards?   Did you try Digital Read Serial?

But, how do you know "the sequence" is stopping?

Did you write the whole program without testing anything?   You should "develop" and test your code a few lines at a time.

Do you have anything connected to simulate the outputs (horn, hazard, etc.)? 

In addition to monitoring the outputs, some Serial.print() messages to the serial monitor, such as "Door Open", "Door Closed", Sounding Alarm", etc.  That way you can "see" what your program is doing.  You can also print-out your timer states, etc.

And, for debugging purposes you can shorten your delays.

Ockay16

Hello DVDdoug, and thanks for your help!
Sorry I wasn't precise enough, yes I tested everything a few line at a time with 3 buttons and 4 LED on my breadboard to simulate the sequence. And I also shortened the sequence to 3 seconds then 1 seconde and 1 second.
Everything was working fine until I realized that the sequence would stop (and the blinking LED representing the horn) if I pressed again the button 1 witch is the door switch.

I was focused on learning about the change state command because I thought it would be the solution and then I saw that the wiring could be wrong but nothing worked.

Then I found the solution, I realized that my sequence is not stopping, it's just resetting.

Every time I push the button (doorSwitch) it sets my alarmOnMillis equal to currentMillis and hence restarts my timer for my delays with millis.

Adding the following if function did the trick by only allowing the alarmOnMillis to be set to currentMillis if the alarm is OFF. (there might be something more elegant though ;))

Code: [Select]

void loop() {
 unsigned long currentMillis = millis();
if ((alarmOn) == false){
if (digitalRead(doorSwitch) == HIGH){ // door switche pressed
  alarmOn = true;                     // alarm is ON
  alarmOnMillis = currentMillis;      // start timing for futur events
}


So the whole corrected code for now is:

Code: [Select]

//Global Variables
const int doorSwitch = 2; // door switch linked to input 2
const int button1 = 3; // button 1 linked to input 3
const int button2 = 4; // button 2 linked to input 4
const int LED = 13; // to ON LED
const int hazard = 12; // to hazard lights
const int horn = 11; // to car horn
const int relay = 10; // to latchning relay (cuts off fuel pump)
int hornState = LOW;
 
unsigned long alarmOnMillis; // when alarm was activated
unsigned long hazardTurnOnDelay = 3000; // wait to turn on hazard after alarm activated
unsigned long hornTurnOnDelay = 4000; // wait to turn on horn after alarm activated
unsigned long relayTurnOnDelay = 5000; // wait to activat relay after alarm activated
unsigned long previousMillis = 0;
long interval = 500;           // horn ON and OFF interval
bool hazardOn = false; // 
bool hornOn = false; //
bool relayOn = false; //
bool alarmOn = false; //
 
void setup() {
 pinMode(doorSwitch, INPUT);
 pinMode(hazard, OUTPUT);
 pinMode(LED,OUTPUT);
 pinMode(horn,OUTPUT);
 pinMode(relay,OUTPUT);
 pinMode(button1,INPUT);
 pinMode(button2, INPUT);

}
 
void loop() {
 unsigned long currentMillis = millis();
if ((alarmOn) == false){
if (digitalRead(doorSwitch) == HIGH){ // door switche pressed
  alarmOn = true;                     // alarm is ON
  alarmOnMillis = currentMillis;      // start timing for futur events
}
}
 if (alarmOn) {
        digitalWrite(LED,HIGH);       // alarm status LED turns ON
        hazardOn = true;              // hazard code activated
        hornOn = true;                // horn code activated
        relayOn = true;               // relay code activated
       }
       else{                          // if alarm is deactivated by button 2 (see above)
        (digitalWrite(LED,LOW));      // shuts done everything
        hazardOn = false;
        (digitalWrite(hazard,LOW));
        hornOn = false;
        (digitalWrite(horn,LOW));
        relayOn = false;
        (digitalWrite(relay,LOW));
       }
 
 if (hazardOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= hazardTurnOnDelay) {
                                      // check if hazard delay has passed
     digitalWrite(hazard, HIGH);      // when yes, starts hazard
   }
 }

if (hornOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= hornTurnOnDelay) {
                                      // check if horn delay has passed
    if (currentMillis - previousMillis >= interval) {
                                      // if yes, starts horn ON and OFF depending on interval
    previousMillis = currentMillis;

                                      // if horn is off turn it on and vice-versa:
    if (hornState == LOW) {
      hornState = HIGH;
    } else {
      hornState = LOW;
    }

                                      // set the horn with the hornState of the variable:
    digitalWrite(horn, hornState);
   }
}
}

if (relayOn) {
   if ((unsigned long)(currentMillis - alarmOnMillis) >= relayTurnOnDelay) {
                                      // check if relay delay has passed
     digitalWrite(relay, HIGH);       // starts relay
   }
}
 
 if (digitalRead(button1) == HIGH) {  // check if button 1 is pressed
  alarmOn = false;                    // turn off alarm
 }
}

Ockay16

Since I found the solution to my problem, would it be relevant to change the Subject title to "Project car alarm with anti carjacking system" and move it to project ?

That way I could describe the new updates to my code and show the final hardware.

What do the moderators think about that ?

TomGeorge

#4
Nov 07, 2017, 06:30 pm Last Edit: Nov 07, 2017, 06:31 pm by TomGeorge
Hi,
You should leave the thread here, but edit it with [SOLVED]  added to the subject, that way it will be identified as problem solved.

If you want to put your project in Projects, then put it there as a new thread and have circuit diagrams and explanation of the full code as a proper presentation, not as a problem solving subject.

Thanks., Tom... :)
Good to hear you got it working.. :)
Everything runs on smoke, let the smoke out, it stops running....

MarkT

I'd just add that its worth learning to use state-machines for this sort of interface - states and state-transitions
and a good way to understand and develop this sort of code.  What happens for each input change commonly
will depend upon what state you are in, so make that explicit in the code and it will be much easier to read.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Ockay16

TomGeorge, I followed your advice and I'm preparing an article into Projects to show what I want to do and maybe help people who had something similar in mind.

MarkT, I have so much thinks to learn with Arduino, I'm definitly going to give a look to states machines.

Thanks guys for your help.

Pierre

Go Up