Помогите со спящим режимом
- Войдите на сайт для отправки комментариев
Сб, 13/12/2014 - 17:27
Добрый день знатоки. Помогите со спящим режимом. Хочу чтобы ардуина просыпалась через каждую минуту, посылала данные через nrf, дождавшись ответа снова засыпала.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <stdint.h>
#include <avr/sleep.h>
#include <avr/power.h>
#define CE_PIN 9
#define CSN_PIN 10 //для UNO
const uint64_t writingPipe = 0xE8E8F0F0AALL;
uint32_t message; // Эта переменная для сбора обратного сообщения от приемника;
int T;
int Pos[3];
int sleepStatus = 0; // Переменная для хранения статуса (спим, проснулись) - не используется в коде
int count = 0; // Счетчик
RF24 radio(CE_PIN, CSN_PIN);
void setup() {
Serial.begin(9600);
delay(2000);
pinMode(2, OUTPUT);
radio.begin();
radio.setChannel(0); // канал для передачи
radio.setRetries(15,15); //
radio.setDataRate(RF24_250KBPS); // скорость передачи
radio.setPALevel(RF24_PA_MAX); // мощность передатчмка
radio.setAutoAck(1);
radio.openWritingPipe(writingPipe);
radio.enableAckPayload(); // разрешаем посылку message
}
void loop(){
digitalWrite(8, HIGH);//подаем питание на D8
delay(500);
T = analogRead(7); //читаем напряжение на А7
digitalWrite(2, LOW);//отключаем питание на D8
Pos[0] = 0;
Pos[1] = T;
Pos[2] = 1;
radio.write( &Pos, sizeof(Pos) );
if ( radio.isAckPayloadAvailable() ) { // Ждем получения...
radio.read(&message,sizeof(message)); //
}
if (message = 111) { // если пришел ответ то спать
********** ЗАСТАВИТЬ АРДУИНО СПАТЬ *****************
}
}
Читал здесь на форуме темы про спящий режим, но ничего конкретного не нашел.
а вообще почитать?
http://playground.arduino.cc/Learning/ArduinoSleepCode
http://inet-deal.mpa.ru/articles/arduino-003.html
Спасибо, видел эти статьи. Не пойму можно ли во время сна пользоваться обычным таймеро или он не будет работать. Правильно ли будет использовать MsTimer2::set(10000, wakeUpNow); или надо как-то использовать сторожевой таймер(не особо понимаю что это).
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <stdint.h> #include <avr/sleep.h> #include <avr/power.h> #include <MsTimer2.h> #define CE_PIN 9 #define CSN_PIN 10 //для UNO const uint64_t writingPipe = 0xE8E8F0F0AALL; uint32_t message; // Эта переменная для сбора обратного сообщения от приемника; int T; int Pos[3]; int sleepStatus = 0; // Переменная для хранения статуса (спим, проснулись) - не используется в коде int count = 0; // Счетчик RF24 radio(CE_PIN, CSN_PIN); void wakeUpNow() { sleep_disable(); // после просыпания - выключить спящий режим } void setup() { MsTimer2::set(10000, wakeUpNow); // 10000 ms = 10 s MsTimer2::start(); Serial.begin(9600); delay(2000); pinMode(2, OUTPUT); radio.begin(); radio.setChannel(0); radio.setRetries(15,15); radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_MAX); radio.setAutoAck(1); radio.openWritingPipe(writingPipe); radio.enableAckPayload(); } void sleepNow() // Функция увода ардуины в спячку. { set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Здесь устанавливается режим сна sleep_enable(); // Включаем sleep-бит в регистре mcucr. Теперь возможен слип sleep_mode(); // Здесь устройство перейдет в режим сна!!! } void loop(){ digitalWrite(8, HIGH);//подаем питание на D8 delay(500); T = analogRead(7); //читаем напряжение на А7 digitalWrite(2, LOW);//отключаем питание на D8 Pos[0] = 0; Pos[1] = T; Pos[2] = 1; radio.write( &Pos, sizeof(Pos) ); if ( radio.isAckPayloadAvailable() ) { // Ждем получения... radio.read(&message,sizeof(message)); //... и имеем переменную message с числом 111 от приемника. } if (message = 111) { // если пришел ответ то спать Serial.println(111); sleepNow(); // засыпаем } }Не пойму можно ли во время сна пользоваться обычным таймеро или он не будет работать.
Смотря какую глубину сна выберете. Там их несколько, и для каждой стадии - описано: что будет работать, а что - нет...
Правильно ли будет использовать MsTimer2::set(10000, wakeUpNow); или надо как-то использовать сторожевой таймер(не особо понимаю что это).
Сторожевой таймер, по истечению установленного промежутка времени (8 секунд максимум), вызовет ресет платы кроме случая:
используется свойство "WDTCSR Bit 6 - WDIE: Watchdog Interrupt Enable", т.е. при установке этого бита в "единицу" первое срабатывание WatchDog будет просто вызывать прерывание а не ресетить процессор: разница в точке, с которой продолжается работа скетча.
Хотелось бы чтобы плата с датчиком работала от батарейки как можно дольше, как лучше быть. Я так понял, что MsTimer2::set(10000, wakeUpNow); будет работать только в режиме SLEEP_MODE_PWR_SAVE: 1.62 mA.
Посоветуйте пожалуйста как мне решить проблему, просыпаться нужно хотя бы раз в минуту.
Посоветуйте пожалуйста как мне решить проблему, просыпаться нужно хотя бы раз в минуту.
Тут либо спать кусочками по 8 секунд, либо отключать WatchDog и "будить" МК с помощью внешнего раздражителя-таймера, который, в свою очередь, тоже будет кушать электричество. У DS3107 есть внутренние будильники, которые можно было бы использовать для этого.
У DS3107 есть внутренние будильники, которые можно было бы использовать для этого.
О! А я блин и не знал. Спасибо!
А на счет MsTimer2::set(10000, wakeUpNow); будет работать только в режиме SLEEP_MODE_PWR_SAVE, это я правильно понимаю. Гляньте пожалуйста мой код, корректно ли будет сделать так если я заменю SLEEP_MODE_PWR_DOWN на SLEEP_MODE_PWR_SAVE.