前提・実現したいこと
arduinoでセンサ値を読み取り、センサの出力がない(センサが反応しない)時間が4分を超えたら出力をリセットするシステムを作りたいです。
発生している問題・エラーメッセージ
sleep関数を使用するとloop文が回らない(program)が回らない
該当のソースコード
arduino
1#include <avr/sleep.h> 2#include <MsTimer2.h>//時間計測 3#include <avr/wdt.h> 4fastIoPin<3>PPR1; 5fastIoPin<10>LED_BLUE; 6fastIoPin<11>LED_GREEN; 7fastIoPin<12>LED_RED; 8fastIoPin<13>buza_Pin; 9unsigned int state1 = 0; 10void time_count(void); 11void delayWDT2(unsigned long t); 12ISR(WDT_vect); 13unsigned int lastState1 = LOW; 14unsigned long risingEdgeTime1 = 0; 15unsigned int stage1 = 0; //0=初期, 1=監視期間, 2=HIGH期間 16int x; 17 18void setup() { 19 MsTimer2::set(20, value_count);//オーバーフローする時間が20sで20ミリ秒ごとにtime_count関数を呼出, 20 PPR1.pinMode(INPUT);//センサ値 21 LED_BLUE.pinMode(OUTPUT);//青LED 22 LED_GREEN.pinMode(OUTPUT);//緑LED 23 LED_RED.pinMode(OUTPUT);//赤LED 24 buza_Pin.pinMode(OUTPUT);//buza 25 set_sleep_mode(SLEEP_MODE_PWR_DOWN);//sleep設定 26 wdt_enable(WDTO_8S);//秒数設定 27 Serial.begin(9600); 28 MsTimer2::start(); 29} 30//sensor値取得 31void value_count(void) { 32 float t = (millis() - 30000) * 0.001; //loop開始からの経過秒 33 state1 = digitalNoiselessRead1(3, 40, 10000); //PPR1 ピンが 0.04秒間 HIGH になっていたら,その後 10秒間 HIGH が返る 34 Serial.print(t, 2); 35 Serial.print(" "); 36 Serial.println(state1); 37 delayWDT2(7); // 引数でスリープ時間指定(詳細はdelayWDT_setup参照)//7=2s 38 39} 40 41void delayWDT2(unsigned long t) { // パワーダウンモードでdelayを実行 42 Serial.flush(); // シリアルバッファが空になるまで待つ 43 delayWDT_setup(t); // ウォッチドッグタイマー割り込み条件設定 44 45 // ADCを停止(消費電流 147→27μA) 46 ADCSRA &= ~(1 << ADEN); 47 48 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード指定 49 sleep_enable(); 50 51 // BODを停止(消費電流 27→6.5μA) 52 MCUCR |= (1 << BODSE) | (1 << BODS); // MCUCRのBODSとBODSEに1をセット 53 MCUCR = (MCUCR & ~(1 << BODSE)) | (1 << BODS); // すぐに(4クロック以内)BODSSEを0, BODSを1に設定 54 55 asm("sleep"); // 3クロック以内にスリープ sleep_mode();では間に合わなかった 56 57 sleep_disable(); // WDTがタイムアップでここから動作再開 58 ADCSRA |= (1 << ADEN); // ADCの電源をON(BODはハードウエアで自動再開される) 59} 60 61void delayWDT_setup(unsigned int ii) { // ウォッチドッグタイマーをセット。 62 // 引数はWDTCSRにセットするWDP0-WDP3の値。設定値と動作時間は概略下記 63 // 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms 64 // 6=1sec, 7=2sec, 8=4sec, 9=8sec 65 byte bb; 66 if (ii > 9 ) { // 変な値を排除 67 ii = 9; 68 } 69 bb = ii & 7; // 下位3ビットをbbに 70 if (ii > 7) { // 7以上(7.8,9)なら 71 bb |= (1 << 5); // bbの5ビット目(WDP3)を1にする 72 } 73 bb |= ( 1 << WDCE ); 74 75 MCUSR &= ~(1 << WDRF); // MCU Status Reg. Watchdog Reset Flag ->0 76 // start timed sequence 77 WDTCSR |= (1 << WDCE) | (1 << WDE); // ウォッチドッグ変更許可(WDCEは4サイクルで自動リセット) 78 // set new watchdog timeout value 79 WDTCSR = bb; // 制御レジスタを設定 80 WDTCSR |= _BV(WDIE); 81} 82 83//ISR(WDT_vect) { // WDTがタイムアップした時に実行される処理 84// wdt_cycle++; // 必要ならコメントアウトを外す 85//} 86 87unsigned int digitalNoiselessRead1(unsigned int pin1, long monitoringPeriod1, long highPeriod1) { 88 state1 = digitalRead<3>(); 89 unsigned long now = millis(); 90 if (stage1 == 0 && lastState1 == LOW && state1 == HIGH) { //立ち上がり検出 91 risingEdgeTime1 = now; 92 stage1 = 1; //監視期間開始 93 } 94 lastState1 = state1; 95 if (stage1 == 1) { //監視期間中 96 if (state1 == LOW) { //ノイズだった 97 stage1 = 0; 98 } else if (now - risingEdgeTime1 >= monitoringPeriod1) { 99 stage1 = 2; //HIGH 期間へ移行 100 } else { 101 state1 = LOW; //監視期間中は LOW 102 } 103 } else if (stage1 == 2) { //HIGH期間中 104 if (now - risingEdgeTime1 <= monitoringPeriod1 + highPeriod1) { 105 state1 = HIGH; //HIGH期間中は HIGH 106 } else { 107 stage1 = 0; //HIGH期間終了 108 } 109 } 110 return state1; 111} 112void loop() { //LED,システム 113 switch (x) { 114 case 0: 115 //buza_Pin.digitalWrite(LOW); 116 LED_RED.digitalWrite(LOW); 117 LED_GREEN.digitalWrite(HIGH); 118 LED_BLUE.digitalWrite(LOW); //青 119 break; 120 case 1: 121 //buza_Pin.digitalWrite(LOW); 122 LED_RED.digitalWrite(HIGH); 123 LED_GREEN.digitalWrite(LOW); 124 LED_BLUE.digitalWrite(HIGH); //黄 125 break; 126 case 2: 127 //buza_Pin.digitalWrite(HIGH); 128 LED_RED.digitalWrite(HIGH); 129 LED_GREEN.digitalWrite(HIGH); 130 LED_BLUE.digitalWrite(HIGH); //赤 131 delay(100); 132 //buza_Pin.digitalWrite(HIGH); 133 LED_RED.digitalWrite(LOW); 134 LED_GREEN.digitalWrite(HIGH); 135 LED_BLUE.digitalWrite(HIGH); //赤 136 delay(100); 137 break; 138 case 3: 139 //buza_Pin.digitalWrite(HIGH); 140 LED_RED.digitalWrite(HIGH); 141 LED_GREEN.digitalWrite(LOW); 142 LED_BLUE.digitalWrite(LOW); //白 143 break; 144 } 145 if (state1 == LOW) { //青 00000 146 x = 0; 147 } 148else if (state1 == HIGH) {//5m~10m黄色11000 149 x = 1; 150 } 151…//その他30通り記載 152}
試したこと
実際はセンサを5つ使用しています。loop文、新しい関数内などにdelayWDT2関数を入れてみましたが正常に動作しません。関数をコメントアウトするとシステムは正常に動きますがリセット機能がないので5分ほどでシステムが停止します。
補足情報(FW/ツールのバージョンなど)
モバイルバッテリーを使用すると約5分ほどでシステムが停止します。恐らく、モバイルバッテリーの過電流防止回路が発生しているのだと思います。そこで、5分以内に定期的にシステムのリセットをすることができればシステムを長時間使用することができると思い、いろいろ試しましたができませんでした。もしわかる方がいらっしゃいましたらご教示いただけないでしょうか。よろしくお願い致します。
回答2件
あなたの回答
tips
プレビュー