Радио модули 443 МГц представляют собой передатчик (FS1000A) и приёмник (MX-RM-5V) которые предназначены для передачи данных по радиоканалу, на частоте 433,920 МГц.
Характеристики передатчика FS1000A
- Рабочая частота: 433.920 МГц (указывается на металлическом корпусе модуля)
- Тип модуляции: ASK — амплитудная манипуляция
- Дальность передачи: до 100 м (в зоне прямой видимости, без антенны)
- Выходная мощность: до 40 мВт
- Напряжение питания: 3 … 12 В
- Ток потребления в режиме ожидания: 0 мА
- Ток потребления в режиме передачи: 20 .. 30 мА
Характеристики приёмника MX-RM-5V
- Рабочая частота: 433.920 МГц
- Тип модуляции: ASK — амплитудная манипуляция
- Дальность приёма: до 100 м (в зоне прямой видимости, без антенны)
- Напряжение питания: 5 В
- Ток потребления: 4 мА
На этой странице представлены несколько практических скетчей применения радио модулей. Первый пример скетча тестовое включение радиомодулей, в качестве микроконтроллеров в тестовом скетче можно использовать Atmega8, Atmega88, Atmega168 и Atmega328 (Arduino Nano).
Для увеличения дальности связи рекомендуется к приемнику и передатчику припаять антенны (одножильный медный провод длиной 17,3 см).
Вам понадобится следующие библиотеки:
Для тестового скетча Вам необходимо собрать схему:
Передатчик
// pin DATA === D12 #include <VirtualWire.h> void setup(void) { vw_set_ptt_inverted(true); vw_setup(2000); } void loop(void) { int number = 12345; String symbol = "a"; String strMsg = "z "; strMsg += symbol; strMsg += " "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); delay(200); }
Приемник
// pin DATA === D11 #include <VirtualWire.h> void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) { int i=4; if (buf[0] != 'z'){return; } char command = buf[2]; int number = 0; while (buf[i] != ' '){ number *= 10; number += buf[i] - '0'; i++; } Serial.print(command); Serial.print(" "); Serial.println(number); } }
После загрузки скетчей откройте монитор порта (приемник), в нем Вы должны увидеть следующее:
Если в мониторе порта приемника отображаются верные значения символов передаваемые передатчиком , то можно приступить к следующему примеру, в котором при нажатии кнопки на D7 будет загораться или гаснуть светодиод на D13 (установлен на плате Arduino Nano).
Передатчик
// pin DATA === D12 #include <VirtualWire.h> char symbol; bool w; void setup(void){ vw_set_ptt_inverted(true); vw_setup(2000); pinMode(7,INPUT_PULLUP); } void loop(void){ if(digitalRead(7)==LOW && w==0){w=1; symbol='a';delay(200);} if(digitalRead(7)==LOW && w==1){w=0; symbol='b';delay(200);} String strMsg = "z "; strMsg += symbol; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); }
Приемник
// pin DATA === D11 #include <VirtualWire.h> void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); pinMode(13,OUTPUT); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) { int i=4; if (buf[0] != 'z'){return; } char command = buf[2]; if(command=='a'){digitalWrite(13,HIGH);} if(command=='b'){digitalWrite(13,LOW);} Serial.println(command); } }
При нажатии кнопки передатчик отсылает в приемник символ «a», загорается светодиод, при повторном нажатии кнопки передатчик отсылает в приемник символ «b», светодиод гаснет.
В следующем примере уже используется 4-е кнопки в передатчике и 4-е выхода управления реле в приемнике.
Передатчик
// pin DATA === D12 #include <VirtualWire.h> int number; bool w1,w2,w3,w4; void setup(void){ vw_set_ptt_inverted(true); vw_setup(2000); pinMode(7,INPUT_PULLUP); pinMode(6,INPUT_PULLUP); pinMode(5,INPUT_PULLUP); pinMode(4,INPUT_PULLUP); } void loop(void){ if(digitalRead(7)==LOW && w1==0){w1=1;number |= (1<<0);delay(200);} if(digitalRead(7)==LOW && w1==1){w1=0;number &=~(1<<0);delay(200);} if(digitalRead(6)==LOW && w2==0){w2=1;number |= (1<<1);delay(200);} if(digitalRead(6)==LOW && w2==1){w2=0;number &=~(1<<1);delay(200);} if(digitalRead(5)==LOW && w3==0){w3=1;number |= (1<<2);delay(200);} if(digitalRead(5)==LOW && w3==1){w3=0;number &=~(1<<2);delay(200);} if(digitalRead(4)==LOW && w4==0){w4=1;number |= (1<<3);delay(200);} if(digitalRead(4)==LOW && w4==1){w4=0;number &=~(1<<3);delay(200);} String strMsg = "z "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); }
Приемник
// pin DATA === D11 #include <VirtualWire.h> void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) { int i=2; if (buf[0] != 'z'){return; } int number = 0; while (buf[i] != ' '){ number *= 10; number += buf[i] - '0'; i++; } Serial.println(number); if(((number >> 0) & 1) ==1){digitalWrite(2,HIGH);}else{digitalWrite(2,LOW);} if(((number >> 1) & 1) ==1){digitalWrite(3,HIGH);}else{digitalWrite(3,LOW);} if(((number >> 2) & 1) ==1){digitalWrite(4,HIGH);}else{digitalWrite(4,LOW);} if(((number >> 3) & 1) ==1){digitalWrite(5,HIGH);}else{digitalWrite(5,LOW);} } }
В этом примере нажатие определенной кнопки передатчика меняет состояние битов байта number, приемник получает этой байт и в зависимости от состояния битов байта number, меняет состояние цифровых выходов D2 D3 D4 D5, к которым можно подключить четыре модуля реле или другой исполнительный элемент.
Далее рассмотрим пример создания простого электронного термометра с диапазоном измерения о 0 до 100 °С, в качестве датчика температуры будет использован цифровой датчик DS18B20, который подключается к передатчику, информация о температуре передается в приемник и выводится на LCD1602 с I2C модулем.
Передатчик
// pin DATA === D12 #include <VirtualWire.h> #include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip OneWire ds(2); // Вход датчика 18b20 void setup(void){ vw_set_ptt_inverted(true); // Необходимо для DR3100 vw_setup(2000); // Устанавливаем скорость передачи (бит/с) } void loop(void) { int number = dsRead(0)*100; char symbol = 'c'; String strMsg = "z "; strMsg += symbol; strMsg += " "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); Serial.println(msg); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); // Ждем пока передача будет окончена delay(2000); } float dsRead(byte x) { byte data[2], addr[8][8], kol = 0; while (ds.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков kol++; } ds.reset_search(); // Сброс поиска датчика ds.reset(); // Инициализация, выполняется сброс шины ds.select(addr[x]); // Обращение к датчику по адресу ds.write(0x44, 0); // Измерение температуры с переносом данных в память ds.reset(); // Инициализация, выполняется сброс шины ds.select(addr[x]); // Обращение к датчику по адресу ds.write(0xBE); // Обращение памяти data[0] = ds.read();// Чтение памяти byte low data[1] = ds.read();// Чтение памяти byte high float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод }
Приемник
// pin DATA === D11 #include <VirtualWire.h> #include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 #include <Wire.h> LiquidCrystal_I2C lcd(0x27,16,2); byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}; byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C}; byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C}; byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07}; byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}; byte d1,d2,d3,d4,d5,d6,e1,e2,e3,a[6],x; void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); Wire.begin();lcd.init();lcd.backlight(); lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4); lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)){ int i=4; if (buf[0] != 'z'){return;} char command = buf[2]; int number = 0; while (buf[i] != ' '){ number *= 10; number += buf[i] - '0'; i++; } Serial.print(command); Serial.print(" "); Serial.println(number); a[0]=number/1000; a[1]=number/100%10; a[2]=number/10%10; a[3]=number%10; if(number<1000){a[0]=10;} if(number<100){a[1]=10;} for(x=0;x<4;x++){ switch(x){ case 0: e1=0;e2=1,e3=2;break; case 1: e1=3,e2=4,e3=5;break; case 2: e1=7,e2=8,e3=9;break; case 3: e1=10,e2=11,e3=12;break; }digit();} lcd.setCursor(6,1);lcd.print("."); lcd.setCursor(14,1);lcd.write((uint8_t)223);;lcd.print("C"); lcd.setCursor(15,0);lcd.print("*"); delay(200); } else{lcd.setCursor(15,0);lcd.print(" ");} } void digit(){ switch(a[x]){ case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break; case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break; case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break; case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break; case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break; case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break; case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break; case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break; case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break; } lcd.setCursor(e1,0);lcd.write((uint8_t)d1); lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);lcd.setCursor(e1,1); lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}
Передатчик с интервалом в 2 секунды передает температуру, приемник получет значение температуры и выводит ее на LCD дисплей, в момент получения информации на экран выводится символ «*».
Следующий скетч демонстрирует работу двух передатчиков и одного приемника.
Как видно на скриншоте первый передатчик отсылает символ «а» и число 12345, а второй передатчик символ «b» и число 6789. В мониторе порта приемника Вы можете увидеть одновременный прием информации с обеих передатчиков.
Передатчик 1
#include <VirtualWire.h> void setup(void) { vw_set_ptt_inverted(true); vw_setup(2000); } void loop(void) { int number = 6789; String symbol = "b"; String strMsg = "v "; strMsg += symbol; strMsg += " "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); delay(200); }
Передатчик 2
#include <VirtualWire.h> void setup(void) { vw_set_ptt_inverted(true); vw_setup(2000); } void loop(void) { int number = 12345; String symbol = "a"; String strMsg = "z "; strMsg += symbol; strMsg += " "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); delay(200); }
Приемник
#include <VirtualWire.h> int i; char command_z,command_v; int number_z,number_v; void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) { i=4; if (buf[0] == 'v'){ command_v = buf[2]; number_v = 0; while (buf[i] != ' '){ number_v *= 10; number_v += buf[i] - '0'; i++; }} i=4; if (buf[0] == 'z'){ command_z = buf[2]; number_z = 0; while (buf[i] != ' '){ number_z *= 10; number_z += buf[i] - '0'; i++; }} Serial.print(command_z); Serial.print(" "); Serial.println(number_z); Serial.print(command_v); Serial.print(" "); Serial.println(number_v); } }
Энергосбережение
Во всех выше показанных скетчах передатчики непрерывно отсылают пакеты информации, в каких то проектах это необходимо, например в скетче электронного термометра, но в таком примере как управление 4-я реле в постоянной отсылке пакетов информации нет необходимости, тем более передатчик в подобном проекте лучше запитывать от батареи или аккумулятора, поэтому ниже показан скетч на примере управления 4-я реле который отсылает пакет информации в приемник только в момент нажатия кнопки. Это дает возможность более эффективно использовать элемент питания который питает передатчик.
Передатчик
// pin DATA === D12 #include <VirtualWire.h> int number; bool w1,w2,w3,w4,w; void setup(void){ vw_set_ptt_inverted(true); vw_setup(2000); pinMode(7,INPUT_PULLUP); pinMode(6,INPUT_PULLUP); pinMode(5,INPUT_PULLUP); pinMode(4,INPUT_PULLUP); } void loop(void){ if(digitalRead(7)==LOW && w1==0){w1=1;number |= (1<<0);delay(200);w=1;} if(digitalRead(7)==LOW && w1==1){w1=0;number &=~(1<<0);delay(200);w=1;} if(digitalRead(6)==LOW && w2==0){w2=1;number |= (1<<1);delay(200);w=1;} if(digitalRead(6)==LOW && w2==1){w2=0;number &=~(1<<1);delay(200);w=1;} if(digitalRead(5)==LOW && w3==0){w3=1;number |= (1<<2);delay(200);w=1;} if(digitalRead(5)==LOW && w3==1){w3=0;number &=~(1<<2);delay(200);w=1;} if(digitalRead(4)==LOW && w4==0){w4=1;number |= (1<<3);delay(200);w=1;} if(digitalRead(4)==LOW && w4==1){w4=0;number &=~(1<<3);delay(200);w=1;} if(w==1){w=0; String strMsg = "z "; strMsg += number; strMsg += " "; char msg[255]; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); } }
Приемник
// pin DATA === D11 #include <VirtualWire.h> void setup(){ Serial.begin(9600); vw_set_ptt_inverted(true); vw_setup(2000); vw_rx_start(); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); } void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) { int i=2; if (buf[0] != 'z'){return; } int number = 0; while (buf[i] != ' '){ number *= 10; number += buf[i] - '0'; i++; } Serial.println(number); if(((number >> 0) & 1) ==1){digitalWrite(2,HIGH);}else{digitalWrite(2,LOW);} if(((number >> 1) & 1) ==1){digitalWrite(3,HIGH);}else{digitalWrite(3,LOW);} if(((number >> 2) & 1) ==1){digitalWrite(4,HIGH);}else{digitalWrite(4,LOW);} if(((number >> 3) & 1) ==1){digitalWrite(5,HIGH);}else{digitalWrite(5,LOW);} } }
Как видно из скетча, в код нажатия кнопки добавлена переменная «w», при нажатии нажатии кнопки состояние переменной меняется на 1, далее если переменная равна 1 исполняется код отправки сообщения и переменная меняет свое состояние на 0, что не дает повторно отправить сообщение пока не будет снова нажата кнопка.
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=6463#p6463