Hello. A group of friends and I are working on a project for a competition. It's very complicated to explain and instead of trying to have someone do it for me...I'd like to learn how to do it. Basically I want to wait 30 seconds until the led turns on. If a switch is pressed anywhere in that 30 second timeframe, it will remain off. If not, after the 30 seconds has gone by, I want the LED to turn on. This is the basic way my project to work as far as code goes but with a GSM module. I don't want to use a delay because I do not want to hold up the loop for 30 seconds. Any help would be appreciated. I'm sorry if this is a stupid question ...
You, sure, just post your code and where you are stuck.
Do remember, millis() is just like a clock. No matter in what time zone you're clock is, you will always be able to determined the time that has passed. "17:50" - "17:05" = 45 minutes but "1:05" - "0:20" = 45 minutes as well. millis() is no different Only in ms and the "origin" is the moment the Arduino is started.
I can't post code without code tags due to me being on my phone and don't have access to a computer until tomorrow evening. My project is a GSM module that when two wires pull apart and break the circuit, it will start a 30 second timer. If a cancel button isn't pressed within that 30 seconds, then it will proceed to send emergency services your current GPS location. This doesn't work with a delay. Millis is the only other thing I can think of to do this correctly. I wish I could explain this better to you ear to ear but Arduino forum is the only way...thanks for the quick reply I really appreciate it
Use millis() as a timer who's time of reference is the moment the wire is broken
Using millis() timing is like sex.
Before you try the first time, it sounds exciting, then you realise it’s great but has overheads (like a partner).
Then as you figure it out, you wonder how you lived without it!
Finally your life is perfect until your programmer dies, or you change to a new target.
Grab it with both hands and enjoy the ride, you’ll have to start all over again one day - perhaps with self-modifying code. (Irrelevant but it fit the metaphor!)
“Using millis() timing is like sex. ”
???
“Grab it with both hands and enjoy the ride,“
Then you’ll discover Timer objects.
Josephm3502:
Very confused with millis...
Expound on the part of millis that's confusing.
Very confused with millis
Have a look at Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.
My teacher and I came with this. we basically have it set up so that when the wires get pulled apart, it begins a timer. every second the timer adds one to the count. after 30 seconds has elapsed, 30 counts have been made. once it goes greater than 30, it stops and begins to call. this part of it works. is there an easy way to check whether or not the button is pressed while the count is going up? our code looks like it should detect the button while it is counting but that is not the case according to the serial monitor.
#include "Adafruit_FONA.h"
#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST); //define fona
// constants
const int buttonPin = 5 ; // button for auto emergency distress
const int ledPin = 13; // LED for distress will be called
const int recordPin = 11;
// variables
int buttonState = 1; //start with harness connected
char gps_string[ 140 ]; //define the GPS information as a string
void setup() {
fonaSerial->begin(4800); //begin software serial at 4800 baud
fona.begin(*fonaSerial); //fona begins to utilize software serial
fona.enableGPS(true); //enable GPS function
fona.getGPS( 0, gps_string, 140 ); //get the GPS location as a reference
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
pinMode(recordPin, OUTPUT); //set the digital record pin as an output
}
void loop() {
buttonState = digitalRead(buttonPin); //read for button push every loop
fona.getGPS( 0, gps_string, 140 ); //update GPS info every loop
if (buttonState == HIGH) { //if pin is high (harness still connected) keep everything off
digitalWrite(ledPin, LOW);
digitalWrite(recordPin, LOW);
fona.hangUp();}
else { //if pin is low (harness tripped) turn everything on
digitalWrite(ledPin, LOW);
delay(5000);
fona.sendSMS("5555555555", "Hello, is Dillan Holiday. My Hunters Life Line has just tripped. I may or may not need assistance. Emergency services have been contacted. Here are my current GPS coordinates:");
delay(2500);
fona.sendSMS("5555555555", gps_string );
delay(5000);
fona.callPhone("5555555555");
delay(7500);
digitalWrite(recordPin, HIGH);
delay(500);
digitalWrite(recordPin, LOW);
delay(60000);
}
}
is there an easy way to check whether or not the button is pressed while the count is going up?
Yes.
Remove all those delay()s and read this.
Several things at the same time.
https://forum.arduino.cc/index.php?topic=223286.0
My teacher and I came with this. we basically have it set up so that when the wires get pulled apart, it begins a timer. every second the timer adds one to the count. after 30 seconds has elapsed, 30 counts have been made. once it goes greater than 30, it stops and begins to call.
There is nothing in the code you posted which does any of that.
Josephm3502:
Basically I want to wait 30 seconds until the led turns on. If a switch is pressed anywhere in that 30 second timeframe, it will remain off. If not, after the 30 seconds has gone by, I want the LED to turn on.
You need to think about this problem in an upside-down way. Reset the timer every time the switch is pressed. Then if it has not been pressed for 30 secs the LED can turn on. Like this pseudo code (assumed to be within loop() )
if (switch is pressed) {
timeSwitchWasLastPressed = millis()
}
if (millis() - timeSwitchWasLastPressed >= 30000) {
turn led on
}
...R
Im sorry i copied the wrong code as I'm doing this through teamviewer on my schools computer...here is the right code. here is the code i was talking about earlier...
#include "Adafruit_FONA.h"
#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST); //define fona
// constants
const int buttonPin = 5 ; // button for auto emergency distress
const int ledPin = 13; // LED for distress will be called
const int recordPin = 11;
const int cancelPin = 6; //If cancel button on harness is pushed to cancel the call
// variables
int buttonState = 1; //start with harness connected
char gps_string[ 140 ]; //define the GPS information as a string
int ThirtySecondCounter = 0; //Number of seconds in thirty second count after pin was pulled
int cancelState = 0; //begin with the cancel button not pressed
void setup() {
fonaSerial->begin(4800); //begin software serial at 4800 baud
fona.begin(*fonaSerial); //fona begins to utilize software serial
fona.enableGPS(true); //enable GPS function
fona.getGPS( 0, gps_string, 140 ); //get the GPS location as a reference
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
pinMode(recordPin, OUTPUT); //set the digital record pin as an output
pinMode(cancelPin, INPUT); //set the cancel button as an input
Serial.begin(4800);
}
void loop() {
buttonState = digitalRead(buttonPin); //read for button push every loop
fona.getGPS( 0, gps_string, 140 ); //update GPS info every loop
Serial.print("ButtonState is: ");
Serial.println(buttonState);
Serial.print("cancelState is: ");
Serial.println(cancelState);
if (buttonState == 0) { //if pin is high (harness still connected) keep everything off
digitalWrite(ledPin, LOW);
digitalWrite(recordPin, LOW);
fona.hangUp();}
if (buttonState == 1) { //if pin is low (harness tripped) turn everything on
while (ThirtySecondCounter <=30){
cancelState = digitalRead(cancelPin); //read for cancel push
ThirtySecondCounter = ThirtySecondCounter +1;
Serial.print("ThirtySecondCounter is: ");
Serial.println(ThirtySecondCounter);
if (cancelState == 1) {
Serial.print("Cancel is pushed!");
}
delay (1000);
}
if (ThirtySecondCounter > 30 && cancelState == 0){
digitalWrite(ledPin, LOW);
delay(5000);
fona.sendSMS("7247147099", "Hello, this is Dillan Holiday. My Hunters Life Line has just tripped. I need assistance. Emergency services have been contacted. Here are my current GPS coordinates:");
delay(2500);
fona.sendSMS("7247147099", gps_string );
delay(5000);
fona.callPhone("7247147099");
delay(7500);
digitalWrite(recordPin, HIGH);
delay(500);
digitalWrite(recordPin, LOW);
delay(60000);
}
}
}
if (buttonState == 1) //if pin is low (harness tripped) turn everything on
The code does match the comment. Which is correct ?
while (ThirtySecondCounter <= 30)
You never set ThirtySecondCounter back to zero. Is that deliberate ?
if (cancelState == 1)
{
Serial.print("Cancel is pushed!");
}
If the cancel button is pressed just carry on counting. Is that what you want to do or should something happen if/when the cancel button becomes pressed ?
delay (1000);
I did not expect to find this in the code for thread with this title
How is pin 5 wired ? Any pullup/pulldown resistor in place or is it floating at an uncertain voltage that could be HIGH or LOW when the button is not pressed ?
What do your Serial.print()s show you is happening ?
It's not clear to me what the problem is. You mention that you want to be able to detect "the" button while counting. I'll guess that you mean the cancel button. How is it wired?
UKHeliBob:
if (buttonState == 1) //if pin is low (harness tripped) turn everything on
The code does match the comment. Which is correct ?
while (ThirtySecondCounter <= 30)
You never set ThirtySecondCounter back to zero. Is that deliberate ?if (cancelState == 1)
{
Serial.print("Cancel is pushed!");
}
If the cancel button is pressed just carry on counting. Is that what you want to do or should something happen if/when the cancel button becomes pressed ?
delay (1000);
I did not expect to find this in the code for thread with this title How is pin 5 wired ? Any pullup/pulldown resistor in place or is it floating at an uncertain voltage that could be HIGH or LOW when the button is not pressed ? What do your Serial.print()s show you is happening ?
The comment is incorrect. I started changing code without changing comments...
The 30 second timer doesn't start unless pull two wires apart, breaking the circuit. In the variables section, I set ThirtySecondTimer to 0. It will not move from that position until the wires are broken.
I want while the 30 second counter is going, I want it to detect the cancel button (mind you that this only happens when the other wires are broken (open circuit). If the cancel button is pressed while it is counting up from 0, i want it to do nothing. If the cancel button is not pressed, I want it to proceed to the if statement which states [if (ThirtySecondCounter > 30 && cancelState == 0)], which will engage the call.
no pullup resistor or anything. I can get the arduino to detect both so my wiring is okay.
my serial monitor is showing that when i pull the pins apart, the 30 second timer begins as normal, but when i hit the cancel button, it doesn't stop the count. It continues the count and continues to call. I want it so that when i push the cancel button at any point between 0 and 30 it will cancel everything. I'd even be okay with it terminating the whole program when that button is pressed.
no pullup resistor or anything. I can get the arduino to detect both so my wiring is okay.
If you say so
when i hit the cancel button, it doesn't stop the count. It continues the count and continues to call.
Where is the code that stops the count ?
Do you ever see the "Cancel is pushed!" message ?
If so, then break out of the while loop at that point
UKHeliBob:
If you say so
Where is the code that stops the count ?
Do you ever see the "Cancel is pushed!" message ?
If so, then break out of the while loop at that point
i didnt put it in there because i cant even get it to say that phrase. I cant even detect it while its counting. Thats where i am stuck. Also, do i have to do one break or two (one to break the if loop and the other to break the whole while loop)?
i cant even get it to say that phrase.
In that case the code is never entering the while loop which implies that buttonState never equals 1 (note that it would be more correct to test for HIGH but for all practical purposes it will not matter). What do you see from the printout of buttonState ? Try printing ThirtySecondCounter before you start the while loop. What do you see ?
do i have to do one break or two (one to break the if loop and the other to break the whole while loop)?
There is no such thing as an if loop. The result of the test is either true or false. There is nothing to break out of. If you are worried about it then you could set a boolean to true as a result of the if returning true then test the boolean in the body of the while loop and break if it is true.