Использование PWM вместе с Watchdog/MsTimer2
- Войдите на сайт для отправки комментариев
Доброй ночи. Появилась идея автополива на ардуино, но на просторах интернета все "гайды" примитивные, без таймеров/энергосбережения etc. В итоге решил сделать сам. Покурив немного про энергосбережение и собсна пробуждения ото сна, написал код. Все вроде как работает, но кроме одной вещи. Помпу для собственно полива я включаю мосфетом, и открывать его я хочу не на всю, т.е подавать на него не 255, а, скажем, 50, дабы регулировать подачу воды этой помпы. Но вот незадача, при использовании таймеров, PWM перестает воспринимать все аргументы в analogWrite, которые ниже 255. Погуглив на ру/еу форумах, так и не нашел нажной мне информации. Где-то видел что какой-то юзер писал, что таймеры что-то вроде могут 'блокировать' PWM на пинах, но так и не понял правда ли это, и если да, то как это исправить. Сразу скажу, что пытался использовать все пины на которых есть функция PWM (у меня Arduino Nano), но все было тщетно. При прекращении использования таймеров PWM разумеется работает как надо.
Вот мой код:
#include <avr/wdt.h> #include <avr/sleep.h> #include <avr/interrupt.h> #define adc_disable() (ADCSRA &= ~(1<<ADEN)) #define PERIOD_BETWEEN_OPENINGS 5 #define MOSFET_OPEN_TIME 2 #define PIN_MOSFET 3 long mainTimer, myTimer; bool mosfetOpened = false; void setup() { for (byte i = 0; i < 6; i++) { pinMode(i, INPUT); } adc_disable(); wdt_reset(); wdt_enable(WDTO_1S); WDTCSR |= _BV(WDIE); sei(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); } void loop() { mainTimer++; if (!mosfetOpened) { if (mainTimer - PERIOD_BETWEEN_OPENINGS >= 0) { mainTimer = 0; mosfetOpened = true; pinMode(PIN_MOSFET, OUTPUT); analogWrite(PIN_MOSFET, 255); } } else { if (mainTimer - MOSFET_OPEN_TIME >= 0) { mainTimer = 0; mosfetOpened = false; analogWrite(PIN_MOSFET, 0); pinMode(PIN_MOSFET, INPUT); } } sleep_enable(); sleep_cpu(); } ISR (WDT_vect) { WDTCSR |= _BV(WDIE); }
PWM делается с помощью таймеров. По 2 пина на таймер. Поэтому не надо использовать PWM на пинах относящихся к тому таймеру с которым вы работаете. Только я что-то не вижу ничего про таймеры в вашем коде.
PWM делается с помощью таймеров. По 2 пина на таймер. Поэтому не надо использовать PWM на пинах относящихся к тому таймеру с которым вы работаете. Только я что-то не вижу ничего про таймеры в вашем коде.
Я упомянул MsTimer2, поскольку я экспериментировал с прерываниями с помощью таймеров, и заметил, что при включении таймера из этой библиотеки PWM перестает работать. В текущей версии я использую Watchdog, и он вроде как тоже таймер, так ведь? Ну и как я сказал, при использовании Watchdog я пытался подавать PWM на различные пины (в моем случае это 3, 5, 6, 9, 10, 11), но любое значение не равное 255 игнорировалось можно сказать
Djensen - в вашем случае дело не в таймерах, а во спящем режиме. При уходе в сон PWM останавливается,
Вам необходимо переписать код так, чтобы контроллер засыпал только между поливами, а не в момент когда включена помпа
Djensen - в вашем случае дело не в таймерах, а во спящем режиме. При уходе в сон PWM останавливается,
Вам необходимо переписать код так, чтобы контроллер засыпал только между поливами, а не в момент когда включена помпа
Хм, правильно ли я понимаю, что 53 и 54 строка в этом виновны? Ибо я получается подаю PWM на мосфет, и сразу же 53 и 54 строки переводят ардуино в сон, и тем самым выключают PWM?
Хм, правильно ли я понимаю, что 53 и 54 строка в этом виновны? Ибо я получается подаю PWM на мосфет, и сразу же 53 и 54 строки переводят ардуино в сон, и тем самым выключают PWM?
да, похоже так
Хм, правильно ли я понимаю, что 53 и 54 строка в этом виновны? Ибо я получается подаю PWM на мосфет, и сразу же 53 и 54 строки переводят ардуино в сон, и тем самым выключают PWM?
да, похоже так
Да, и вправду проблема была в этом. Спасибо за помощь!