Arduino中的AlarmRepeat函数
Posted
技术标签:
【中文标题】Arduino中的AlarmRepeat函数【英文标题】:AlarmRepeat function in Arduino 【发布时间】:2015-04-11 02:30:05 【问题描述】:我在 Arduino 中使用 Time.h 和 TimeAlarms.h 库。我尝试在一天中的特定时间(每天)调用一个函数。该功能在第一天被调用,但在第二天似乎警报停止工作,尽管它应该每天重复。任何想法我的草图有什么问题?
#include <Time.h>
#include <TimeAlarms.h>
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message
// The constant variables used in the code:
const unsigned long shock_delay = 10; // shock stimulus duration (s)
// Edit below only if you make changes to the hardware configuration:
const int tonePin = 13; // the number of the LED pin
const int shockPin = 12; // the number of the shocker pin
const int buzzerOut = 8; // the number of the tone producer
const int trialButton=2; // the number of the trial button
const int controlButton=3; // the number of the control button
// Define the variables that will change in the code
unsigned int Interval1; // the interval between the beginning of the hour and the first footshock
unsigned int Interval2; // the interval between the first and the second footshock
void setup()
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
setTime(23,59,50,10,4,15); // The current time (HH,MM,SS,DD,MM,YY)
// Define the position of the different digital pins
pinMode(tonePin, OUTPUT); // The tone LED (red)
pinMode(shockPin, OUTPUT); // The shock output, which will coincide with green LED
pinMode(trialButton, INPUT); // The trial input button
pinMode(controlButton, INPUT); // The control input button
Alarm.alarmRepeat(20,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(21,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(22,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(23,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(0,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(1,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(2,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(3,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(4,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(5,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(6,00,0,RandomShock); // Initiate the user defined RandomShock function
Alarm.alarmRepeat(7,00,0,RandomShock); // Initiate the user defined RandomShock function
void loop()
// Create a message that gives the current time and date on the monitor
if(Serial.available() )
processSyncMessage();
if(timeStatus() == timeNotSet)
Serial.println("waiting for sync message");
else
digitalClockDisplay(); // The function that calls on the time display
Alarm.delay(1000); // Delay of 1 minute between time display
void digitalClockDisplay()
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
void printDigits(int digits)
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
void processSyncMessage()
// if time sync available from serial port, update time and return true
while(Serial.available() >= TIME_MSG_LEN ) // time message consists of header & 10 ASCII digits
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER )
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++)
c = Serial.read();
if( c >= '0' && c <= '9')
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
setTime(pctime); // Sync Arduino clock to the time received on the serial port
void RandomShock ()
Interval1 = random(0,60); // Random value between 0 and 59 [min]
digitalWrite(tonePin,HIGH); // Indicate the shock program is ON by the red LED
Alarm.delay(Interval1*60000); // Wait for the duration of the first interval
digitalWrite(tonePin,LOW); // Turn the red LED OFF
digitalWrite(shockPin, HIGH); // Apply the first shock (green LED will turn ON)
Serial.println("Applying an electeric shock at:"); // Write a message indicating a shock is applied
digitalClockDisplay(); // Display the time during which the shock was applied
Alarm.delay(shock_delay*1000); // The duration of the shock [10 seconds]
digitalWrite(shockPin, LOW); // Terminate the first shock (green LED will turn OFF)
Interval2 = random(0,(61-Interval1)); // Randomly asign a value to the second interval [min]
digitalWrite(tonePin,HIGH); // Indicate the shock program is ON by the red LED
Alarm.delay(Interval2*60000-20000); // Wait for the duration of the second interval
digitalWrite(tonePin,LOW); // Turn the red LED OFF
digitalWrite(shockPin,HIGH); // Apply the second shock (green LED will turn ON)
Serial.println("Applying an electeric shock at:"); // Write a message indicating a shock is applied
digitalClockDisplay(); // Display the time during which the shock was applied
Alarm.delay(shock_delay*1000); // The duration of the shock [10 seconds]
digitalWrite(shockPin,LOW); // Terminate the second shock
digitalWrite(tonePin,HIGH); // Indicate the shock program is ON by the red LED
Alarm.delay((60-Interval1-Interval2)*60000); // Wait until the hour is completed
digitalWrite(tonePin,LOW); // Turn the red LED OFF
【问题讨论】:
你能分享你遇到的错误吗? 感谢您的回复。没有错误消息。草图运行顺利。我进行了一次测试,发现它在第一天运行良好,但是一旦日期在午夜打开,alarmRepeat 函数就停止调用我的函数 (RandomShock)。据我了解,不应该是这样的。 AlarmRepeat 应该每天在同一时间调用我的函数。 已解决:我写的草图有两个问题:1)Alarm.alarmRepeat 函数似乎无法在午夜(00:00:00)准确地调用我的函数,但是,如果我将它安排到任何其他时间(例如,00:00:01),它就可以正常工作。 2)您可以调度的警报数量有限制:最大警报数量为6。解决方案是更改此阈值,或减少警报数量。修正这两个问题后,草图工作顺利。 @cassiopeiam 请将您的解决方案发布为答案并将其标记为已接受(您不会因此获得任何代表,但我会支持它)。 【参考方案1】:我写的草图有两个问题:
Alarm.alarmRepeat 函数似乎无法调用我的 正好在午夜 (00:00:00) 运行,但是,如果我安排它 到任何其他时间(例如,00:00:01)它工作得很好。
您可以安排的警报数量有限制: 最大警报数量为 6。解决方法是更改此阈值,或减少警报数量。
在纠正这两个问题后,草图工作顺利。
【讨论】:
【参考方案2】:似乎 TimeAlarm 库无法将闹钟设置为午夜 https://github.com/PaulStoffregen/TimeAlarms/issues/3
试试这个拉取请求https://github.com/PaulStoffregen/TimeAlarms/pull/4
【讨论】:
【参考方案3】:如果您需要超过 6 个警报,只需在库中的 TimeAlarms.h 中查找:
#if defined(__AVR__)
#define dtNBR_ALARMS 6 // max is 255
#else
#define dtNBR_ALARMS 12 // assume non-AVR has more memory
#endif
并根据您的需要更改(例如:24)
#if defined(__AVR__)
#define dtNBR_ALARMS 24 // max is 255
#else
#define dtNBR_ALARMS 12 // assume non-AVR has more memory
#endif
【讨论】:
以上是关于Arduino中的AlarmRepeat函数的主要内容,如果未能解决你的问题,请参考以下文章
使用串行通信在 python 和 arduino 之间进行同步
关于通过 USART 上的 MDB 协议与自动售货机通信时 Arduino 的 TX 线的问题