Offline
Newbie
Karma: 0
Posts: 1
|
 |
« on: April 09, 2011, 06:51:40 am » |
Is there anyway to reset a timerOnce Alarm that has been set already? I spent some time playing with timerID's and could not figure out the right syntax. I thought it would be slick to debounce some float switches(need about 1 second) with a timer that gets called in an interrupt. Then my idea was, every time the interrupt would get called, it would start the timer over. On the last interrupt for the now debounced switch, the final timer would be carried out. I don't need help with alternative ways to do this, I had to implement one, but for future reference I would like to know if it is possible to start a timerOnce Alarm, then change it to go off after a new period, without going off at the original setpoint? The observed behaviour was that it created another timerOnce alarm every time. Here is a very simple example: #include <Time.h> //Serial time sync with PC #include <TimeAlarms.h> //Alarms!
void setup() { attachInterrupt(0, debounce, CHANGE); Serial.begin(9600); }
void loop() { Alarm.delay(0); //Service timeAlarms }
void debounce() { Alarm.timerOnce(1, buttonPress); // This does not do what I intended, it sets a new alarm every time the interrupt is called - just delays the switch bouncing.
}
void buttonPress() { Serial.println("Debounced Interrupt generated."); } This is an extremely useful library - thank you! I love the ability to keep time with a PC tethered Arduino. Thanks for your help.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36458
Seattle, WA USA
|
 |
« Reply #1 on: April 09, 2011, 08:26:08 am » |
I suspect that there is some significance in the choice of function names. Personally, I would not choose timerOnce() as the name of a function that was intended to be used multiple times.
If you have a switch that bounces around all over the place for a full second, it hardly seems appropriate to be using an interrupt to read that switch.
|
|
|
|
|
Logged
|
|
|
|
|
Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #2 on: February 02, 2012, 12:51:48 am » |
I would like to know the same thing. I basically want to restart the Alarm.timerOnce function every time a button gets pushed. Here is the code. It runs fine and starts the Alarm.timerOnce(10, SkyTimer) alarm with the first push, but it does not restart that alarm timer with the more pushes of the buttons. Any idea how to cancel the first call and restart the Alarm.timerOnce routine? Thx #include <Time.h> //include Time library #include <TimeAlarms.h> //include Alarms library
int buttonPin = A4; //sets button input pin to ADC 4 int buttonVal = 0; //holds value of last button pushed int newVal = 0; //holds updated value int ledState[6]={0,0,0,0,0,0}; //holds value of Led activity const int Ohead = 27; //Ohead = 748 const int Runway = 26; //Runway = 564 const int East = 24; //East = 429 const int South = 23; //South = 321 const int West = 25; //West = 223 const int North = 22; //North = 121
void setup() { Serial.begin(9600); //set up Serial Library at 9600 /* setTime(7,07,0,2,2,12); //set time to 19:07:00 Feb 2 2012 */ pinMode(buttonPin, INPUT); // sets analog pin for input pinMode(Ohead, OUTPUT); //sets digital pin to output pinMode(Runway, OUTPUT); //sets digital pin to output pinMode(East, OUTPUT); //sets digital pin to output pinMode(South, OUTPUT); //sets digital pin to output pinMode(West, OUTPUT); //sets digital pin to output pinMode(North, OUTPUT); //sets digital pin to output } void SkyTimer() { //Blue Sky timer int i = 0; for (int i=0; i < 6; i++) { ledState[i]=0; digitalWrite(22+i, LOW); } Serial.println("SkyTimer timedout, and turned the LEDs off"); } int readButtons() // returns the button number pressed, or zero for none pressed // int pin is the analog pin number to read { int c,i = 0; c=analogRead(buttonPin); // get the analog value if (c <= 768 and c >= 728) //checking for Ohead button 748 { ledState[5]=1; digitalWrite(Ohead, HIGH); } else if (c <= 584 and c >= 544) //checking for Runway button 564 { ledState[4]=1; digitalWrite(Runway, HIGH); } else if (c <= 449 and c >= 409) //checking for East button 429 { ledState[2]=1; digitalWrite(East, HIGH); } else if (c <= 341 and c >= 301) //checking for South button 321 { ledState[1]=1; digitalWrite(South, HIGH); } else if (c <= 243 and c >= 203) //checking for West button 223 { ledState[3]=1; digitalWrite(West, HIGH); } else if (c <= 141 and c >= 101) //checking for North button 121 { ledState[0]=1; digitalWrite(North, HIGH); } if (c > 20){ Serial.println("SkyTimer alarm called"); Alarm.timerOnce(10, SkyTimer); //called once after 10 seconds } buttonVal=c; return buttonVal; }
void loop() { readButtons(); if (buttonVal == 0) { Serial.println("No button pressed"); Serial.print("Last value: "); Serial.println(newVal); } else { newVal = buttonVal; Serial.print("Value of last button pressed is: "); Serial.println(newVal); } Alarm.delay(100); }
|
|
|
|
|
Logged
|
|
|
|
|
|
|
Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #4 on: February 02, 2012, 08:21:23 am » |
Thank you Si. I'm reading multiple buttons on one analog pin. I don't have any problems with the actual reading. So it is not a question of debouncing. With the button push the program turns on a corresponding LED and a 30 minute timer. If at some point during that thirty minutes the user decides to push the same or another of the buttons I want to restart that 30 minute timer.
Therefore, I either have to reset the running alarm.timer, or cancel the running alarm.timer and start it again by calling it the way it is being called as it is in the program now.
Thx
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
God Member
Karma: 9
Posts: 895
Twitter: @simonmonk2
|
 |
« Reply #5 on: February 02, 2012, 08:32:31 am » |
Sorry, So, if I understand you properly, then the problem is not being able to cancel the Alarm once its off and running. If so, I have a library, that lets you do long (and cancellable) timing operations. http://srmonk.blogspot.com/2012/01/arduino-timer-library.html
|
|
|
|
|
Logged
|
|
|
|
|
Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #6 on: February 02, 2012, 10:45:09 am » |
Here is the context: The user pushes one or more of 6 buttons to indicate certain temporary conditions are true. This immediately turns on the corresponding LED to show which of the buttons he pushed. And any button push will start a timer running. After 1800 seconds the LED(s) will turn off (I'm using 10 seconds at the moment for debugging). The user must push the button(s) again to indicate which conditions are true at that time. This basic routine works. However, I would like the user to be able to re-confirm that a condition is true at any time by pushing the appropriate button, which should then restart the timer.
Keep in mind I'm a newbie. At the moment I'm using Alarm.timerOnce. This timer starts running from the first time it is called by a button push. However it does not restart running with additional button pushes until it reaches its full 1800 seconds counting from the first time it was called. Rather than having to wait for that full period, if the user pushes one of the button 1790 seconds after the first time Alarm.timerOnce was called, I would like it to go back to zero and start timing to 1800 again.
I can not figure out how to either zero the Timer, or how to cancel Alarm.timerOnce and then call it again.
Thx
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36458
Seattle, WA USA
|
 |
« Reply #7 on: February 02, 2012, 11:23:34 am » |
From TimeAlarm.h: AlarmID_t alarmOnce(time_t value, OnTick_t onTickHandler); // trigger once at given time of day AlarmID_t alarmOnce( const int H, const int M, const int S, OnTick_t onTickHandler); // as above, with hms arguments AlarmID_t alarmOnce(const timeDayOfWeek_t DOW, const int H, const int M, const int S, OnTick_t onTickHandler); // as above, with day of week All three methods return an ID. You are not recording the ID, so there is no way to reset/stop the alarm. If you did, you could call Alarm.disable() to disable that particular alarm, and then create a new one.
|
|
|
|
|
Logged
|
|
|
|
|
Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #8 on: February 05, 2012, 02:12:24 am » |
Hi PaulS,
Thank you for pointing me in this direction. I don't know yet what it means what you wrote (as I said, I'm a newbie to this), but at least now I have something new to point me where to go read next. Appreciate the help.
Thx
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36458
Seattle, WA USA
|
 |
« Reply #9 on: February 05, 2012, 09:19:07 am » |
I don't know yet what it means what you wrote It means that you can declare a global variable: AlarmID_t stupidAlarmClock = 0; It means that you can capture the ID of the alarm you set: stupidAlarmClock = Alarm.timerOnce(10, SkyTimer); //called once after 10 seconds
It means that you can disable that alarm: stupidAlarmClock.disable(); // Don't ring any more
|
|
|
|
|
Logged
|
|
|
|
|
Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #10 on: February 05, 2012, 01:41:21 pm » |
PaulS you rock!
I have been trying to find how to apply the commands. I found lots of places where they repeat the 'readme' text that is included with the library. Nowhere where it is brought down to newbie level like you just did. Thank you so much. I'm going to play with this now and get it to work.
Thx!!!!
|
|
|
|
|
Logged
|
|
|
|
|
|