i2c в режиме SLEEP_MODE_PWR_DOWN
- Войдите на сайт для отправки комментариев
Всем доброго времени суток!
Пытаюсь сделать метеостанцию и столкнулся с проблемой спящего режима. У станции будет 2 датчика:датчик температуры dht22 и датчик освещенности BH1750. Станция должна посылать показания по радиоканалу один раз в 5 минут и засыпать. Станция работает от батареек, поэтому вопрос энергопотребления критичен. Почитал про режимы сна и выяснил, что для снижения энергопотребления нужно все пины переводить в режим output low. И действительно, в этом случае мне удалось довести энергопотребление до 0,001 мА (1 мкА) в режиме сна. Но возникла следующая проблема: датчик BH1750 работаем по шине i2c. Когда я перевожу пин A5 в режим output low, микроконтроллер первый раз обрабатывает это нормально, а на второй итерации зависает. Код программы привожу. Еще раз хочу отметить, что одну итерацию микроконтроллер отрабатывает нормально. Знающие люди, подскажите, как правильно перевести пин A5 в режим low, чтобы потом продолжала работать шина i2c? Если его не переводить в режим low энергопотребление составляет около 0,1 мА, что довольно много для питания от батареек.
#include "DHT.h"
#include <VirtualWire.h>
#include "Wire.h"
#include "BH1750.h"
#include <meteo_packet.h>
#include <Adafruit_SleepyDog.h>
#include <avr/sleep.h>
#define DHTPIN 7 // номер пина, к которому подсоединен датчик температуры
void setup() {
}
void loop() {
ADCSRA = 0; // disable ADC
for (byte i = 0; i <= A4; i++)
{
pinMode (i, OUTPUT); // changed as per below
digitalWrite (i, LOW); // ditto
}
for(int sleep=0;sleep<1;)
{
sleep+=Watchdog.sleep(3000)/1000;
}
DHT dht(DHTPIN, DHT22); // Датчик температуры и влажности
BH1750 lightMeter; // Датчик освещенности
pinMode(2,OUTPUT);
digitalWrite(2,LOW);
vw_setup(2000);
vw_set_tx_pin(3);
digitalWrite(2,HIGH);
Watchdog.sleep(500);
lightMeter.begin();
dht.begin();
meteo_data m_data;
m_data.H = dht.readHumidity();//Считываем влажность
m_data.T = dht.readTemperature();// Считываем температуру
m_data.L = lightMeter.readLightLevel();
vw_send((uint8_t*)&m_data,sizeof(m_data));
vw_wait_tx();
}
Нужно переводить в спящий режим сам микроконтроллер. Отдельно порт не отключается.
Микроконтроллер в спящий режим естественно перевожу! Но такой нюанс: если просто перевести в режим сна, потребялет 0,1 мА, если перед этим перевести пин в low, то потребление 0,001 мА.
Столкнулся с такой же проблемой. Не нашли решения?
где то на просторах интернета находил информацию чтоVirtualWire.h
что то ломает при инициализации и ее не рекомендуют при использовании в МК с WDT
сам планирую использовать Manchester.h - пишут что более стабильно
Нашел, правда почему именно не работало, уже не помню. Высылаю рабочий код, из его анализа, надеюсь разберетесь, в чем причина.
#include "DHT.h" #define PB7_out DDRB |=1<<7; #define PB7_high PORTB|=1<<7; #define PB7_low PORTB&=~(1<<7); #include <VirtualWire.h> #include "Wire.h" #include "BH1750.h" #include <meteo_packet.h> #include <Adafruit_SleepyDog.h> #define DHTPIN 5 // номер пина, к которому подсоединен датчик температуры DHT dht(DHTPIN, DHT22); // Датчик температуры и влажности BH1750 lightMeter; // Датчик освещенности void setup() { pinMode (3, OUTPUT); PB7_out // Serial.begin(9600); // Serial.println("test"); } void loop() { digitalWrite(3,HIGH); // digitalWrite(7,HIGH); PB7_high Watchdog.sleep(500); lightMeter.begin(); dht.begin(); vw_setup(2000); vw_set_tx_pin(2); Watchdog.sleep(150); meteo_data m_data; m_data.L = lightMeter.readLightLevel(); m_data.H = dht.readHumidity(); m_data.T = dht.readTemperature(); pinMode(A2, INPUT);// Датчик дождя digitalWrite(A2,HIGH); m_data.R=analogRead(A2); vw_send((uint8_t*)&m_data,sizeof(m_data)); vw_wait_tx(); PB7_low for (byte i = 0; i <= A5; i++) { pinMode (i, OUTPUT); digitalWrite (i, LOW); } byte adcsra_save = ADCSRA; ADCSRA = 0; // disable ADC for(int sleep=0;sleep<6;) sleep+=Watchdog.sleep()/1000; ADCSRA=adcsra_save; // m_data.print(); }У меня на I2C висят часы DS3231. устройство уходит в сон на час и по будильнику от DS3231 (нога SQW) контролер должен просыпаться делать замеры и отправлять измерения по радио, после чего переставлять будильник на час вперед и снова засыпать, а ноги I2C жрут во сне 0,2 мА., что много для спящего. я пока попробую их принудительно в OUTPUT LOW режим перед сном отправлять, а после сна снова в INPUT, может сработает.