12時間ごとに開閉する小さなドアを開閉しようとしています。12時間delay()、delay(43 200 000 000)で小さなループスクリプトを作成できるかどうか疑問に思いました。私は推測する?しかし、それが可能であるか、推奨できるか、あるいはその両方であるかどうかはわかりません。いくつかのフィードバック/代替案(必要な場合)がいいでしょう:)
12時間ごとに開閉する小さなドアを開閉しようとしています。12時間delay()、delay(43 200 000 000)で小さなループスクリプトを作成できるかどうか疑問に思いました。私は推測する?しかし、それが可能であるか、推奨できるか、あるいはその両方であるかどうかはわかりません。いくつかのフィードバック/代替案(必要な場合)がいいでしょう:)
回答:
リアルタイムクロック方式が最も正確な方法ですが、それ以外の場合は millis
unsigned long startMillis = millis();
while (millis() - startMillis < LONG_DELAY_MS);
これは最大約遅延します。4294967295ms(2 ^ 32-1)または49日後、タイマーは次の値に追いつきますstartMillis
delay(LONG_DELAY_MS)
ますか?arduinoの実装では、符号なしlong型を受け入れます。また、私は完全に必ず時にコードが正しく機能していないよmillis()
ラップアラウンド、およびよりも小さいstartMillis
delay()
その用途はありますが、長い遅延のため、それは良くありません。それは単にx
クロックサイクルに対して何もしないようにマイクロコントローラーに伝えます。その間、Arduinoは他に何もできません。
あなたの最善の策は、リアルタイムクロック(RTC)と呼ばれるものを使用することです。これらのチップは、時間を追跡するために特別に作成されており、Arduinoに簡単に接続できます。これを行う方法の例を次に示します。
ウォッチドッグ割り込みを使用して、待機中にMCUをスリープさせ、電力を節約できます。
ただし、ボードもそれを節約する場合にのみ、電力を節約することに注意してください。つまり、Unoなどの最も一般的なArduinoボードを装備する通常のレギュレーターの代わりに、低静止電圧レギュレーターが必要です。それ以外の場合は、ボードが省エネルギーしない場合にMCUがエネルギーを節約するかどうかは問題ではありません。
ここにコードがあります(テストされていません):
#include <avr/sleep.h>
// This variable is made volatile because it is changed inside an interrupt function
volatile int sleep_count = 0; // Keep track of how many sleep cycles have been completed.
const int interval = 720; // Interval in minutes between waking and doing tasks.
const int sleep_total = (interval*60)/8; // Approximate number of sleep cycles
// needed before the interval defined above elapses. Not that this does integer math.
void setup(void) {
watchdogOn(); // Turn on the watch dog timer.
// Disable the ADC by setting the ADEN bit (bit 7) to zero.
ADCSRA = ADCSRA & B01111111;
// Disable the analog comparator by setting the ACD bit (bit 7) to one.
ACSR = B10000000;
// Disable digital input buffers on all analog input pins by setting bits 0-5 to one.
DIDR0 = DIDR0 | B00111111;
}
void loop(void) {
goToSleep(); // ATmega328 goes to sleep for about 8 seconds
// and continues to execute code when it wakes up
if (sleep_count == sleep_total) {
// CODE TO BE EXECUTED PERIODICALLY
}
}
void goToSleep() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
sleep_enable(); // Enable sleep mode.
sleep_mode(); // Enter sleep mode.
// After waking from watchdog interrupt the code continues
// to execute from this point.
sleep_disable(); // Disable sleep mode after waking.
}
void watchdogOn() {
// Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
MCUSR = MCUSR & B11110111;
// Set the WDCE bit (bit 4) and the WDE bit (bit 3) of WDTCSR.
WDTCSR = WDTCSR | B00011000;
// Set the watchdog timeout prescaler value to 1024 K
// which will yeild a time-out interval of about 8.0 s.
WDTCSR = B00100001;
// Enable the watchdog timer interupt.
WDTCSR = WDTCSR | B01000000;
MCUSR = MCUSR & B11110111;
}
ISR(WDT_vect)
{
sleep_count ++; // keep track of how many sleep cycles have been completed.
}
私がコピーしたコードはこのページからです:ウォッチドッグタイマーを使用した低電力Arduino。
スリープ(符号なし整数秒)はありますか?
そうでない場合は、これにより非常に長い間delay()を実行できます。
for (unsigned int bigloop=0; bigloop<65535; bigloop++)
{
for (unsigned int smallloop=0; smallloop<65535; smallloop++)
{
for (unsigned int tinyloop=0; tinyloop<65535; tinyloop++)
{
delay(65535);
}
}
}
間に何かしたくない場合は、forループを使用します。
for (int Hours = 0; Hours < 12; Hours++) { //Creates 12 hours
for (int Minutes = 0; Minutes < 60; Minutes++) { //Creates 1 hour
for (int Seconds = 0; Seconds < 60; Seconds++) { //Creates 1 minute
delay(1000); //Creates 1 second
}
}
}