Энергоэффективный режим работы arduino с DS3231
Добавлено: Пт окт 27, 2017 14:15:33
Планируется, что Arduino pro mini обвешаная дачтиками, питающаяся от батареек будет производить измерения 1 раз в час, слать их по радио и засыпать, через час по будильнику DS3231 просыпаться повотрять то же самое. Все вроде работает, но есть одно НО, которое все портит. Потребление в режиме сна 300 мкА!
250 мкА из которых утекают по линии SQW, по которой приходит прерывание спящего режима arduino.
То есть если arduino спит без подключенной линий SQW часов потребление 30-40 мкА (что устраивает). Но если подключить линию SQW к пину 2 ( который в режиме INPUT_PULLUP и еще подтянут к питанию 5кОм) то паразитный ток 250мкА все портит. (То есть в SQW при режиме ожидания висит резюк 10кОм перед землей, в момент срабатывания будильника сопротивление убирается и коротится на землю, что пробуждает контролер). Если в линию еще последовательное ставить резистр, то ток уменьшается но arduino уже не просыпается.
Ниже код урезанный именно та часть которая отвечает за сон и пробуждение (так то линия запитки и дачтиков висит на одной из ног дуины, перед сном они переводятся в состояние INPUT, что посзволило снизить с единиц мА до десятков мкА).
#include <Wire.h>
#include <LowPower.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <SPI.h>
#include <Streaming.h>
#define wakePin 2
DS3231 clock;
RTCDateTime dt;
void setup() {
pinMode(wakePin, INPUT_PULLUP);
clock.begin();
clock.enableOutput(false);
clock.armAlarm1(false);
clock.armAlarm2(false);
clock.clearAlarm1();
clock.clearAlarm2();
}
void loop() {
setSleepTimer(1);
sleepNow();
}
}
void wakeUp()
{
// Just a handler for the pin interrupt.
}
void setSleepTimer(int mins) {
uint8_t hours = mins / 60;
uint8_t mins_left = mins - hours * 60;
dt = clock.getDateTime();
uint8_t hnow = dt.hour;
uint8_t mnow = dt.minute;
uint8_t sec = dt.second;
mnow += mins_left;
if (mnow >= 60) {
mnow -= 60;
hnow += 1;
}
hnow += hours;
if (hnow > 23) {
hnow -= 24;
}
clock.setAlarm1(0, hnow, mnow, sec, DS3231_MATCH_H_M_S);
}
void sleepNow() {
ADCSRA = 0;
power_all_disable();
attachInterrupt(0, wakeUp, LOW);
PINs_to_sleep();
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
sleep_enable();
sleep_mode();
sleep_disable();
power_all_enable();
detachInterrupt(0);
PINs_to_work();
delay(100);
}
Подскажите как можно устранить ток по линии SQW.
250 мкА из которых утекают по линии SQW, по которой приходит прерывание спящего режима arduino.
То есть если arduino спит без подключенной линий SQW часов потребление 30-40 мкА (что устраивает). Но если подключить линию SQW к пину 2 ( который в режиме INPUT_PULLUP и еще подтянут к питанию 5кОм) то паразитный ток 250мкА все портит. (То есть в SQW при режиме ожидания висит резюк 10кОм перед землей, в момент срабатывания будильника сопротивление убирается и коротится на землю, что пробуждает контролер). Если в линию еще последовательное ставить резистр, то ток уменьшается но arduino уже не просыпается.
Ниже код урезанный именно та часть которая отвечает за сон и пробуждение (так то линия запитки и дачтиков висит на одной из ног дуины, перед сном они переводятся в состояние INPUT, что посзволило снизить с единиц мА до десятков мкА).
Спойлер
#include <DS3231.h>#include <Wire.h>
#include <LowPower.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <SPI.h>
#include <Streaming.h>
#define wakePin 2
DS3231 clock;
RTCDateTime dt;
void setup() {
pinMode(wakePin, INPUT_PULLUP);
clock.begin();
clock.enableOutput(false);
clock.armAlarm1(false);
clock.armAlarm2(false);
clock.clearAlarm1();
clock.clearAlarm2();
}
void loop() {
setSleepTimer(1);
sleepNow();
}
}
void wakeUp()
{
// Just a handler for the pin interrupt.
}
void setSleepTimer(int mins) {
uint8_t hours = mins / 60;
uint8_t mins_left = mins - hours * 60;
dt = clock.getDateTime();
uint8_t hnow = dt.hour;
uint8_t mnow = dt.minute;
uint8_t sec = dt.second;
mnow += mins_left;
if (mnow >= 60) {
mnow -= 60;
hnow += 1;
}
hnow += hours;
if (hnow > 23) {
hnow -= 24;
}
clock.setAlarm1(0, hnow, mnow, sec, DS3231_MATCH_H_M_S);
}
void sleepNow() {
ADCSRA = 0;
power_all_disable();
attachInterrupt(0, wakeUp, LOW);
PINs_to_sleep();
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
sleep_enable();
sleep_mode();
sleep_disable();
power_all_enable();
detachInterrupt(0);
PINs_to_work();
delay(100);
}

