Контроллер просыпается по таймеру но код исполняется странно
- Войдите на сайт для отправки комментариев
Доброго дня!
Делаю простой проектик, но захотелось чтоб с перламутровыми пуговицами, на солнечных батареях и фотонным двигателем :)
Это типа ночника, сувенир, стоит на полке и в момент когда в комнате гаснет свет, включается не надолго подсветка (во первых красиво, во вторых можно дойти, например, до кровати).
Для экономии решил его спать. Основная часть кода- пример из интернета, кое что дописал.
Теперь о проблеммах, пока это был "блинк" все работало, но с моим функционалом работает не очень и через раз. Более того, вставляя Serial.print() для отладки, печатает какой то мусор. В тои месте гда идет сравнение текущего и предидущего значений освещенности ( если поставить Serial.print() и оградить его delay() ) можно видеть, что последнее "предидущее" значение не соотвествует "текущему" на шаг назад... Немного путанно, короче, то что он показывает, это не то, что он измерял и напечатал в прошый раз.
Из за этого все работает весьма криво, хотя вроде код несложный. Очевидно я что то упускаю по незнанию, поэтому и прошу помощи
#include <avr/sleep.h> //AVR MCU power management #include <avr/power.h> //disable/anable AVR MCU peripheries (Analog Comparator, ADC, USI, Timers/Counters) #include <avr/wdt.h> //AVR MCU watchdog timer #include <avr/io.h> //includes the apropriate AVR MCU IO definitions #include <avr/interrupt.h> //manipulation of the interrupt flags #include "OneButton.h" #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) #endif #define LIGHT 3 #define SENSOR A0 #define SWITCH 0 volatile int bri, preBri, temp, test, ledBri; volatile boolean flag; volatile boolean dark; volatile boolean autoLight = true; OneButton button(SWITCH, true); /* setup() Main setup NOTE: - valid sleep intervals: WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S WDTO_4S, WDTO_8S */ void setup() { Serial.begin(9600); ledBri = 32; pinMode (SENSOR, INPUT); pinMode (LIGHT, OUTPUT); preBri = analogRead (SENSOR); button.attachClick(click1); button.attachLongPressStart(longPressStart); setup_watchdog(WDTO_500MS); //time to sleep } void loop() { if (autoLight) { while (!flag) { // МК спит, пока сторожевой таймер не снимет флаг arduino_sleep(); } // МК если таймер сработал, должен выполниться код ниже wdt_disable(); // отключить таймер flag = false; // вернуть флаг, чтоб МК снова уснул power_all_enable(); // включить переферию delay(10); if (!digitalRead(SWITCH)) { // ручное включение света autoLight = false; ledBri = 1; } bri = analogRead (SENSOR); // чтение сенсора освещенности if (bri < 200 && preBri >= 250 && bri < preBri) { // сравнение с предидущим значением light(); // если ДА плавно включить и потушить свет } preBri = bri; // запись текущего значения для последующего сравнения if (bri < 250) { // запуск сторожевого таймера, если темно то на большее время wdt_enable(WDTO_2S); } else { wdt_enable(WDTO_500MS); } } else { // ручное управление button.tick(); if (!autoLight) { wdt_disable(); analogWrite(LIGHT, ledBri); } } } /**************************************************************************/ void light() { wdt_disable(); analogWrite(LIGHT, 92); for (int i = 92; i < 255; i++) { delay(15); analogWrite(LIGHT, i); if (analogRead (SENSOR) > 250) { analogWrite(LIGHT, 0); return; } } delay(5000); for (int i = 255; i > 0; i--) { delay(25); analogWrite(LIGHT, i); if (analogRead (SENSOR) > 250) { analogWrite(LIGHT, 0); return; } } analogWrite(LIGHT, 0); } /*****************************************************************************/ void arduino_sleep() { cli(); //disable interrupts for time critical operations below power_all_disable(); //disable all peripheries (ADC, Timer0, Timer1, Universal Serial Interface) // power_adc_disable(); //disable ADC // power_timer0_disable(); //disable Timer0 // power_timer1_disable(); //disable Timer2 // power_usi_disable(); //disable the Universal Serial Interface module set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep type #if defined(BODS) && defined(BODSE) //if MCU has bulit-in BOD it will be disabled, ATmega328P, ATtiny85, AVR_ATtiny45, ATtiny25 sleep_bod_disable(); //disable Brown Out Detector (BOD) before going to sleep, saves more power #endif sei(); //re-enable interrupts sleep_mode(); /* system stops & sleeps here, it automatically sets Sleep Enable (SE) bit, so sleep is possible, goes to sleep, wakes-up from sleep after interrupt, if interrupt is enabled or WDT enabled & timed out, than clears the SE bit. */ /*** NOTE: sketch will continue from this point after sleep ***/ } void setup_watchdog(byte sleep_time) { cli(); //disable interrupts for time critical operations below wdt_enable(sleep_time); //set WDCE, WDE change prescaler bits MCUSR &= ~_BV(WDRF); //must be cleared first, to clear WDE #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) WDTCR |= _BV(WDCE) & ~_BV(WDE); //set WDCE first, clear WDE second, changes have to be done within 4-cycles WDTCR |= _BV(WDIE); //set WDIE to Watchdog Interrupt #else WDTCSR |= _BV(WDCE) & ~_BV(WDE); //set WDCE first, clear WDE second, changes have to be done within 4-cycles WDTCSR |= _BV(WDIE); //set WDIE to Watchdog Interrupt #endif sei(); //re-enable interrupts } /**************************************************************************/ /* ISR(WDT_vect) Watchdog Interrupt Service Routine, executed when watchdog is timed out NOTE: - if WDT ISR is not defined, MCU will reset after WDT */ /**************************************************************************/ ISR(WDT_vect) { flag = true; } void click1() { if (!autoLight) { ledBri = ledBri + 32; if (ledBri > 255) ledBri = 32; } } void longPressStart() { autoLight = true; analogWrite(LIGHT, 0); wdt_enable(WDTO_500MS); }
Отсюда и все беды. Делали б как все нормальные люди с блэкджеком и шлюхами, так всё бы работало, и даже корованы грабились бы. А так ...
В тои месте гда идет сравнение текущего и предидущего значений освещенности ( если поставить Serial.print() и оградить его delay() ) можно видеть, что последнее "предидущее" значение не соотвествует "текущему" на шаг назад...
Давайте, Вы это сделаете и выложите а) именно тот скетч и б) лог печати. Хочется посмотреть.
И, да, кстати, посмотрите на условия в строке №61. Вам не кажется, что последнее условие - лишнее?
Какой "тот"? Он у меня один, вот он же с принтами
пример откуда я брал основу
https://github.com/enjoyneering/Arduino_Deep_Sleep/blob/master/arduino_d...
лог, то что отмеченно, должно быть одинаковым, по моему разумению.
Какой "тот"? Он у меня один, вот он же с принтами
Вот, правильно. "Тот" - это тот, который печатает. Хочется смотреть на то как печатает и на результат, а не догадываться. Щас посмотрим неспеша.