Необходимо управлять удаленно из дома исполнительными устройствами в помещении на участке, расположенном примерно в 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 | Поиск в магазине Отрон | |||
Скачать список элементов (PDF)
Прикрепленные файлы:
- si4432.zip (5 Кб)
Комментарии (4) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
[Автор]