Беспроводной диммер

Bee
Offline
Зарегистрирован: 08.01.2016

Здравствуйте всем!

Под старость лет решил всртяхнусть молодостью и сесть за реализацию своих хотелок... Но видимо уже мозг не так работает как в молодости и многое, что раньше (касаемо програмирования) делалось за 5-10 минут, сейчас уходит ГОРАЗДО больше времени.

Пока вот такая у меня идея... Необходимо реализовать управлеие подсветкой (а может и нетолько) без проводов.

Т.к. давно еще покупал модули NRF24L01+ и ардуаинки Pro Mini (5V), то при помощи поиска удалось реализовать передающюю часть и приемную (пока только комманды). Но это уже прогресс.

В качестве передающей части использую NRF24L01+ , Pro Mini (5V) и Энкодер с кнопкой... И пока научился передовать такие комманды как: Вращение вправо, Вращение влево, Нажатие кнопки, Двойное нажатие кнопки, Начало долгого нажатия кнопки, Удержание при долгом нажатии кнопки, Окончание долгого нажатия кнопки. Питать планируется от трехвольтовой Li-Ion батарейки. Так-же передающий блок должен отправлять раз в 15 минут (параметр настраиваемый) напряжение батарейки. Названия и структура полей еще не определена, но хочется некой универсальности...

Приемной частью планируется быть устройство с питанием от источника питания (не от батарейки), и передачей информации по MQTT (Скорее всего это будет ESP8266 и NRF24L01+). MQTT есть свой в сети.

Проблемы возникли с потреблением передающей части... Много читал про прерывания про спячку, про глубокую спячку... Про изменения загрузчика у ProMini и перевод его на 8Мгц и питание 3Вольта. А может быть и сильно много 328р камня для всего этого?

В передатчике за исключением подключения NRF24L01+ необходимо еще: 4 вывода (2 - энкодер, 1 - кнопка, 1 - измерение питания..) Может какой другой процессор использывать с менишей частотой и потреблением? Тогда возникает вопрос, как он будет совместим с кодом для Pro Mini ? Или как его перекомпилить под новый Amtel?

Для более обширного диалога привожу пока что есть для передатчика и приемника.

Передатчик:

#include <Rotary.h>                     // Rotary-master https://github.com/brianlow/Rotary
#include <OneButton.h>                  // OneButton https://github.com/mathertel/OneButton
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>                       

Rotary encoder = Rotary(2, 3);
OneButton button(4, true);
RF24 radio(9, 10);                      // CE, CSN
const uint64_t pipe = 0xF0F1F2F3F4LL;   // индитификатор передачи, "труба"
int msg[1];

void setup() {
  
  Serial.begin(115200);
  Serial.println("Power ON...");

  button.attachClick(ClickFunction);
  button.attachDoubleClick(DoubleclickFunction);
  button.attachLongPressStart(LongPressStartFunction);
  button.attachLongPressStop(LongPressStopFunction);
  button.attachDuringLongPress(LongPressFunction);

  /*************************                Модуль NRF24                **********************/
  delay(100);                             // Пусть зарядится конденсатор на NRF24
  radio.begin();                          // Включение модуля;
  delay(2);                               // Так было
  radio.setChannel(9);                    // Установка канала вещания;
//  radio.setRetries(15,15);                // Установка интервала и количества попыток "дозвона" до приемника;
  radio.setDataRate(RF24_250KBPS);        // Установка минимальной скорости RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
  radio.setPALevel(RF24_PA_LOW);          // Установка максимальной мощности RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM,
//  radio.setAutoAck(1);                    // Установка режима подтверждения приема;
  radio.openWritingPipe(pipe);            // Активация данных для отправки
  radio.openReadingPipe(1,pipe);          // Активация данных для чтения
//  radio.startListening();                 // Слушаем эфир.
//  radio.printDetails();

}

void loop() {

  /*************************                Кнопка                **********************/
  button.tick();


  /*************************               Энкодер                **********************/
  unsigned char rotary = encoder.process();
  if (rotary == DIR_NONE) {
    // do nothing
  }
  else if (rotary == DIR_CW) {
    LeftRotation();
  }
  else if (rotary == DIR_CCW) {
    RightRotation();
  }

  /*************************                Еще                  **********************/

}


void LeftRotation() {
  msg[0] = 1; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("LeftRotation. (1)");
}

void RightRotation() {
  msg[0] = 2; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("RightRotation. (2)");
}

void ClickFunction() {
  msg[0] = 3; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("Click. (3)");
} 


void DoubleclickFunction() {
  msg[0] = 4; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("Doubleclick.. (4)");
} 


void LongPressStartFunction() {
 msg[0] = 5; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("LongPress start (5)");
} 


void LongPressFunction() {
  msg[0] = 6; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("LongPress... (6)");
} 


void LongPressStopFunction() {
  msg[0] = 7; // присваиваем значение
  radio.stopListening();
  radio.write(&msg, sizeof(msg)); // отправляем данные и указываем сколько байт пакет
  radio.startListening();
  Serial.println("LongPress stop (7)");
} 

Приемник:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h> // https://github.com/maniacbug/RF24

const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба"

RF24 radio(2, 15); // CE, CSN
  
void setup(){
  Serial.begin(115200);

      /*************************                Модуль NRF24                **********************/
    delay(500);                             // Пусть зарядится конденсатор
    radio.begin();                          // Включение модуля;
    delay(2);                               // Так было
    radio.setChannel(9);                    // Установка канала вещания;
//    radio.setRetries(15,15);                // Установка интервала и количества попыток "дозвона" до приемника;
    radio.setDataRate(RF24_250KBPS);        // Установка минимальной скорости RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
    radio.setPALevel(RF24_PA_LOW);          // Установка максимальной мощности RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM,
//    radio.setAutoAck(1);                    // Установка режима подтверждения приема;
    radio.openWritingPipe(pipe);     // Активация данных для отправки
    radio.openReadingPipe(1,pipe);          // Активация данных для чтения
    radio.startListening();                 // Слушаем эфир.
//    radio.printDetails();
}

void loop()   
{  
  int data; 
  
  if (radio.available()){ // проверяем не пришло ли чего в буфер.
    radio.read(&data, sizeof(data)); // читаем данные, указываем сколько байт читать
    
    Serial.print("data: ");
    Serial.println(data); 
  } 
} 

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

переводить  на 3в питания и работу от внутреннего генератора. режим повер довн для радиомодуля, сон и так далее

Bee
Offline
Зарегистрирован: 08.01.2016

Я это понимаю... А под эти задачи 328р не многовато? Может что-нибудь другое? 

Сейчас пытаю библиотеку LowPower - https://github.com/rocketscream/Low-Power

Только вот вопрос у меня: какие входы на ардуино можно использовать для обработки просыпания по прерыванию? и какое их количество? (Ответ нашел тут - http://robotosha.ru/arduino/arduino-interrupts.html)

В идеале хочу получить такой алгоритм:

1. Как только начали вращать энкодер или нажимать кнопки - пробуждаем ProMini , выводим из спячки NRF24, передаем комманду. При неактивности кнопок и энкодера 3 секунды - переводим NRF24 в спячку и ProMini тоже в глубокий сон.

2. Каждые 20 минут пробуждаем ProMini , выводим из спячки NRF24 отправляем напряжение питания и возможно состояния некоторых выводов (а может и температурного датчика) и уводим в обратной последовательности в спячку.