├── .gitignore ├── .vscode └── extensions.json ├── README.md ├── doc ├── cc1101.jpg ├── d1_mini.jpg ├── simple_modules.jpg └── superheterodyne.jpg ├── lib └── README ├── platformio.ini └── src └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .pioenvs 3 | .piolibdeps 4 | .vscode/.browse.c_cpp.db* 5 | .vscode/c_cpp_properties.json 6 | .vscode/launch.json 7 | .vscode/settings.json 8 | .ccls 9 | .clang_complete 10 | .gcc-flags.json 11 | .DS_Store 12 | lib/rc-switch 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DISCONTINUED 2 | 3 | As I moved my whole setup to a [FHEM](https://fhem.de) server with a [SIGNALduino](https://github.com/RFD-FHEM/SIGNALDuino) this project is now deprecated. This does *not* mean that its not working or will stop working in the future. 4 | 5 | The good news is that if you want to change your existing setup to FHEM as well you probably already have everything to do that. 6 | 7 | For example, with a C1101 module all you need to do is swap the GDO0 and GDO2 connections and you have a SIGNALduino ready to flash. 8 | 9 | ## Migration to FHEM 10 | 11 | - Make sure you have a HEX file of the current firmware to be able to go back 12 | - If using CC1101: switch cables for `GD0`and `GD2` 13 | - Download correct hex file (esp/nano/CC1101) from [SIGNALduino](https://github.com/RFD-FHEM/SIGNALDuino) releases 14 | - Upload hex using avrdude or esptool.py 15 | - See the [homebridge-433-arduino](https://github.com/normen/homebridge-433-arduino) project for the FHEM server setup 16 | 17 | # arduino-433 18 | Arduino/ESP based 433MHz home control transceiver 19 | 20 | ## Introduction 21 | This Arduino code allows you to create a cheap 433MHz wireless transceiver to control electric switches and other home appliances. It can use USB or WiFi to connect to a computer to receive and send commands. It is mainly used for the [homebridge-433-arduino](https://github.com/normen/homebridge-433-arduino) plugin but can of course be used otherwise as well. 22 | 23 | The project uses the PlatformIO IDE and runs on Arduino as well as ESP hardware. To decode signals the rc-switch or ESPiLight libraries can be used. Simple 433MHz receiver/sender hardware or more advanced CC1101 based transceiver modules are supported to send and receive 433MHz switch signals. 24 | 25 | This is not meant to be an advanced firmware but a hobby software that is simple to use, build and understand. 26 | 27 | ## Installation 28 | ### PlatformIO 29 | - Download and install the PlatformIO IDE, i.e. VisualStudioCode (see https://platformio.org) 30 | - Clone or download this github repository, e.g. `git clone https://github.com/normen/arduino-433` 31 | - Open the project folder in PlatformIO 32 | - Configure the platformio.ini build options if needed (see below) 33 | - Configure the code as needed (see below) 34 | - Connect the desired microcontroller and transceiver hardware (see below) 35 | - Build and upload the project to your Arduino or ESP 36 | 37 | #### Arduino IDE 38 | Alternatively you can copy-paste the code in `src/main.cpp` into the Arduino IDE and install the needed boards as well as the libraries listed under `lib_deps` in the `platformio.ini` file. Comment out the `#include "Arduino.h"` line in main.cpp when using Arduino IDE. *Note that using PlatformIO is recommended!* 39 | 40 | ## Recommended Setup 41 | The recommended setup is the D1 Mini board with a C1101 transceiver module and ESPiLight mode enabled. This gives you the simplest hardware connection, best radio preformance and the largest amount of supported switches out-of-the-box. For other options see the documentation below. 42 | 43 | Simply uncomment the `#define USE_CC1101` and `#define USE_ESPILIGHT` lines in the `src/main.ccp` file and connect the D1 Mini and C1101 boards according to the table below. 44 | 45 | ![D1 Mini Image](/doc/d1_mini.jpg?raw=true "D1 Mini ESP8266 Board")![CC1101 Image](/doc/cc1101.jpg?raw=true "CC1101 Transceiver") 46 | 47 | ```` 48 | ESP8266 / CC1101 49 | ------------------------------------ 50 | 3V3 (3,3V) / VCC 51 | G (GND) / GND 52 | D5 (SCK) / SCK 53 | D6 (MISO) / MISO 54 | D7 (MOSI) / MOSI 55 | D8 (SS) / CSN 56 | D1 (PWM) / GDO0 (TX) 57 | D2 (PWM) / GDO2 (RX) 58 | ```` 59 | 60 | ## Hardware Options 61 | ### Microcontrollers 62 | - ESP8266 / D1 Mini Board (3.3V) - recommended with CC1101, needed for WiFi and ESPiLight 63 | - Arduino Micro (5V) - best for the simple receivers/senders as they work at 5V 64 | - Arduino Nano (3.3V) - for CC1101 without WiFi or ESPiLight 65 | - Other Arduinos, ESP32 (see below) 66 | 67 | The PlatformIO project is by default set up for the D1 Mini board. Support for Arduino Micro is also prepared, change `default_envs` in platformio.ini to `micro` to switch. See the PlatformIO documentation on how to compile for other boards / hardware. Note that you will have to change the input/output pin values in the software for each type of microcontroller (see below). 68 | 69 | ### Simple 433MHz sender / receivers 70 | - Use 5V power 71 | - Cheap (0.5-2$) 72 | - For the sender these modules (e.g FS1000A) seem to work fine for me 73 | - For the receiver the very cheap modules didn't receive from very far for me 74 | 75 | ![Cheap Modules Image](/doc/simple_modules.jpg?raw=true "Simple Modules") 76 | 77 | ### Superheterodyne 433MHz receiver 78 | - Uses 5V power 79 | - These "superheterodyne" (NOT superregeneration) receivers worked much better for me than the simple receivers 80 | - Still Cheap (2-5$) 81 | 82 | ![superheterodyne image](/doc/superheterodyne.jpg?raw=true "Superheterodyne Receiver") 83 | 84 | ### CC1101 based 433MHz transceiver 85 | - Uses 3.3V power 86 | - Can receive and send in one module 87 | - Configurable via SPI 88 | - Often comes with a proper antenna 89 | - These modules work much better in general but might be more expensive (8-15$) 90 | 91 | ![CC1101 Image](/doc/cc1101.jpg?raw=true "CC1101 Transceiver") 92 | 93 | ### Connections 94 | #### Simple Modules 95 | For the simple modules and the superheterodyne receiver, connect a 173mm piece of solid wire as antenna to the ANT pin, connect VCC to 5V on the micorcontroller board and connect GND to ground on the microcontroller board. See below for which pin on the microcontroller to use for the receiver/sender DATA pins. 96 | 97 | #### CC1101 98 | For the CC1101 module, see [this repository](https://github.com/LSatan/RCSwitch-CC1101-Driver-Lib) for info and images showing how to connect these transceivers to various microcontrollers. See below for enabling support for the CC1101 module in the transceiver code. 99 | 100 | ## The Software 101 | ### Configuration 102 | To configure the transceiver open `src/main.cpp` and change/uncomment the following `#define` parameters. 103 | 104 | #### `#define RC_INPUT_PIN D2`/ `#define RC_OUTPUT_PIN D1` 105 | These values are needed and represent the input (receiver) and output (transmitter) pins. The microcontroller has to support interrupts on the input pin for the receiver, almost any output pin can be used for the transmitter. Note that these are actual pin numbers, not interrupt numbers. 106 | 107 | Usual Values: 108 | - ESP8266 109 | - Receiver on pin **`D2`** (IRQ4) 110 | - Sender on pin **`D1`** 111 | - Arduino Micro 112 | - Receiver on pin **`3`** (IRQ 0) 113 | - Sender on pin **`4`** 114 | - Arduino Nano 115 | - Receiver on pin **`2`** (IRQ 0) 116 | - Sender on pin **`6`** 117 | 118 | #### `#define USE_CC1101` 119 | You can use a more advanced CC1101 based transceiver module instead of simple 433MHz receiver/sender pairs. These modules also have send and receive pins but are additionally connected via SPI for configuration. 120 | 121 | Works on Arduino and ESP. 122 | 123 | #### `#define USE_WEBSOCKET` 124 | You can use WiFi to connect to the computer instead of USB. 125 | 126 | This will create a websocket server to send/receive data in addition to the serial port, default hostname is `arduino-433`, port 80. Specify your WiFi credentials in `#define WIFI_SSID "ssid_here"` and `#define WIFI_PASS "pass_here"`. 127 | 128 | Works on ESP. 129 | 130 | #### `#define USE_ESPILIGHT` 131 | You can use ESPilight insted of rc-switch to decode switches. 132 | 133 | The send/receive data format will change to JSON, with `type` and `message` content. Additionally pilight debug messages, always beginning with `pilight` might be generated. 134 | 135 | Works on ESP. 136 | 137 | ### Adding support for unsupported switches when using rc-switch 138 | If you have a 433 device that doesn't work you can try and download a different version of the rcswitch library and run a "discovery application" that suggests how to extend the rcswitch.cpp file to add support for the unknown signal: 139 | 140 | https://github.com/Martin-Laclaustra/rc-switch/tree/protocollessreceiver 141 | 142 | Use the `protocollessreceiver` branch in that repository, it includes the Arduino discovery application example. 143 | 144 | ### Transceiver transmit protocol 145 | *Note: If you're using homebridge-433-arduino you can skip this section unless you're interested in the interna of the transceiver communication.* 146 | 147 | In its default mode the transceiver will use the USB serial port to send rc-switch data (code, pulse, protocol) in a format like `12345/123/1` when any 433MHz codes are received and decoded. When receiving serial data in the same format the transceiver will send the corresponding 433MHz data and return an `OK` message. The serial data is terminated by `\n`. 148 | 149 | In ESPiLight mode the transceiver will send received signals in a JSON based format like `{"type":"switch_type","message":{"id":"A3","unit":"20","state":"off"}}`. When sending data the format changes slightly to `{"type":"switch_type","message":{"id":"A3","unit":"20","off":1}}`. See the ESPiLight documentation for more info. 150 | 151 | Accordingly, the transceiver will only ever output 4 types of messages: 152 | - Message `OK` -> after receiving a message and sending the corresponding code 153 | - Message starting with `{` -> JSON data when using ESPiLight 154 | - Message starting with `pilight` -> debug data when using ESPiLight 155 | - Message starting with a number -> code/pulse/protocol message when using rc-switch 156 | 157 | Note that when sending RC data the transceiver can not receive any new commands, wait until the `OK` message has been sent back before sending any new commands. 158 | 159 | ## License 160 | Published under the MIT License. 161 | 162 | ## Version History 163 | - Version 1.1 164 | - Use C1101 library from arduino library manager 165 | -------------------------------------------------------------------------------- /doc/cc1101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/normen/arduino-433/eb9c6707851628388ca5dfbce341d2ee970c94b9/doc/cc1101.jpg -------------------------------------------------------------------------------- /doc/d1_mini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/normen/arduino-433/eb9c6707851628388ca5dfbce341d2ee970c94b9/doc/d1_mini.jpg -------------------------------------------------------------------------------- /doc/simple_modules.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/normen/arduino-433/eb9c6707851628388ca5dfbce341d2ee970c94b9/doc/simple_modules.jpg -------------------------------------------------------------------------------- /doc/superheterodyne.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/normen/arduino-433/eb9c6707851628388ca5dfbce341d2ee970c94b9/doc/superheterodyne.jpg -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = d1_mini 13 | 14 | [env:d1_mini] 15 | platform = espressif8266@2.6.3 16 | board = d1_mini 17 | framework = arduino 18 | lib_deps = rc-switch@^2.6.3 19 | ESPiLight@^0.16.2 20 | WebSockets@^2.2.0 21 | SmartRC-CC1101-Driver-Lib@^2.3.5 22 | 23 | [env:micro] 24 | platform = atmelavr 25 | board = micro 26 | framework = arduino 27 | lib_deps = rc-switch@^2.6.3 28 | SmartRC-CC1101-Driver-Lib@^2.3.5 29 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * arduino-433 v1.2.1 3 | * Use the arduino platform to control 433MHz switches 4 | * (c) by Normen Hansen, released under MIT license 5 | ***/ 6 | 7 | // comment this out when using Arduino IDE 8 | #include 9 | 10 | // input pin for RC receiver -> D2 for 8266 by default, 3 for Arduino Micro by default 11 | #define RC_INPUT_PIN D2 12 | // output pin for RC transmitter -> D1 for 8266 by default, 4 for Arduino Micro by default 13 | #define RC_OUTPUT_PIN D1 14 | 15 | // uncomment this to use CC1101 insted of simple 443 sender/receivers 16 | //#define USE_CC1101 17 | 18 | // uncomment this to start websocket server for homebridge -> set WLAN login creds 19 | //#define USE_WEBSOCKET 20 | 21 | // uncomment this to use ESPilight insted of rc-switch to decode switches -> different message format 22 | //#define USE_ESPILIGHT 23 | 24 | // WIFI login if using websocket 25 | #ifdef USE_WEBSOCKET 26 | #define WIFI_SSID "my_wifi_ssid" 27 | #define WIFI_PASS "my_wifi_pass" 28 | #define WIFI_HOSTNAME "arduino-433" 29 | #endif 30 | 31 | // size of local message buffer 32 | #define CHAR_BUFFER_SIZE 255 33 | 34 | 35 | /**** CODE STARTS HERE ****/ 36 | #ifdef USE_ESPILIGHT 37 | #include 38 | extern "C" { 39 | #include "pilight/libs/pilight/core/json.h" 40 | } 41 | #else 42 | #include 43 | #endif 44 | 45 | #ifdef USE_CC1101 46 | #include 47 | #endif 48 | 49 | #ifdef ESP8266 50 | #include 51 | #include 52 | #elif ESP32 53 | #include 54 | #include 55 | #endif 56 | 57 | #ifdef USE_WEBSOCKET 58 | #include 59 | #endif 60 | 61 | #ifdef USE_ESPILIGHT 62 | ESPiLight rf(RC_OUTPUT_PIN); // use -1 to disable transmitter 63 | #else //RCSWITCH 64 | RCSwitch mySwitch = RCSwitch(); 65 | #endif 66 | 67 | char receivedChars[CHAR_BUFFER_SIZE]; // an array to store the received data 68 | boolean newData = false; // was a full new string received? 69 | String dash = "/"; 70 | 71 | #ifdef USE_WEBSOCKET 72 | #ifdef ESP8266 73 | ESP8266WiFiMulti WiFiMulti; 74 | #elif ESP32 75 | WiFiMulti WiFiMulti; 76 | #endif 77 | WebSocketsServer webSocket = WebSocketsServer(80); 78 | uint8_t lastClientNum = 0; 79 | 80 | void copyPayload(char* src, char* dst, size_t len) { 81 | for (int i = 0; i < len; i++) { 82 | *dst++ = *src++; 83 | } 84 | } 85 | 86 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 87 | switch(type) { 88 | case WStype_DISCONNECTED: 89 | break; 90 | case WStype_CONNECTED: 91 | webSocket.sendTXT(num, "OK"); 92 | break; 93 | case WStype_TEXT: 94 | lastClientNum = num; 95 | if(length < CHAR_BUFFER_SIZE){ 96 | copyPayload((char*)payload, receivedChars, length); 97 | receivedChars[length]='\0'; 98 | newData = true; 99 | } 100 | break; 101 | case WStype_BIN: 102 | break; 103 | default: 104 | break; 105 | } 106 | } 107 | #endif 108 | 109 | #ifdef USE_ESPILIGHT 110 | void espiCallback(const String &protocol, const String &message, int status, 111 | size_t repeats, const String &deviceID) { 112 | if (status == VALID) { 113 | String out = "{\"type\":\""+protocol+"\",\"message\":"+message+"}"; 114 | Serial.println(out); 115 | #ifdef USE_WEBSOCKET 116 | webSocket.broadcastTXT(out); 117 | #endif 118 | } 119 | } 120 | #endif 121 | 122 | void setup() { 123 | Serial.begin(9600); 124 | Serial.setTimeout(100); 125 | #ifdef USE_CC1101 126 | //CC1101 Settings: (Settings with "//" are optional!) 127 | ELECHOUSE_cc1101.Init(); // must be set to initialize the cc1101! set TxPower PA10, PA7, PA5, PA0, PA_10, PA_15, PA_20, PA_30. 128 | //ELECHOUSE_cc1101.setRxBW(16); // set Receive filter bandwidth (default = 812khz) 1 = 58khz, 2 = 67khz, 3 = 81khz, 4 = 101khz, 5 = 116khz, 6 = 135khz, 7 = 162khz, 8 = 203khz, 9 = 232khz, 10 = 270khz, 11 = 325khz, 12 = 406khz, 13 = 464khz, 14 = 541khz, 15 = 650khz, 16 = 812khz. 129 | ELECHOUSE_cc1101.setMHZ(433.92); // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet. 130 | ELECHOUSE_cc1101.SetRx(); // set Recive on 131 | #endif 132 | 133 | #ifdef USE_ESPILIGHT 134 | rf.setCallback(espiCallback); 135 | rf.initReceiver(RC_INPUT_PIN); 136 | #else 137 | mySwitch.enableReceive(digitalPinToInterrupt(RC_INPUT_PIN)); 138 | mySwitch.enableTransmit(RC_OUTPUT_PIN); 139 | mySwitch.setRepeatTransmit(8); 140 | #endif 141 | 142 | #ifdef ESP8266 143 | WiFi.mode(WIFI_STA); // prevent ESP from creating access point by default 144 | #elif ESP32 145 | WiFi.mode(WIFI_MODE_STA); 146 | #endif 147 | #ifdef USE_WEBSOCKET 148 | WiFi.hostname(WIFI_HOSTNAME); 149 | WiFiMulti.addAP(WIFI_SSID, WIFI_PASS); 150 | while(WiFiMulti.run() != WL_CONNECTED) { 151 | delay(100); 152 | } 153 | webSocket.begin(); 154 | webSocket.onEvent(webSocketEvent); 155 | #endif 156 | } 157 | 158 | // gets the values from a string formatted like 123456/123 159 | String getValue(String data, char separator, int index) { 160 | int found = 0; 161 | int strIndex[] = {0, -1}; 162 | int maxIndex = data.length()-1; 163 | for(int i=0; i<=maxIndex && found<=index; i++){ 164 | if(data.charAt(i)==separator || i==maxIndex){ 165 | found++; 166 | strIndex[0] = strIndex[1]+1; 167 | strIndex[1] = (i == maxIndex) ? i+1 : i; 168 | } 169 | } 170 | return found>index ? data.substring(strIndex[0], strIndex[1]) : ""; 171 | } 172 | 173 | void receiveSerialData() { 174 | static byte ndx = 0; 175 | char endMarker = '\n'; 176 | char rc; 177 | if (Serial.available() > 0) { 178 | rc = Serial.read(); 179 | if (rc != endMarker) { 180 | receivedChars[ndx] = rc; 181 | ndx++; 182 | if (ndx >= CHAR_BUFFER_SIZE) { 183 | ndx = CHAR_BUFFER_SIZE - 1; 184 | } 185 | } 186 | else { 187 | receivedChars[ndx] = '\0'; // terminate the string 188 | ndx = 0; 189 | newData = true; 190 | } 191 | } 192 | } 193 | 194 | void sendRcData() { 195 | if (newData == true) { 196 | #ifdef USE_CC1101 197 | ELECHOUSE_cc1101.SetTx(); 198 | #endif 199 | #ifdef USE_ESPILIGHT 200 | if (json_validate(receivedChars)) { 201 | JsonNode *fullJson = json_decode(receivedChars); 202 | JsonNode *typeJson = json_find_member(fullJson, "type"); 203 | JsonNode *messageJson = json_find_member(fullJson, "message"); 204 | if(typeJson != NULL && messageJson != NULL){ 205 | char *message = json_encode(messageJson); 206 | rf.send(typeJson->string_, message); 207 | json_free(message); 208 | }else{ 209 | Serial.println("pilight(0): missing type or message in JSON"); 210 | } 211 | json_delete(messageJson); 212 | json_delete(typeJson); 213 | json_delete(fullJson); 214 | }else{ 215 | Serial.println("pilight(0): invalid JSON"); 216 | } 217 | #else 218 | long value = getValue(receivedChars, '/', 0).toInt(); 219 | long pulse = getValue(receivedChars, '/', 1).toInt(); 220 | long protocol = getValue(receivedChars, '/', 2).toInt(); 221 | if(protocol==0) protocol = 1; 222 | mySwitch.setProtocol(protocol); 223 | mySwitch.setPulseLength(pulse); 224 | mySwitch.send(value, 24); 225 | #endif 226 | #ifdef USE_CC1101 227 | ELECHOUSE_cc1101.SetRx(); 228 | #endif 229 | #ifdef USE_WEBSOCKET 230 | webSocket.sendTXT(lastClientNum, "OK"); 231 | #endif 232 | Serial.println("OK"); 233 | newData = false; 234 | } 235 | } 236 | 237 | #ifdef USE_ESPILIGHT 238 | #else 239 | void receiveRcData(){ 240 | if (mySwitch.available()) { 241 | long value = mySwitch.getReceivedValue(); 242 | long pulse = mySwitch.getReceivedDelay(); 243 | long protocol = mySwitch.getReceivedProtocol(); 244 | if (value != 0) { 245 | String out = String(value) + dash + String(pulse) + dash + String(protocol); 246 | #ifdef USE_WEBSOCKET 247 | webSocket.broadcastTXT(out); 248 | #endif 249 | Serial.println( out ); 250 | } 251 | mySwitch.resetAvailable(); 252 | } 253 | } 254 | #endif 255 | 256 | void loop() { 257 | #ifdef USE_WEBSOCKET 258 | webSocket.loop(); 259 | #endif 260 | receiveSerialData(); 261 | sendRcData(); 262 | #ifdef USE_ESPILIGHT 263 | rf.loop(); 264 | #else 265 | receiveRcData(); 266 | #endif 267 | } 268 | --------------------------------------------------------------------------------