Удаленное управление исполнительными устройствами по радиоканалу

Необходимо управлять удаленно из дома исполнительными устройствами в помещении на участке, расположенном примерно в 20м от дома. В основном это включение/выключение освещения, а также включение насосов для полива и фонтана.

Используем Arduino и радиомодули SI4432, Необходимо 2 устройства:

  • пульт (Arduino с кнопками и дисплеем)
  • Arduino c блоком реле

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

Модули трансивера SI4432 на основе микросхемы SI4432 позволяют реализовать устойчивую двустороннюю радиосвязь в диапазоне частот от 240 до 930 МГц на расстоянии до 1 км на открытой местности и 100 — 300м в помещении. Скорость  передачи данных 0.123-256 kbps, виды модуляции  — FSK, GFSK, OOK. Мощность передатчика до +20 dBm. Модули имеют малый размер.

 

Характеристики модуля SI4432

  • Частотный диапазон: 240 –930 МГц;
  • Чувствительность приемника: до 121 дБм;
  • Модуляция сигнала: FSK (ЧМн), GFSK (ГЧМн), OOK (АМн);
  • Максимальная выходная мощность: 20 дБм;
  • Скорость передачи данных: 0.123-256 Кбит/с;
  • Напряжение питания: 1.8-3.6 В;
  • Рабочая температура: от -20 до 60 °C.

Назначение выводов

 

  • VDD — питание модуля;
  • GND — общий;
  • NSEL — вывод разрешения интерфейса SPI;
  • SCLK — вывод синхронизации интерфейса SPI;
  • SDI — вывод получения данных интерфейса SPI;
  • SDO — вывод отправки данных интерфейса SPI;
  • NIRQ — вывод прерываний по получению данных;
  • SDN — вывод перехода в режим энергосбережения (HIGH); 
  • GPIO0, GPIO1, GPIO2 — программируемые порты ввода/вывода.

Подключение к плате Arduino

Модули работают по протоколу SPI. Для Подключение к плате Arduino согласно таблице 1. При этом обязательно согласование уровней 3.3 В → 5 В, необходимо использовать конвертер уровня!!! Для питания модулей желательно использовать внешний источник питания 3.3 В (при передаче на небольшое расстояние возможно брать питание с вывода 3.3 В платы Arduino).

SI4432

Arduino UNO

Arduino Mega

GND

GND

GND

SDN

GND

GND

NIRQ

D2

D2

NSEL

D10

D53

SCLK

D13

D52

SDI

D11

D51

SDO

D12

D50

Схемы соединения элементов

1) пульт

2) исполнительный блок

Скетч для пульта.

По нажатии кнопки должно меняться состояние релею На пульте хранится в массиве

uint8_t status_click[]={48,48,48,48,48,48,48,48};   // 48-выкл,  49-вкл

При нажатии кнопки значение в массиве меняется на противоположное.

При нажатии кнопки, а также каждые 200 секунд пульт отправляет массив состояний реле и в ответ ждет подтверждения — такой же массив.

Полученное состояние массива выводится на дисплей из 4 семисегментных индикаторов TM1637

 #define YES 0 #define NO 1  #define LED 13  #include <SPI.h> #include <RF22.h> #include "TM1637Display.h" #include <EEPROM.h>  TM1637Display display(8, 9); // CLC, DIO  // for display const uint8_t n00[] = {   //SEG_D  // _ }; const uint8_t n00_2[] = {   SEG_DP  //SEG_D  // _: }; const uint8_t n11[] = {   SEG_B | SEG_C |  SEG_E | SEG_F  // |_| }; const uint8_t n11_2[] = {   SEG_B | SEG_C |  SEG_E | SEG_F | SEG_DP  // |_|: }; const uint8_t n10[] = {   SEG_E | SEG_F  // |_ }; const uint8_t n10_2[] = {   SEG_E | SEG_F | SEG_DP  // |_ }; const uint8_t n01[] = {   SEG_B | SEG_C  // _| }; const uint8_t n01_2[] = {   SEG_B | SEG_C | SEG_DP  // _|: }; const uint8_t err[] = {   SEG_A | SEG_D | SEG_E | SEG_F | SEG_G,            // E   SEG_D ,           // _   SEG_E | SEG_G,           // r   SEG_A | SEG_E | SEG_F | SEG_G            // F }; const uint8_t err1[] = {   SEG_A | SEG_D | SEG_E | SEG_F | SEG_G,            // E   SEG_D | SEG_DP ,           // _   SEG_E | SEG_G,           // r   SEG_A | SEG_E | SEG_F | SEG_G            // F };  // buttons pins //int pinButtons[]={A5,A1,A4,A0,6,A3,7,A2}; int pinButtons[]={A5,A6,A4,A0,6,A3,7,A2};  // bad - A6 int lastButtons[]={NO,NO,NO,NO,NO,NO,NO,NO}; int currentButtons[]={NO,NO,NO,NO,NO,NO,NO,NO}; boolean change=false; //uint8_t status_click[]={1,1,1,1,1,1,1,1,1,1}; uint8_t status_click[]={48,48,48,48,48,48,48,48};  // Singleton instance of the radio RF22 rf22;  void(* resetFunc) (void) = 0;  int counterr=0; unsigned long millist=0; int cntm=0;  void setup() {   //     Serial.begin(9600);   Serial.println("start");   // ini   if(EEPROM.read(11) != 55)     iniDataEEPROM();   readDataEEPROM();     // пины кнопок   for(int i=0;i<8;i++) {     pinMode(pinButtons[i],INPUT_PULLUP);   }   // пин 13: горит - ok, нет - False   pinMode(LED,OUTPUT);   digitalWrite(LED,LOW);   // display   display.setBrightness(4); // яркость от 0 до 7, true/false   display.clear();   // connect   if (!rf22.init()){     // Defaults after init are 434.0MHz, 0.05MHz AFC pull-in, modulation FSK_Rb2_4Fd36     Serial.println("RF22 init failed");     counterr++;     if(counterr%2==0)       display.setSegments(err);     else       display.setSegments(err1);     delay(500);     if(counterr>5)       resetFunc();    }   delay(200);    display.clear();   digitalWrite(LED,HIGH);   sendrf(); }  void loop() {   // сканирование кнопок   for(int i=0;i<8;i++) {        currentButtons[i] = debounce(lastButtons[i],pinButtons[i]);    // если нажатие...    if (lastButtons[i] == NO && currentButtons[i] == YES) {      ;     }    //если отжатие    else if (lastButtons[i] == YES && currentButtons[i] == NO) {       Serial.print("onclick=");Serial.println(i);       if(status_click[i]==48)          status_click[i]=49;       else          status_click[i]=48;       change=true;    }       lastButtons[i]  = currentButtons[i];       }   // send if change=true   if(change==true) {      sendrf();   }   if((millis()-millist) > 20*1000) {     cntm=(cntm+1)%10;     if(cntm==0){         sendrf();Serial.println(millist);     }     millist=millis();        } }

Полностью скетч прикреплен в архиве для скачивания.

Скетч для блока исполнительных устройств

 #define ON 1 #define OFF 0  #define LED 13  #include <SPI.h> #include <RF22.h>  // relays pins //int pinRelays[]={A3,7,A2,6,5,6,A0,4}; int pinRelays[]={A3,7,A2,6,A1,5,A0,4}; uint8_t status_relays[]={0,0,0,0,0,0,0,0};  // Singleton instance of the radio RF22 rf22;  void(* resetFunc) (void) = 0;  void setup() {   Serial.begin(9600);   // pins relay ini   for(int i=0;i<8;i++) {     pinMode(pinRelays[i],OUTPUT);     digitalWrite(pinRelays[i],OFF);   }   // пин 13: горит - ok, нет - False   pinMode(LED,OUTPUT);   digitalWrite(LED,LOW);   //   if (!rf22.init()){     Serial.println("RF22 init failed");     digitalWrite(LED,HIGH);     // перезагрузка     delay(3000);     resetFunc();   } }  void loop() {   while (1)   {     rf22.waitAvailable();     //Serial.println(millis());     // Should be a message for us now        //uint8_t buf[RF22_MAX_MESSAGE_LEN];     uint8_t buf[9];     uint8_t len = sizeof(buf);     if (rf22.recv(buf, &len))     {       Serial.println("got request: ");       Serial.println((char*)buf);        // relay        for(int i=7;i>=0;i--){          status_relays[i]=buf[7-i]-48;          Serial.print(status_relays[i]);       }       // включение/выключение        for(int i=0;i<8;i++){          if(status_relays[i]==1)           digitalWrite(pinRelays[i],ON);          else           digitalWrite(pinRelays[i],OFF);           Serial.print("pinRelay ");Serial.print(pinRelays[i]);Serial.print("=");Serial.println(status_relays[i]);       }       //delay(500);             // Send a reply       uint8_t data[9]={0,0,0,0,0,0,0,0,0};       for(int i=0;i<8;i++) {          data[i]=status_relays[i]+48;             }       rf22.send(data, sizeof(data));       rf22.waitPacketSent();       Serial.println("Sent a reply");     }     else     {       Serial.println("recv failed");     }   } }

Скетч прикреплен в архиве для скачивания.

 

Питание

На пульте в EEPROM Arduino хранится информация о статусах реле. Включаем по мере необходимости. Используем обычный китайский блок питания 5В 2А.

Для блока исполнительных устройств питание — такой же китайский блок питания 5В 2А.

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Контроллер Плата Arduino Arduino Nano 3.0 2
Радиомодуль si4432 2
Конвертер логического уровня 2
Кнопка 8
Дисплей TM1637 1
Реле шилд на 8 1
Клеммная колодка KF301 2
Блок питания 5В 2А 1