Simple WiFi Remote Control Socket With ESP8266
by bcsedlon in Circuits > Arduino
6260 Views, 50 Favorites, 0 Comments
Simple WiFi Remote Control Socket With ESP8266
This project demonstrate how to make very simple WiFi remote control socket. It is based on ESP8266 dev kit and H34A 433Mhz transmitter. In additional you need radio controlled socket available in market.
Device works in 3 modes:
1) Connect to your WiFi infrastructure: if first time or no known network found starts as WiFi Access Point to chose WiFi network, after your chose it will connect to your network and work as WiFi device with IP addres from your DHCP server (usualy router). In this case no pin is grounded.
2) If pin D3 is grounded starts as AP to chose network again, then works like mode 1. It is for cases when you want to change known network.
3) If pin D2 is grounded works as standalone WiFi Access Point.
This project demonstrate autonomous clock switch with two settable times per day to switch socket on to desired duration. Time in device is set from public NTP server.
Another possibility is control device manually via web browser from phone on computer or automatically from other device by HTTP request. Every request has to be authenticate.
Part List
ESP8266 Development Board
H34A-433 433MhzI RF Wireless Transmitter Module Remote Control ASK 2.6-12V
Maclean MCE07GB Remote Control Sockets
Circuit Diagram
ESP8266 ..... H34A
G .................. GND
3V ................ VCC
D5 ............... DATA
D2 ............... if grounded works as WiFi AP
D3 ............... if grounded reconfigure WiFi network
Code
Download complete code in zip file.
#include //https://github.com/esp8266/Arduino<br></p><p>//needed for library #include #include #include "libraries/WiFiManager.h" //https://github.com/tzapu/WiFiManager</p><p>#include //#include ESP8266WebServer server(80);</p><p>char* htmlHeader = " button {height:100px;width:100px;font-family:monospace;border-radius:5px;} </p>esp8266<p>"; char* htmlFooter = "</p><p>"; //const char HTTP_STYLE[] PROGMEM = " .c{text-align: center;} div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;font-family:verdana;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} .q{float: right;width: 64px;text-align: right;} .l{background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==\") no-repeat left center;background-size: 1em;}</p><p>";</p><p>const char* www_username = "admin"; const char* www_password = "esp8266";</p><p>#include </p><p>#include </p><p>#include "libraries/RF433.h" //#define RFRX_PIN A4 #define RFTX_PIN 14 //D5 // MCE07 byte rf1off[] = {11,30,3,4,3,3,3,11,3,11,3,11,3,3,3,4,3,11,3,3,3,4,3,3,3,4,3,3,3,4,3,10,4,3,3,11,3,11,3,3,4,3,3,4,3,10,3,11,3,4,3,11,3,10,4,10,3,11,3,11,3,11,3,3,3,11,3,4,3,11,3,10,3,11,3,11,3,3,4,3,3,3,4,188,3,3,3,3,30,29,4,3,3,3,4,10,3,11,3,11,3,3,4,3,3,11,3,3,4,3,3,3,4,3,3,3,4,3,3,11,3,4,3,10,4}; byte rf1on[] = {5,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,10,4,3,3,3,4,3,3,3,4,3,3,4,3,10,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,4,3,10,3,11,3,11,3,11,3,11,3,10,3,4,3,11,3,11,3,3,3,4,3,3,3,4,3,10,4,10,3,11,3,90,3,3,4,3,29,30,3,3,3,4,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3}; byte rf2off[] = {16,29,3,4,3,3,3,11,3,11,3,11,3,3,3,4,3,11,3,3,3,4,3,3,3,4,3,3,3,4,3,11,3,3,3,11,3,11,3,4,2,4,3,3,3,11,3,11,3,4,3,11,3,10,3,11,3,11,3,11,3,11,3,3,3,11,3,11,3,3,3,11,3,11,3,3,3,11,3,4,3,3,3,188,4,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,10,4,3,3,3,4,3,3,3,3,4,3,4,3,10,3,4,3,11,3}; byte rf2on[] = {4,11,3,3,3,11,3,4,3,3,3,11,3,3,3,11,3,11,3,188,3,3,4,2,30,30,3,3,3,4,3,10,3,11,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,10,3,4,3,3,3,4,3,11,3,10,3,4,3,11,3,11,3,11,3,10,3,11,3,11,3,4,3,11,3,3,3,11,3,3,3,4,3,11,3,3,3,11,3,11,3,90,3,3,3,3,30,30,3,3,3,4,3,10,3,11,3,11,3}; byte rf3off[] = {5,3,3,3,29,30,3,3,4,3,3,11,3,11,3,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,10,3,11,3,11,3,3,4,11,3,3,3,4,3,10,3,11,3,11,3,11,3,3,3,4,3,188,3,3,4,2,30,29,4,3,3,3,4,10,3,11,3,11,3,3,3,4,3,11,3,3,3,4,3,3,3,4,3,3,3,4,3,11,3}; byte rf3on[] = {5,2,4,3,29,30,3,3,3,4,3,11,3,10,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,3,10,3,11,3,4,3,11,3,11,3,10,3,4,3,3,3,4,3,3,3,11,3,11,3,90,3,3,4,3,29,30,3,3,3,4,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3}; byte rf4off[] = {4,11,3,4,3,10,3,11,3,11,3,11,3,11,3,10,3,4,3,11,3,11,3,10,3,4,3,11,3,3,3,4,3,11,3,3,3,90,3,3,4,3,29,30,3,3,3,4,3,11,3,10,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,10,3,4,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,2,11,3,11,3,3,4,11,3,10,3,11,3,4,3,10,3,4,3,3,3,11,3,4,3}; byte rf4on[] = {4,4,3,10,4,89,4,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,2,11,3,11,3,3,4,11,3,3,3,4,3,10,3,4,3,11,3,10,3,4,3,11,3,188,3,3,3,3,30,29,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,11,3,3,3,4,3,3,3,4,3};</p><p>#include #include "libraries/NTPClient.h" WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP);</p><p>#include "libraries/interval.h" Interval minInterval, secInterval;</p><p>#include "libraries/Timezone.h" //Central European Time (Frankfurt, Paris) TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time Timezone CE(CEST, CET);</p><p>#define CONFIG_WIFIAP_PIN 4 //D2 #define CONFIG_WIFI_PIN 5 //D3</p><p>#define DEVICES_NUM 4</p><p>#define OUTPUT_BIT 0 #define MANUAL_BIT 1 #define CMD_BIT 2 #define RAIN_BIT 3</p><p>#define EEPROM_OFFSET 8</p><p>struct Device { byte onHour1; byte onMin1; unsigned int durationSec1; byte onHour2; byte onMin2; unsigned int durationSec2; byte flags; char name[8]; };</p><p>Device devices[DEVICES_NUM];</p><p>String getDeviceForm(int i, struct Device devices[]) { Device d = devices[i]; String s = " </p> "; s += i; s += ": "; s += d.name; s += "<p>OFF ON AUTO"; s += " </p> <h3>Settings:</h3><p>"; s += " </p>NAME<br> Switch ON at [hour] 1<br> Switch ON at [min] 1<br> Switch ON duration [min] 1<br> Switch ON at [hour] 2<br> Switch ON at [min] 2<br> Switch ON duration [min] 2<br> F<br> SET";<p> s += "</p><p>"; return s; }</p><p>void handleRoot(){ if(!server.authenticate(www_username, www_password)) return server.requestAuthentication();</p><p> Serial.println("Enter handleRoot"); String message; server.send(200, "text/plain", message); }</p><p>void setup() { // put your setup code here, to run once:</p><p> Serial.begin(115200); Serial.print("\n\n");</p><p> EEPROM.begin(512); if(!EEPROM.read(0)) { for(int d=0; d< DEVICES_NUM; d++) { EEPROM.get(EEPROM_OFFSET + sizeof(Device) * d, devices[d]); } }</p><p> pinMode(CONFIG_WIFIAP_PIN, INPUT_PULLUP); pinMode(CONFIG_WIFI_PIN, INPUT_PULLUP); pinMode(RFTX_PIN, OUTPUT);</p><p> //WiFiManager //Local intialization. Once its business is done, there is no need to keep it around WiFiManager wifiManager; //reset saved settings //wifiManager.resetSettings();</p><p> //set custom ip for portal //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));</p><p> //fetches ssid and pass from eeprom and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" //and goes into a blocking loop awaiting configuration if(digitalRead(CONFIG_WIFIAP_PIN) == LOW) { WiFi.softAP("esp8266AP", "esp8266"); IPAddress myIP = WiFi.softAPIP(); Serial.println("Starting AP ..."); Serial.print("AP IP address: "); Serial.println(myIP);</p><p> Serial.print("Open http://"); Serial.print(myIP); Serial.println("/ in your browser to see it working");</p><p> //AP } else { if ( digitalRead(CONFIG_WIFI_PIN) == LOW ) { Serial.println("Starting AP for reconfiguration ..."); wifiManager.startConfigPortal("esp8266"); //AP } else { Serial.println("Starting AP or connecting to Wi-Fi ..."); wifiManager.autoConnect("esp8266"); } //or use this for auto generated name ESP + ChipID</p><p> //if you get here you have connected to the WiFi Serial.println("Connected"); Serial.print("Open http://"); Serial.print(WiFi.localIP()); Serial.println("/ in your browser to see it working");</p><p> }</p><p> server.on("/", [](){ Serial.println("/"); if(!server.authenticate(www_username, www_password)) return server.requestAuthentication();</p><p> String message = htmlHeader;</p><p> //message += "Time: " + timeClient.getFormattedTime(); time_t t = CE.toLocal(timeClient.getEpochTime());</p><p> byte h = (t / 3600) % 24; byte m = (t / 60) % 60; byte s = t % 60; message += "Time: "; if(h<10) message += '0'; message += h; message += ":"; if(m<10) message += '0'; message += m; message += ":"; if(s<10) message += '0'; message += s;</p><p> for(int i = 0; i < DEVICES_NUM; i++) { message += " </p><p> server.on("/save", [](){ Serial.println("/save"); if(!server.authenticate(www_username, www_password)) return server.requestAuthentication();</p><p> for(int d=0; d< DEVICES_NUM; d++) { EEPROM.put(EEPROM_OFFSET + sizeof(Device) * d, devices[d]); } EEPROM.write(0, 0); EEPROM.commit();</p><p> char value; for(int i=0; i < 512; i++) { //EEPROM.write(addr, val); if(i % 32 == 0) Serial.println(); value = EEPROM.read(i); Serial.print(value, HEX); Serial.print(' '); }</p><p> String message = htmlHeader; message += "OK"; message += htmlFooter; server.send(200, "text/html", message);</p><p> });</p><p> server.on("/dev", [](){ Serial.println("/dev"); if(!server.authenticate(www_username, www_password)) return server.requestAuthentication();</p><p> String cmd=server.arg("cmd"); Serial.println(cmd);</p><p> byte id=server.arg("id").toInt(); if(cmd.equals("set")) { byte onHour1=server.arg("h1").toInt(); byte onMin1=server.arg("m1").toInt(); unsigned int durationSec1=server.arg("d1").toInt(); byte onHour2=server.arg("h2").toInt(); byte onMin2=server.arg("m2").toInt(); unsigned int durationSec2=server.arg("d2").toInt(); String name=server.arg("n");</p><p> if(id >=0 && id < DEVICES_NUM) { devices[id].onHour1 = onHour1; devices[id].onMin1 = onMin1; devices[id].durationSec1 = durationSec1; devices[id].onHour2 = onHour2; devices[id].onMin2 = onMin2; devices[id].durationSec2 = durationSec2; name.toCharArray(devices[id].name, 8); } } if(cmd.equals("auto")) { bitClear(devices[id].flags, MANUAL_BIT); } if(cmd.equals("off")) { bitSet(devices[id].flags, MANUAL_BIT); bitClear(devices[id].flags, CMD_BIT); bitClear(devices[id].flags, OUTPUT_BIT); } if(cmd.equals("on")) { bitSet(devices[id].flags, MANUAL_BIT); bitSet(devices[id].flags, CMD_BIT); bitSet(devices[id].flags, OUTPUT_BIT); }</p><p> String message = htmlHeader; message += getDeviceForm(id, devices); message += htmlFooter;</p><p> server.send(200, "text/html", message); });</p><p> server.begin(); timeClient.update(); }</p><p>void loop() { // put your main code here, to run repeatedly:</p><p> // ArduinoOTA.handle(); server.handleClient();</p><p> if(minInterval.expired()) { minInterval.set(60000); timeClient.update(); } if (secInterval.expired()) { secInterval.set(1000);</p><p> //Serial.print('\n'); for(int i = 0; i < DEVICES_NUM; i++) { unsigned int onSec1 = devices[i].onHour1 * 3600 + devices[i].onMin1 * 60; unsigned int offSec1 = onSec1 + devices[i].durationSec1; unsigned int onSec2 = devices[i].onHour2 * 3600 + devices[i].onMin2 * 60; unsigned int offSec2 = onSec2 + devices[i].durationSec2;</p><p> //unsigned int onSec = timeClient.getHours() * 3600 + timeClient.getMinutes() * 60; time_t t = CE.toLocal(timeClient.getEpochTime()); byte h = (t / 3600) % 24; byte m = (t / 60) % 60; byte s = t % 60; unsigned int onSec = h * 3600 + m * 60;</p><p> unsigned int offSec = onSec; bool out1 = false; bool out2 = false;</p><p> if(offSec1 >= 24 * 60 * 60) offSec = onSec + 24 * 60 * 60; if(onSec >= onSec1 && offSec < offSec1) { out1 = true; } if(offSec2 >= 24 * 60 * 60) offSec = onSec + 24 * 60 * 60; if(onSec >= onSec2 && offSec < offSec2) { out2 = true; }</p><p> if(!bitRead(devices[i].flags, MANUAL_BIT)) { if(out1 || out2) bitSet(devices[i].flags, OUTPUT_BIT); else bitClear(devices[i].flags, OUTPUT_BIT); } /* Serial.print(devices[i].flags); Serial.print('\t'); Serial.print(devices[i].name); Serial.print('\n');*/ }</p><p> if(bitRead(devices[0].flags, OUTPUT_BIT)) sendSignal(RFTX_PIN, rf1on); else sendSignal(RFTX_PIN, rf1off); if(bitRead(devices[1].flags, OUTPUT_BIT)) sendSignal(RFTX_PIN, rf2on); else sendSignal(RFTX_PIN, rf2off); if(bitRead(devices[2].flags, OUTPUT_BIT)) sendSignal(RFTX_PIN, rf3on); else sendSignal(RFTX_PIN, rf3off); if(bitRead(devices[3].flags, OUTPUT_BIT)) sendSignal(RFTX_PIN, rf4on); else sendSignal(RFTX_PIN, rf4off); } }</p> <br><br>
Downloads
Screenshots
Web pages screenshots from mobile phone browser connected to ESP8266 web server.
HTTP Requests
Device can be controlled via HTTP request with following format:
http://?id=&cmd=
where is device IP address, id is socket id 0 to 3 and CMD is on, off or auto.
For example http://192.168.4.1?id=0&cmd=on switch socket 0 on. First time authorization request will be shown to prevent unauthorized access.
For control from another wget can be used:
wget http://192.168.4.1?id=0&cmd=on --user=admin --password=esp8266
How to Learn Remote Control Code
If you have another remote control socket with unknown code you can learn it.
Connect RF receiver to Arduino, and use following sketch to listen. Then copy captured code from Serial Monitor to main code into variables: byte rf1off[], byte rf1on[] and so on.
RX pin of reciever is connected to A0 arduino pin.
<p>#include "RF433.h"</p><p>#include "SerialCommand.h" /* Adapted from Steven Cogswell library, * see <a href="https://github.com/scogswell/ArduinoSerialCommand" rel="nofollow"> https://github.com/scogswell/ArduinoSerialCommand...</a> * Branched from main, 2013 */</p><p>#define LED 13 // Debug, or activity purpose #define RX A0 #define TX 4</p><p>// MCE07 byte storedData1off[] = {11,30,3,4,3,3,3,11,3,11,3,11,3,3,3,4,3,11,3,3,3,4,3,3,3,4,3,3,3,4,3,10,4,3,3,11,3,11,3,3,4,3,3,4,3,10,3,11,3,4,3,11,3,10,4,10,3,11,3,11,3,11,3,3,3,11,3,4,3,11,3,10,3,11,3,11,3,3,4,3,3,3,4,188,3,3,3,3,30,29,4,3,3,3,4,10,3,11,3,11,3,3,4,3,3,11,3,3,4,3,3,3,4,3,3,3,4,3,3,11,3,4,3,10,4}; byte storedData1on[] = {5,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,10,4,3,3,3,4,3,3,3,4,3,3,4,3,10,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,4,3,10,3,11,3,11,3,11,3,11,3,10,3,4,3,11,3,11,3,3,3,4,3,3,3,4,3,10,4,10,3,11,3,90,3,3,4,3,29,30,3,3,3,4,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3}; byte storedData2off[] = {16,29,3,4,3,3,3,11,3,11,3,11,3,3,3,4,3,11,3,3,3,4,3,3,3,4,3,3,3,4,3,11,3,3,3,11,3,11,3,4,2,4,3,3,3,11,3,11,3,4,3,11,3,10,3,11,3,11,3,11,3,11,3,3,3,11,3,11,3,3,3,11,3,11,3,3,3,11,3,4,3,3,3,188,4,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,10,4,3,3,3,4,3,3,3,3,4,3,4,3,10,3,4,3,11,3}; byte storedData2on[] = {4,30,3,3,3,4,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,10,4,3,3,3,3,4,3,11,3,10,4,3,3,11,3,11,3,10,4,10,3,11,3,11,3,3,3,11,3,4,3,10,4,3,3,4,3,10,3,4,3,10,4,10,3,90,4,2,4,3,29,30,3,3,3,4,3,11,3,10,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3}; byte storedData3off[] = {1,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,3,10,3,11,3,4,3,11,3,3,3,4,3,10,3,11,3,11,3,11,3,3,3,4,3,90,3,3,3,3,30,30,3,3,3,4,3,10,3,11,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,10,3,4,3,3,3,4,3,11,3,11,2,4,3,11,3,11,3}; byte storedData3on[] = {5,2,4,3,29,30,3,3,3,4,3,11,3,10,3,11,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,3,10,3,11,3,4,3,11,3,11,3,10,3,4,3,3,3,4,3,3,3,11,3,11,3,90,3,3,4,3,29,30,3,3,3,4,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3}; byte storedData4off[] = {3,3,3,11,3,10,4,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,10,4,3,3,3,3,4,3,11,3,10,4,3,3,11,3,11,3,11,3,10,3,11,3,11,3,3,3,11,3,4,3,3,3,11,3,11,3,11,3,10,4,3,3,3,4,90,3,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3}; byte storedData4on[] = {4,4,3,10,4,89,4,3,3,3,29,30,3,4,3,3,3,11,3,11,3,10,3,4,3,3,3,11,3,4,3,3,3,4,3,3,3,4,3,3,3,11,3,4,3,11,3,11,3,3,3,4,3,3,3,11,3,11,3,3,3,11,3,11,3,11,3,11,2,11,3,11,3,3,4,11,3,3,3,4,3,10,3,4,3,11,3,10,3,4,3,11,3,188,3,3,3,3,30,29,3,4,3,3,3,11,3,11,3,10,4,3,3,3,4,11,3,3,3,4,3,3,3,4,3};</p><p>// Serial command handler SerialCommand SCmd;</p><p>void setup() { Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } pinMode(LED, OUTPUT);</p><p> //SCmd.addCommand("h", scmdHelp); SCmd.addCommand("r", scmdCodeReceive); SCmd.addCommand("s", scmdCodeSend); SCmd.addCommand("1+", scmdCodeSend1On); SCmd.addCommand("1-", scmdCodeSend1Off); SCmd.addCommand("2+", scmdCodeSend2On); SCmd.addCommand("2-", scmdCodeSend2Off); SCmd.addCommand("3+", scmdCodeSend3On); SCmd.addCommand("3-", scmdCodeSend3Off); SCmd.addCommand("4+", scmdCodeSend4On); SCmd.addCommand("4-", scmdCodeSend4Off); SCmd.setDefaultHandler(scmdUnrecognized);</p><p> scmdBanner();</p><p> scmdHelp(); Serial.println(); }</p><p>void scmdCodeReceive() { initData(); listenForSignal(RX); printData(); Serial.println("Done."); }</p><p>void scmdCodeSend1On() { sendSignal(TX, storedData1on); Serial.println("Send 1 ON"); } void scmdCodeSend1Off() { sendSignal(TX, storedData1off); Serial.println("Send 1 OFF"); } void scmdCodeSend2On() { sendSignal(TX, storedData2on); Serial.println("Send 2 ON"); } void scmdCodeSend2Off() { sendSignal(TX, storedData2off); Serial.println("Send 2 OFF"); } void scmdCodeSend3On() { sendSignal(TX, storedData3on); Serial.println("Send 3 ON"); } void scmdCodeSend3Off() { sendSignal(TX, storedData3off); Serial.println("Send 3 OFF"); } void scmdCodeSend4On() { sendSignal(TX, storedData4on); Serial.println("Send 4 ON"); } void scmdCodeSend4Off() { sendSignal(TX, storedData4off); Serial.println("Send 4 OFF"); }</p><p>void scmdCodeSend() { sendSignal(TX); Serial.println("Send last recieved code."); }</p><p>void loop() { SCmd.readSerial(); }</p><p>void scmdUnrecognized() { Serial.println(F("Unknown command or too long command line. Try h or -h ?")); }</p><p>void scmdHelp() { char *arg; arg = SCmd.next(); if (arg == NULL) { scmdBanner();</p><p> Serial.println(); Serial.print(F("Available commands are :\r\n"\ " h\t This screen, some help and status.\n\r"\ " r\t Sniff code (press original remote control button before).\n\r"\ " s\t Sends last sniffed code.\r\n"\ " 1+\t 1 ON\r\n"\ " 1-\t 1 OFF\r\n"\ " 2+\t 2 ON\r\n"\ " 2-\t 2 OFF\r\n"\ " 3+\t 3 ON\r\n"\ " 3-\t 3 OFF\r\n"\ " 4+\t 4 ON\r\n"\ " 4-\t 4 OFF\r\n"\ "Use -h for commands help and their options, when they have.\r\n\r\n")); } else { if(strcmp (arg, "-h") == 0) { Serial.println(F("Help has no help, sorry.")); } else { scmdInvalidOption(arg); } } }</p><p>void scmdBanner() { String banner = F("\r\nMaclean Energy MCE07 remote control codes sniffer\r\n"\ "Version "); Serial.println(banner); }</p><p>void scmdInvalidOption (char *option) { if (strlen(option) > 0) { String dummy = F("Invalid option or argument \""); dummy += option; dummy += F("\". Try -h ?"); Serial.println(dummy); } else { Serial.println(F("Missing or invalid command argument. Try -h ?")); } }</p>