├── .gitattributes ├── README.md ├── T_WatchButton ├── config.h ├── T_WatchButton.ino └── ESP_Now_header.h ├── CloseBySonoff └── CloseBySonoff.ino ├── AES128 └── AES128.h ├── RealMasterESP8266 └── RealMasterESP8266.ino ├── RealSlave └── RealSlave.ino ├── Hello_World └── Hello_World.ino └── RealMaster └── RealMaster.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Encrypted-Remote-Control 2 | 3 | Files for YouTube video: https://youtu.be/cXh0T1CWtyg 4 | -------------------------------------------------------------------------------- /T_WatchButton/config.h: -------------------------------------------------------------------------------- 1 | // => Hardware select 2 | // #define LILYGO_WATCH_2019_WITH_TOUCH // To use T-Watch2019 with touchscreen, please uncomment this line 3 | // #define LILYGO_WATCH_2019_NO_TOUCH // To use T-Watch2019 Not touchscreen , please uncomment this line 4 | #define LILYGO_WATCH_2020_V1 //To use T-Watch2020, please uncomment this line 5 | // #define LILYGO_WATCH_2020_V2 //To use T-Watch2020 V2, please uncomment this line 6 | // #define LILYGO_WATCH_2020_V3 //To use T-Watch2020 V3, please uncomment this line 7 | 8 | 9 | // NOT SUPPORT ... 10 | //// #define LILYGO_WATCH_BLOCK 11 | // NOT SUPPORT ... 12 | 13 | // => Function select 14 | #define LILYGO_WATCH_LVGL //To use LVGL, you need to enable the macro LVGL 15 | 16 | #include 17 | -------------------------------------------------------------------------------- /CloseBySonoff/CloseBySonoff.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Close By example for the Approximate Library 3 | - 4 | Find the MAC address of close by devices - and trigger ARRIVE & DEPART events 5 | - 6 | David Chatting - github.com/davidchatting/Approximate 7 | MIT License - Copyright (c) October 2020 8 | 9 | Example documented here > https://github.com/davidchatting/Approximate/tree/master#when-were-close-using-a-proximate-device-handler 10 | */ 11 | 12 | #include 13 | #include 14 | Approximate approx; 15 | 16 | 17 | String macaddress = "4A:CD:D5:A3:D4:AE"; 18 | 19 | //Define for your board, not all have built-in LED and/or button: 20 | #if defined(ESP8266) 21 | const int LED_PIN = 12; 22 | #elif defined(ESP32) 23 | const int LED_PIN = 2; 24 | #endif 25 | 26 | void setup() { 27 | Serial.begin(115200); 28 | pinMode(LED_PIN, OUTPUT); 29 | Serial.println("Begin"); 30 | 31 | if (approx.init(mySSID, myPASSWORD)) { 32 | approx.setProximateDeviceHandler(onProximateDevice, APPROXIMATE_PERSONAL_RSSI, 5000); 33 | approx.begin(); 34 | } 35 | } 36 | 37 | void loop() { 38 | approx.loop(); 39 | } 40 | 41 | void onProximateDevice(Device *device, Approximate::DeviceEvent event) { 42 | switch (event) { 43 | case Approximate::ARRIVE: 44 | Serial.println("ARRIVE\t" + device->getMacAddressAsString()); 45 | Serial.println(device->getRSSI()); 46 | if (device->getMacAddressAsString() == macaddress) { 47 | digitalWrite(LED_PIN, HIGH); 48 | Serial.println("**ARRIVE\t" + device->getMacAddressAsString()); 49 | } 50 | break; 51 | case Approximate::DEPART: 52 | Serial.println("DEPART\t" + device->getMacAddressAsString()); 53 | Serial.println(device->getRSSI()); 54 | if (device->getMacAddressAsString() == macaddress) { 55 | digitalWrite(LED_PIN, LOW); 56 | Serial.println("**DEPART\t" + device->getMacAddressAsString()); 57 | } 58 | break; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /T_WatchButton/T_WatchButton.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "config.h" 3 | #include "ESP_Now_header.h" 4 | 5 | 6 | TTGOClass *ttgo; 7 | 8 | static void event_handler(lv_obj_t *obj, lv_event_t event) 9 | { 10 | if (event == LV_EVENT_CLICKED) { 11 | Serial.printf("Clicked\n"); 12 | sendData(); 13 | } else if (event == LV_EVENT_VALUE_CHANGED) { 14 | Serial.printf("Toggled\n"); 15 | } 16 | } 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); 21 | ttgo = TTGOClass::getWatch(); 22 | ttgo->begin(); 23 | ttgo->openBL(); 24 | ttgo->lvgl_begin(); 25 | 26 | lv_obj_t *label; 27 | 28 | lv_obj_t *btn1 = lv_btn_create(lv_scr_act(), NULL); 29 | lv_obj_set_event_cb(btn1, event_handler); 30 | lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); 31 | 32 | label = lv_label_create(btn1, NULL); 33 | lv_label_set_text(label, "Open"); 34 | 35 | /* 36 | lv_obj_t *btn2 = lv_btn_create(lv_scr_act(), NULL); 37 | lv_obj_set_event_cb(btn2, event_handler); 38 | lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40); 39 | lv_btn_set_checkable(btn2, true); 40 | lv_btn_toggle(btn2); 41 | lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT); 42 | 43 | label = lv_label_create(btn2, NULL); 44 | lv_label_set_text(label, "Pair"); 45 | */ 46 | 47 | //***** ESP_Now *** 48 | //Set device in STA mode to begin with 49 | WiFi.mode(WIFI_STA); 50 | Serial.println("ESPNow / Basic / Master Example"); 51 | // This is the mac address of the Master in Station Mode 52 | Serial.print("STA MAC: "); Serial.println(WiFi.macAddress()); 53 | // Init ESPNow with a fallback logic 54 | InitESPNow(); 55 | // Once ESPNow is successfully Init, we will register for Send CB to 56 | // get the status of Trasnmitted packet 57 | esp_now_register_send_cb(OnDataSent); 58 | 59 | if (!EEPROM.begin(EEPROM_SIZE)) { 60 | Serial.println("failed to initialise EEPROM"); delay(1000000); 61 | } 62 | EEPROM.get(0, savedCounter); 63 | Serial.println(savedCounter.magic); 64 | if (savedCounter.magic != MAGIC) { 65 | savedCounter.magic = MAGIC; 66 | EEPROM.put(0, savedCounter); 67 | Serial.println ("...................Please pair.................."); 68 | EEPROM.commit(); 69 | } 70 | cryptoInit(); 71 | 72 | } 73 | 74 | void loop() 75 | { 76 | lv_task_handler(); 77 | delay(5); 78 | } 79 | -------------------------------------------------------------------------------- /AES128/AES128.h: -------------------------------------------------------------------------------- 1 | /* Medium example for ESP8266 (not for Arduino, uses additional Base64 layer) */ 2 | 3 | #include 4 | 5 | AESLib aesLib; 6 | 7 | char cleartext[256]; 8 | char ciphertext[512]; 9 | 10 | // AES Encryption Key 11 | byte aes_key[] = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 }; 12 | 13 | // General initialization vector (you must use your own IV's in production for full security!!!) 14 | byte aes_iv[N_BLOCK] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 15 | 16 | 17 | 18 | String encrypt(char * msg, uint16_t msgLen, byte iv[]) { 19 | int cipherlength = aesLib.get_cipher64_length(msgLen); 20 | char encrypted[cipherlength]; // AHA! needs to be large, 2x is not enough 21 | aesLib.encrypt64(msg, msgLen, encrypted, aes_key, sizeof(aes_key), iv); 22 | Serial.print("encrypted = "); Serial.println(encrypted); 23 | return String(encrypted); 24 | } 25 | 26 | String decrypt(char * msg, uint16_t msgLen, byte iv[]) { 27 | char decrypted[msgLen]; 28 | aesLib.decrypt64(msg, msgLen, decrypted, aes_key, sizeof(aes_key), iv); 29 | Serial.print("decrypted = "); Serial.println(decrypted); 30 | return String(decrypted); 31 | } 32 | // Generate IV (once) 33 | void aes_init() { 34 | Serial.println("gen_iv()"); 35 | aesLib.gen_iv(aes_iv); 36 | Serial.println("encrypt()"); 37 | Serial.println(encrypt(strdup(plaintext.c_str()), plaintext.length(), aes_iv)); 38 | } 39 | 40 | void cryptoInit() { 41 | aes_init(); 42 | aesLib.set_paddingmode(paddingMode::CMS); 43 | 44 | // 45 | // verify with https://cryptii.com 46 | // previously: verify with https://gchq.github.io/CyberChef/#recipe=To_Base64('A-Za-z0-9%2B/%3D') 47 | // 48 | 49 | char b64in[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 50 | 51 | char b64out[base64_enc_len(sizeof(aes_iv))]; 52 | base64_encode(b64out, b64in, 16); 53 | 54 | char b64enc[base64_enc_len(10)]; 55 | base64_encode(b64enc, (char*) "0123456789", 10); 56 | 57 | char b64dec[ base64_dec_len(b64enc, sizeof(b64enc))]; 58 | base64_decode(b64dec, b64enc, sizeof(b64enc)); 59 | } 60 | 61 | /* non-blocking wait function */ 62 | void wait(unsigned long milliseconds) { 63 | unsigned long timeout = millis() + milliseconds; 64 | while (millis() < timeout) { 65 | yield(); 66 | } 67 | } 68 | 69 | unsigned long loopcount = 0; 70 | byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... 71 | byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 72 | -------------------------------------------------------------------------------- /RealMasterESP8266/RealMasterESP8266.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Rui Santos 3 | Complete project details at https://RandomNerdTutorials.com/esp-now-esp8266-nodemcu-arduino-ide/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files. 7 | 8 | The above copyright notice and this permission notice shall be included in all 9 | copies or substantial portions of the Software. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | struct { 18 | byte magic; 19 | unsigned long counter; 20 | } savedCounter; 21 | 22 | #define EEPROM_SIZE 64 23 | 24 | #define MAGIC 55 25 | 26 | // REPLACE WITH RECEIVER MAC Address 27 | uint8_t broadcastAddress[] = {0x24, 0x6F, 0x28, 0x4E, 0xD8, 0xD1}; 28 | 29 | // Structure example to send data 30 | // Must match the receiver structure 31 | typedef struct struct_message { 32 | char a[32]; 33 | int b; 34 | float c; 35 | String d; 36 | bool e; 37 | } struct_message; 38 | 39 | unsigned long lastTime = 0; 40 | unsigned long timerDelay = 2000; // send readings timer 41 | 42 | // Callback when data is sent 43 | void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) { 44 | Serial.print("Last Packet Send Status: "); 45 | if (sendStatus == 0) { 46 | Serial.println("Delivery success"); 47 | } 48 | else { 49 | Serial.println("Delivery fail"); 50 | } 51 | } 52 | 53 | void sendData(unsigned long _inputNumber) { 54 | // const uint8_t *peer_addr = slave.peer_addr; 55 | // Encrypt 56 | for (int i = 0; i < 16; i++) enc_iv[i] = 0; 57 | itoa(_inputNumber, cleartext, 10); 58 | uint16_t messLen = String(cleartext).length(); 59 | for (int i = messLen + 1; i < 16; i++) cleartext[i] = 0; // patting to 16 bytes 60 | Serial.print("messLen: "); Serial.println(messLen); 61 | 62 | for (int i = 0; i < 16; i++) { 63 | Serial.print(cleartext[i]); Serial.print("/"); 64 | } 65 | Serial.println(); 66 | String encrypted = encrypt(cleartext, messLen, enc_iv); 67 | sprintf(ciphertext, "%s", encrypted.c_str()); 68 | 69 | Serial.print("Sending: "); 70 | esp_now_send(broadcastAddress, (uint8_t *) &ciphertext, 32); 71 | } 72 | 73 | void setup() { 74 | // Init Serial Monitor 75 | Serial.begin(115200); 76 | 77 | // Set device as a Wi-Fi Station 78 | WiFi.mode(WIFI_STA); 79 | 80 | // Init ESP-NOW 81 | if (esp_now_init() != 0) { 82 | Serial.println("Error initializing ESP-NOW"); 83 | return; 84 | } 85 | 86 | // Once ESPNow is successfully Init, we will register for Send CB to 87 | // get the status of Trasnmitted packet 88 | esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); 89 | esp_now_register_send_cb(OnDataSent); 90 | 91 | // Register peer 92 | esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0); 93 | 94 | EEPROM.begin(EEPROM_SIZE); 95 | EEPROM.get(0, savedCounter); 96 | Serial.println(savedCounter.magic); 97 | if (savedCounter.magic != MAGIC) { 98 | savedCounter.magic = MAGIC; 99 | savedCounter.counter = 0; 100 | EEPROM.put(0, savedCounter); 101 | Serial.println ("...................Please pair.................."); 102 | EEPROM.commit(); 103 | } 104 | cryptoInit(); 105 | } 106 | 107 | void loop() { 108 | savedCounter.counter++; 109 | EEPROM.put(0, savedCounter); 110 | EEPROM.commit(); 111 | Serial.println(savedCounter.counter); 112 | // savedCounter.counter=101; 113 | sendData(savedCounter.counter); 114 | delay(1000); 115 | } 116 | -------------------------------------------------------------------------------- /RealSlave/RealSlave.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ESPNOW - Basic communication - Slave 3 | Date: 26th September 2017 4 | Author: Arvind Ravulavaru 5 | Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 6 | Description: This sketch consists of the code for the Slave module. 7 | Resources: (A bit outdated) 8 | a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf 9 | b. http://www.esploradores.com/practica-6-conexion-esp-now/ 10 | 11 | << This Device Slave >> 12 | 13 | Flow: Master 14 | Step 1 : ESPNow Init on Master and set it in STA mode 15 | Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) 16 | Step 3 : Once found, add Slave as peer 17 | Step 4 : Register for send callback 18 | Step 5 : Start Transmitting data from Master to Slave 19 | 20 | Flow: Slave 21 | Step 1 : ESPNow Init on Slave 22 | Step 2 : Update the SSID of Slave with a prefix of `slave` 23 | Step 3 : Set Slave in AP mode 24 | Step 4 : Register for receive callback and wait for data 25 | Step 5 : Once data arrives, print it in the serial monitor 26 | 27 | Note: Master and Slave have been defined to easily understand the setup. 28 | Based on the ESPNOW API, there is no concept of Master and Slave. 29 | Any devices can act as master or salve. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #define CHANNEL 0 38 | #define PAIRPIN 12 39 | 40 | // int addr = 0; 41 | #define EEPROM_SIZE 64 42 | #define MAGIC 55 43 | 44 | typedef struct counterStruc { 45 | byte magic; 46 | unsigned long counter; 47 | } ; 48 | unsigned long receivedCounter; 49 | counterStruc rollingCounter; 50 | 51 | // Init ESP Now with fallback 52 | void InitESPNow() { 53 | WiFi.disconnect(); 54 | if (esp_now_init() == ESP_OK) { 55 | Serial.println("ESPNow Init Success"); 56 | } 57 | else { 58 | Serial.println("ESPNow Init Failed"); 59 | // Retry InitESPNow, add a counte and then restart? 60 | // InitESPNow(); 61 | // or Simply Restart 62 | ESP.restart(); 63 | } 64 | } 65 | 66 | // config AP SSID 67 | void configDeviceAP() { 68 | const char *SSID = "Slave_1"; 69 | bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0); 70 | if (!result) { 71 | Serial.println("AP Config failed."); 72 | } else { 73 | Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID)); 74 | } 75 | } 76 | 77 | void setup() { 78 | Serial.begin(115200); 79 | Serial.println("ESPNow/Basic/Slave Example"); 80 | //Set device in AP mode to begin with 81 | WiFi.mode(WIFI_AP); 82 | // configure device AP mode 83 | configDeviceAP(); 84 | // This is the mac address of the Slave in AP Mode 85 | Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress()); 86 | // Init ESPNow with a fallback logic 87 | InitESPNow(); 88 | // Once ESPNow is successfully Init, we will register for recv CB to 89 | // get recv packer info. 90 | esp_now_register_recv_cb(OnDataRecv); 91 | 92 | 93 | if (!EEPROM.begin(EEPROM_SIZE)) { 94 | Serial.println("failed to initialise EEPROM"); delay(1000000); 95 | } 96 | // read EEPROM 97 | EEPROM.get(0, rollingCounter); 98 | Serial.println(rollingCounter.magic); 99 | if (rollingCounter.magic != MAGIC) { 100 | rollingCounter.magic = MAGIC; 101 | EEPROM.put(0, rollingCounter); 102 | Serial.println ("...................Please pair.................."); 103 | EEPROM.commit(); 104 | } 105 | 106 | pinMode(PAIRPIN, INPUT_PULLUP); 107 | } 108 | 109 | // callback when data is recv from Master 110 | void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { 111 | char macStr[18]; 112 | snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", 113 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 114 | Serial.println(); 115 | Serial.print("Last Packet Recv from: "); Serial.println(macStr); 116 | 117 | // Decrypt 118 | for (int i = 0; i < 50; i++) ciphertext[i] = 0; // clear input file 119 | for (int i = 0; i < 16; i++) dec_iv[i] = 0; // clear internal variable 120 | int ii = 0; 121 | for (int i = 0; i < 50; i++) { // fill data into ciphertext (maybe not needed) 122 | if (data[i] == 0) break; 123 | ciphertext[i] = data[i]; 124 | Serial.print(ciphertext[i]); 125 | ii++; 126 | } Serial.println(); 127 | String decrypted = decrypt(ciphertext, ii, dec_iv); // Decryption 128 | receivedCounter = atol(decrypted.c_str()); // create unsigned long variable 129 | 130 | Serial.print("ReceivedCounter: "); 131 | Serial.print(receivedCounter); 132 | 133 | // Compare received with stored counter 134 | Serial.print(" RollingCounter "); 135 | Serial.print(rollingCounter.counter); 136 | if (receivedCounter > rollingCounter.counter) { 137 | Serial.println(" Code valid"); 138 | rollingCounter.counter = receivedCounter; 139 | EEPROM.put(0, rollingCounter); 140 | EEPROM.commit(); 141 | } 142 | else Serial.println(" Code not valid"); 143 | 144 | } 145 | 146 | void loop() { 147 | if (digitalRead(PAIRPIN) == 0) { 148 | Serial.println("Pairing Key"); 149 | rollingCounter.counter = receivedCounter; 150 | EEPROM.put(0, rollingCounter); 151 | EEPROM.commit(); 152 | Serial.println(rollingCounter.counter); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /Hello_World/Hello_World.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ESPNOW - Basic communication - Master 3 | Date: 26th September 2017 4 | Author: Arvind Ravulavaru 5 | Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 6 | Description: This sketch consists of the code for the Master module. 7 | Resources: (A bit outdated) 8 | a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf 9 | b. http://www.esploradores.com/practica-6-conexion-esp-now/ 10 | 11 | << This Device Master >> 12 | 13 | Flow: Master 14 | Step 1 : ESPNow Init on Master and set it in STA mode 15 | Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) 16 | Step 3 : Once found, add Slave as peer 17 | Step 4 : Register for send callback 18 | Step 5 : Start Transmitting data from Master to Slave 19 | 20 | Flow: Slave 21 | Step 1 : ESPNow Init on Slave 22 | Step 2 : Update the SSID of Slave with a prefix of `slave` 23 | Step 3 : Set Slave in AP mode 24 | Step 4 : Register for receive callback and wait for data 25 | Step 5 : Once data arrives, print it in the serial monitor 26 | 27 | Note: Master and Slave have been defined to easily understand the setup. 28 | Based on the ESPNOW API, there is no concept of Master and Slave. 29 | Any devices can act as master or salve. 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | // Global copy of slave 36 | esp_now_peer_info_t slave; 37 | #define CHANNEL 1 38 | #define PRINTSCANRESULTS 0 39 | #define DELETEBEFOREPAIR 0 40 | 41 | // Init ESP Now with fallback 42 | void InitESPNow() { 43 | WiFi.disconnect(); 44 | if (esp_now_init() == ESP_OK) { 45 | Serial.println("ESPNow Init Success"); 46 | } 47 | else { 48 | Serial.println("ESPNow Init Failed"); 49 | // Retry InitESPNow, add a counte and then restart? 50 | // InitESPNow(); 51 | // or Simply Restart 52 | ESP.restart(); 53 | } 54 | } 55 | 56 | // Scan for slaves in AP mode 57 | void ScanForSlave() { 58 | int8_t scanResults = WiFi.scanNetworks(); 59 | // reset on each scan 60 | bool slaveFound = 0; 61 | memset(&slave, 0, sizeof(slave)); 62 | 63 | Serial.println(""); 64 | if (scanResults == 0) { 65 | Serial.println("No WiFi devices in AP Mode found"); 66 | } else { 67 | Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices "); 68 | for (int i = 0; i < scanResults; ++i) { 69 | // Print SSID and RSSI for each device found 70 | String SSID = WiFi.SSID(i); 71 | int32_t RSSI = WiFi.RSSI(i); 72 | String BSSIDstr = WiFi.BSSIDstr(i); 73 | 74 | if (PRINTSCANRESULTS) { 75 | Serial.print(i + 1); 76 | Serial.print(": "); 77 | Serial.print(SSID); 78 | Serial.print(" ("); 79 | Serial.print(RSSI); 80 | Serial.print(")"); 81 | Serial.println(""); 82 | } 83 | delay(10); 84 | // Check if the current device starts with `Slave` 85 | if (SSID.indexOf("Slave") == 0) { 86 | // SSID of interest 87 | Serial.println("Found a Slave."); 88 | Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println(""); 89 | // Get BSSID => Mac Address of the Slave 90 | int mac[6]; 91 | if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) { 92 | for (int ii = 0; ii < 6; ++ii ) { 93 | slave.peer_addr[ii] = (uint8_t) mac[ii]; 94 | } 95 | } 96 | 97 | slave.channel = CHANNEL; // pick a channel 98 | slave.encrypt = 0; // no encryption 99 | 100 | slaveFound = 1; 101 | // we are planning to have only one slave in this example; 102 | // Hence, break after we find one, to be a bit efficient 103 | break; 104 | } 105 | } 106 | } 107 | 108 | if (slaveFound) { 109 | Serial.println("Slave Found, processing.."); 110 | } else { 111 | Serial.println("Slave Not Found, trying again."); 112 | } 113 | 114 | // clean up ram 115 | WiFi.scanDelete(); 116 | } 117 | 118 | // Check if the slave is already paired with the master. 119 | // If not, pair the slave with master 120 | bool manageSlave() { 121 | if (slave.channel == CHANNEL) { 122 | if (DELETEBEFOREPAIR) { 123 | deletePeer(); 124 | } 125 | 126 | Serial.print("Slave Status: "); 127 | // check if the peer exists 128 | bool exists = esp_now_is_peer_exist(slave.peer_addr); 129 | if ( exists) { 130 | // Slave already paired. 131 | Serial.println("Already Paired"); 132 | return true; 133 | } else { 134 | // Slave not paired, attempt pair 135 | esp_err_t addStatus = esp_now_add_peer(&slave); 136 | if (addStatus == ESP_OK) { 137 | // Pair success 138 | Serial.println("Pair success"); 139 | return true; 140 | } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) { 141 | // How did we get so far!! 142 | Serial.println("ESPNOW Not Init"); 143 | return false; 144 | } else if (addStatus == ESP_ERR_ESPNOW_ARG) { 145 | Serial.println("Invalid Argument"); 146 | return false; 147 | } else if (addStatus == ESP_ERR_ESPNOW_FULL) { 148 | Serial.println("Peer list full"); 149 | return false; 150 | } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) { 151 | Serial.println("Out of memory"); 152 | return false; 153 | } else if (addStatus == ESP_ERR_ESPNOW_EXIST) { 154 | Serial.println("Peer Exists"); 155 | return true; 156 | } else { 157 | Serial.println("Not sure what happened"); 158 | return false; 159 | } 160 | } 161 | } else { 162 | // No slave found to process 163 | Serial.println("No Slave found to process"); 164 | return false; 165 | } 166 | } 167 | 168 | void deletePeer() { 169 | esp_err_t delStatus = esp_now_del_peer(slave.peer_addr); 170 | Serial.print("Slave Delete Status: "); 171 | if (delStatus == ESP_OK) { 172 | // Delete success 173 | Serial.println("Success"); 174 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) { 175 | // How did we get so far!! 176 | Serial.println("ESPNOW Not Init"); 177 | } else if (delStatus == ESP_ERR_ESPNOW_ARG) { 178 | Serial.println("Invalid Argument"); 179 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) { 180 | Serial.println("Peer not found."); 181 | } else { 182 | Serial.println("Not sure what happened"); 183 | } 184 | } 185 | 186 | uint8_t data[16] = "Hello World"; 187 | // send data 188 | void sendData() { 189 | // data++; 190 | const uint8_t *peer_addr = slave.peer_addr; 191 | Serial.print("Sending: "); //Serial.println(data); 192 | esp_err_t result = esp_now_send(peer_addr, (uint8_t *)&data, sizeof(data)); 193 | Serial.print("Send Status: "); 194 | if (result == ESP_OK) { 195 | Serial.println("Success"); 196 | } else if (result == ESP_ERR_ESPNOW_NOT_INIT) { 197 | // How did we get so far!! 198 | Serial.println("ESPNOW not Init."); 199 | } else if (result == ESP_ERR_ESPNOW_ARG) { 200 | Serial.println("Invalid Argument"); 201 | } else if (result == ESP_ERR_ESPNOW_INTERNAL) { 202 | Serial.println("Internal Error"); 203 | } else if (result == ESP_ERR_ESPNOW_NO_MEM) { 204 | Serial.println("ESP_ERR_ESPNOW_NO_MEM"); 205 | } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) { 206 | Serial.println("Peer not found."); 207 | } else { 208 | Serial.println("Not sure what happened"); 209 | } 210 | } 211 | 212 | // callback when data is sent from Master to Slave 213 | void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { 214 | char macStr[18]; 215 | snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", 216 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 217 | Serial.print("Last Packet Sent to: "); Serial.println(macStr); 218 | Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); 219 | } 220 | 221 | void setup() { 222 | Serial.begin(115200); 223 | //Set device in STA mode to begin with 224 | WiFi.mode(WIFI_STA); 225 | Serial.println("ESPNow/Basic/Master Example"); 226 | // This is the mac address of the Master in Station Mode 227 | Serial.print("STA MAC: "); Serial.println(WiFi.macAddress()); 228 | // Init ESPNow with a fallback logic 229 | InitESPNow(); 230 | // Once ESPNow is successfully Init, we will register for Send CB to 231 | // get the status of Trasnmitted packet 232 | esp_now_register_send_cb(OnDataSent); 233 | } 234 | 235 | void loop() { 236 | // In the loop we scan for slave 237 | ScanForSlave(); 238 | // If Slave is found, it would be populate in `slave` variable 239 | // We will check if `slave` is defined and then we proceed further 240 | if (slave.channel == CHANNEL) { // check if slave channel is defined 241 | // `slave` is defined 242 | // Add slave as peer if it has not been added already 243 | bool isPaired = manageSlave(); 244 | if (isPaired) { 245 | // pair success or already paired 246 | // Send data to device 247 | sendData(); 248 | } else { 249 | // slave pair failed 250 | Serial.println("Slave pair failed!"); 251 | } 252 | } 253 | else { 254 | // No slave found to process 255 | } 256 | 257 | // wait for 3seconds to run the logic again 258 | delay(3000); 259 | } 260 | -------------------------------------------------------------------------------- /T_WatchButton/ESP_Now_header.h: -------------------------------------------------------------------------------- 1 | /** 2 | ESPNOW - Basic communication - Master 3 | Date: 26th September 2017 4 | Author: Arvind Ravulavaru 5 | Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 6 | Description: This sketch consists of the code for the Master module. 7 | Resources: (A bit outdated) 8 | a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf 9 | b. http://www.esploradores.com/practica-6-conexion-esp-now/ 10 | 11 | << This Device Master >> 12 | 13 | Flow: Master 14 | Step 1 : ESPNow Init on Master and set it in STA mode 15 | Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) 16 | Step 3 : Once found, add Slave as peer 17 | Step 4 : Register for send callback 18 | Step 5 : Start Transmitting data from Master to Slave 19 | 20 | Flow: Slave 21 | Step 1 : ESPNow Init on Slave 22 | Step 2 : Update the SSID of Slave with a prefix of `slave` 23 | Step 3 : Set Slave in AP mode 24 | Step 4 : Register for receive callback and wait for data 25 | Step 5 : Once data arrives, print it in the serial monitor 26 | 27 | Note: Master and Slave have been defined to easily understand the setup. 28 | Based on the ESPNOW API, there is no concept of Master and Slave. 29 | Any devices can act as master or salve. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | // Global copy of slave 38 | esp_now_peer_info_t slave; 39 | #define CHANNEL 0 40 | #define PRINTSCANRESULTS 0 41 | #define DELETEBEFOREPAIR 0 42 | 43 | #define EEPROM_SIZE 64 44 | 45 | #define MAGIC 55 46 | 47 | uint8_t data = 0; 48 | 49 | struct { 50 | byte magic; 51 | unsigned long counter; 52 | char ciphertext[50]; 53 | } savedCounter; 54 | 55 | // Init ESP Now with fallback 56 | void InitESPNow() { 57 | WiFi.disconnect(); 58 | if (esp_now_init() == ESP_OK) { 59 | Serial.println("ESPNow Init Success"); 60 | } 61 | else { 62 | Serial.println("ESPNow Init Failed"); 63 | // Retry InitESPNow, add a counte and then restart? 64 | // InitESPNow(); 65 | // or Simply Restart 66 | ESP.restart(); 67 | } 68 | } 69 | 70 | // Scan for slaves in AP mode 71 | void ScanForSlave() { 72 | int8_t scanResults = WiFi.scanNetworks(); 73 | // reset on each scan 74 | bool slaveFound = 0; 75 | memset(&slave, 0, sizeof(slave)); 76 | 77 | Serial.println(""); 78 | if (scanResults == 0) { 79 | Serial.println("No WiFi devices in AP Mode found"); 80 | } else { 81 | Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices "); 82 | for (int i = 0; i < scanResults; ++i) { 83 | // Print SSID and RSSI for each device found 84 | String SSID = WiFi.SSID(i); 85 | int32_t RSSI = WiFi.RSSI(i); 86 | String BSSIDstr = WiFi.BSSIDstr(i); 87 | 88 | if (PRINTSCANRESULTS) { 89 | Serial.print(i + 1); 90 | Serial.print(": "); 91 | Serial.print(SSID); 92 | Serial.print(" ("); 93 | Serial.print(RSSI); 94 | Serial.print(")"); 95 | Serial.println(""); 96 | } 97 | delay(10); 98 | // Check if the current device starts with `Slave` 99 | if (SSID.indexOf("Slave") == 0) { 100 | // SSID of interest 101 | Serial.println("Found a Slave."); 102 | Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println(""); 103 | // Get BSSID => Mac Address of the Slave 104 | int mac[6]; 105 | if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) { 106 | for (int ii = 0; ii < 6; ++ii ) { 107 | slave.peer_addr[ii] = (uint8_t) mac[ii]; 108 | } 109 | } 110 | 111 | slave.channel = CHANNEL; // pick a channel 112 | slave.encrypt = 0; // no encryption 113 | 114 | slaveFound = 1; 115 | // we are planning to have only one slave in this example; 116 | // Hence, break after we find one, to be a bit efficient 117 | break; 118 | } 119 | } 120 | } 121 | 122 | if (slaveFound) { 123 | Serial.println("Slave Found, processing.."); 124 | } else { 125 | Serial.println("Slave Not Found, trying again."); 126 | } 127 | 128 | // clean up ram 129 | WiFi.scanDelete(); 130 | } 131 | 132 | void deletePeer() { 133 | esp_err_t delStatus = esp_now_del_peer(slave.peer_addr); 134 | Serial.print("Slave Delete Status: "); 135 | if (delStatus == ESP_OK) { 136 | // Delete success 137 | Serial.println("Success"); 138 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) { 139 | // How did we get so far!! 140 | Serial.println("ESPNOW Not Init"); 141 | } else if (delStatus == ESP_ERR_ESPNOW_ARG) { 142 | Serial.println("Invalid Argument"); 143 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) { 144 | Serial.println("Peer not found."); 145 | } else { 146 | Serial.println("Not sure what happened"); 147 | } 148 | } 149 | 150 | // Check if the slave is already paired with the master. 151 | // If not, pair the slave with master 152 | bool manageSlave() { 153 | if (slave.channel == CHANNEL) { 154 | if (DELETEBEFOREPAIR) { 155 | deletePeer(); 156 | } 157 | 158 | Serial.print("Slave Status: "); 159 | // check if the peer exists 160 | bool exists = esp_now_is_peer_exist(slave.peer_addr); 161 | if ( exists) { 162 | // Slave already paired. 163 | Serial.println("Already Paired"); 164 | return true; 165 | } else { 166 | // Slave not paired, attempt pair 167 | esp_err_t addStatus = esp_now_add_peer(&slave); 168 | if (addStatus == ESP_OK) { 169 | // Pair success 170 | Serial.println("Pair success"); 171 | return true; 172 | } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) { 173 | // How did we get so far!! 174 | Serial.println("ESPNOW Not Init"); 175 | return false; 176 | } else if (addStatus == ESP_ERR_ESPNOW_ARG) { 177 | Serial.println("Invalid Argument"); 178 | return false; 179 | } else if (addStatus == ESP_ERR_ESPNOW_FULL) { 180 | Serial.println("Peer list full"); 181 | return false; 182 | } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) { 183 | Serial.println("Out of memory"); 184 | return false; 185 | } else if (addStatus == ESP_ERR_ESPNOW_EXIST) { 186 | Serial.println("Peer Exists"); 187 | return true; 188 | } else { 189 | Serial.println("Not sure what happened"); 190 | return false; 191 | } 192 | } 193 | } else { 194 | // No slave found to process 195 | Serial.println("No Slave found to process"); 196 | return false; 197 | } 198 | } 199 | 200 | void transmit(unsigned long _inputNumber) { 201 | const uint8_t *peer_addr = slave.peer_addr; 202 | // Encrypt 203 | for (int i = 0; i < 16; i++) enc_iv[i] = 0; 204 | itoa(_inputNumber, cleartext, 10); 205 | uint16_t messLen = String(cleartext).length(); 206 | for (int i = messLen + 1; i < 16; i++) cleartext[i] = 0; // patting to 16 bytes 207 | Serial.print("messLen: "); Serial.println(messLen); 208 | 209 | for (int i = 0; i < 16; i++) { 210 | Serial.print(cleartext[i], HEX); Serial.print("/"); 211 | } 212 | Serial.println(); 213 | String encrypted = encrypt(cleartext, messLen, enc_iv); 214 | sprintf(ciphertext, "%s", encrypted.c_str()); 215 | 216 | Serial.print("Sending: "); 217 | esp_err_t result = esp_now_send(peer_addr, (uint8_t *)&ciphertext, sizeof(savedCounter)); 218 | Serial.print("Send Status: "); 219 | if (result == ESP_OK) { 220 | Serial.println("Success"); 221 | } else if (result == ESP_ERR_ESPNOW_NOT_INIT) { 222 | // How did we get so far!! 223 | Serial.println("ESPNOW not Init."); 224 | } else if (result == ESP_ERR_ESPNOW_ARG) { 225 | Serial.println("Invalid Argument"); 226 | } else if (result == ESP_ERR_ESPNOW_INTERNAL) { 227 | Serial.println("Internal Error"); 228 | } else if (result == ESP_ERR_ESPNOW_NO_MEM) { 229 | Serial.println("ESP_ERR_ESPNOW_NO_MEM"); 230 | } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) { 231 | Serial.println("Peer not found."); 232 | } else { 233 | Serial.println("Not sure what happened"); 234 | } 235 | } 236 | 237 | void sendData() { 238 | ScanForSlave(); 239 | // If Slave is found, it would be populate in `slave` variable 240 | // We will check if `slave` is defined and then we proceed further 241 | if (slave.channel == CHANNEL) { // check if slave channel is defined 242 | // `slave` is defined 243 | // Add slave as peer if it has not been added already 244 | bool isPaired = manageSlave(); 245 | if (isPaired) { 246 | // pair success or already paired 247 | // Send data to device 248 | savedCounter.counter++; 249 | EEPROM.put(0, savedCounter); 250 | EEPROM.commit(); 251 | Serial.println(savedCounter.counter); 252 | transmit(savedCounter.counter); 253 | } else { 254 | // slave pair failed 255 | Serial.println("Slave pair failed!"); 256 | } 257 | } 258 | else { 259 | // No slave found to process 260 | } 261 | } 262 | 263 | // callback when data is sent from Master to Slave 264 | void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { 265 | char macStr[18]; 266 | snprintf(macStr, sizeof(macStr), " % 02x: % 02x: % 02x: % 02x: % 02x: % 02x", 267 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 268 | Serial.print("Last Packet Sent to: "); Serial.println(macStr); 269 | Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); 270 | } 271 | -------------------------------------------------------------------------------- /RealMaster/RealMaster.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ESPNOW - Basic communication - Master 3 | Date: 26th September 2017 4 | Author: Arvind Ravulavaru 5 | Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 6 | Description: This sketch consists of the code for the Master module. 7 | Resources: (A bit outdated) 8 | a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf 9 | b. http://www.esploradores.com/practica-6-conexion-esp-now/ 10 | 11 | << This Device Master >> 12 | 13 | Flow: Master 14 | Step 1 : ESPNow Init on Master and set it in STA mode 15 | Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) 16 | Step 3 : Once found, add Slave as peer 17 | Step 4 : Register for send callback 18 | Step 5 : Start Transmitting data from Master to Slave 19 | 20 | Flow: Slave 21 | Step 1 : ESPNow Init on Slave 22 | Step 2 : Update the SSID of Slave with a prefix of `slave` 23 | Step 3 : Set Slave in AP mode 24 | Step 4 : Register for receive callback and wait for data 25 | Step 5 : Once data arrives, print it in the serial monitor 26 | 27 | Note: Master and Slave have been defined to easily understand the setup. 28 | Based on the ESPNOW API, there is no concept of Master and Slave. 29 | Any devices can act as master or salve. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | // Global copy of slave 38 | esp_now_peer_info_t slave; 39 | #define CHANNEL 0 40 | #define PRINTSCANRESULTS 0 41 | #define DELETEBEFOREPAIR 0 42 | 43 | #define EEPROM_SIZE 64 44 | 45 | #define MAGIC 55 46 | 47 | uint8_t data = 0; 48 | 49 | struct { 50 | byte magic; 51 | unsigned long counter; 52 | char ciphertext[50]; 53 | } savedCounter; 54 | 55 | // Init ESP Now with fallback 56 | void InitESPNow() { 57 | WiFi.disconnect(); 58 | if (esp_now_init() == ESP_OK) { 59 | Serial.println("ESPNow Init Success"); 60 | } 61 | else { 62 | Serial.println("ESPNow Init Failed"); 63 | // Retry InitESPNow, add a counte and then restart? 64 | // InitESPNow(); 65 | // or Simply Restart 66 | ESP.restart(); 67 | } 68 | } 69 | 70 | // Scan for slaves in AP mode 71 | void ScanForSlave() { 72 | int8_t scanResults = WiFi.scanNetworks(); 73 | // reset on each scan 74 | bool slaveFound = 0; 75 | memset(&slave, 0, sizeof(slave)); 76 | 77 | Serial.println(""); 78 | if (scanResults == 0) { 79 | Serial.println("No WiFi devices in AP Mode found"); 80 | } else { 81 | Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices "); 82 | for (int i = 0; i < scanResults; ++i) { 83 | // Print SSID and RSSI for each device found 84 | String SSID = WiFi.SSID(i); 85 | int32_t RSSI = WiFi.RSSI(i); 86 | String BSSIDstr = WiFi.BSSIDstr(i); 87 | 88 | if (PRINTSCANRESULTS) { 89 | Serial.print(i + 1); 90 | Serial.print(": "); 91 | Serial.print(SSID); 92 | Serial.print(" ("); 93 | Serial.print(RSSI); 94 | Serial.print(")"); 95 | Serial.println(""); 96 | } 97 | delay(10); 98 | // Check if the current device starts with `Slave` 99 | if (SSID.indexOf("Slave") == 0) { 100 | // SSID of interest 101 | Serial.println("Found a Slave."); 102 | Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println(""); 103 | // Get BSSID => Mac Address of the Slave 104 | int mac[6]; 105 | if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) { 106 | for (int ii = 0; ii < 6; ++ii ) { 107 | slave.peer_addr[ii] = (uint8_t) mac[ii]; 108 | } 109 | } 110 | 111 | slave.channel = CHANNEL; // pick a channel 112 | slave.encrypt = 0; // no encryption 113 | 114 | slaveFound = 1; 115 | // we are planning to have only one slave in this example; 116 | // Hence, break after we find one, to be a bit efficient 117 | break; 118 | } 119 | } 120 | } 121 | 122 | if (slaveFound) { 123 | Serial.println("Slave Found, processing.."); 124 | } else { 125 | Serial.println("Slave Not Found, trying again."); 126 | } 127 | 128 | // clean up ram 129 | WiFi.scanDelete(); 130 | } 131 | 132 | // Check if the slave is already paired with the master. 133 | // If not, pair the slave with master 134 | bool manageSlave() { 135 | if (slave.channel == CHANNEL) { 136 | if (DELETEBEFOREPAIR) { 137 | deletePeer(); 138 | } 139 | 140 | Serial.print("Slave Status: "); 141 | // check if the peer exists 142 | bool exists = esp_now_is_peer_exist(slave.peer_addr); 143 | if ( exists) { 144 | // Slave already paired. 145 | Serial.println("Already Paired"); 146 | return true; 147 | } else { 148 | // Slave not paired, attempt pair 149 | esp_err_t addStatus = esp_now_add_peer(&slave); 150 | if (addStatus == ESP_OK) { 151 | // Pair success 152 | Serial.println("Pair success"); 153 | return true; 154 | } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) { 155 | // How did we get so far!! 156 | Serial.println("ESPNOW Not Init"); 157 | return false; 158 | } else if (addStatus == ESP_ERR_ESPNOW_ARG) { 159 | Serial.println("Invalid Argument"); 160 | return false; 161 | } else if (addStatus == ESP_ERR_ESPNOW_FULL) { 162 | Serial.println("Peer list full"); 163 | return false; 164 | } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) { 165 | Serial.println("Out of memory"); 166 | return false; 167 | } else if (addStatus == ESP_ERR_ESPNOW_EXIST) { 168 | Serial.println("Peer Exists"); 169 | return true; 170 | } else { 171 | Serial.println("Not sure what happened"); 172 | return false; 173 | } 174 | } 175 | } else { 176 | // No slave found to process 177 | Serial.println("No Slave found to process"); 178 | return false; 179 | } 180 | } 181 | 182 | void deletePeer() { 183 | esp_err_t delStatus = esp_now_del_peer(slave.peer_addr); 184 | Serial.print("Slave Delete Status: "); 185 | if (delStatus == ESP_OK) { 186 | // Delete success 187 | Serial.println("Success"); 188 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) { 189 | // How did we get so far!! 190 | Serial.println("ESPNOW Not Init"); 191 | } else if (delStatus == ESP_ERR_ESPNOW_ARG) { 192 | Serial.println("Invalid Argument"); 193 | } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) { 194 | Serial.println("Peer not found."); 195 | } else { 196 | Serial.println("Not sure what happened"); 197 | } 198 | } 199 | 200 | void sendData(unsigned long _inputNumber) { 201 | const uint8_t *peer_addr = slave.peer_addr; 202 | // Encrypt 203 | for (int i = 0; i < 16; i++) enc_iv[i] = 0; 204 | itoa(_inputNumber, cleartext, 10); // unsigned long to char string 205 | uint16_t messLen = String(cleartext).length(); 206 | for (int i = messLen + 1; i < 16; i++) cleartext[i] = 0; // padding to 16 bytes 207 | Serial.print("messLen: "); Serial.println(messLen); 208 | 209 | String encrypted = encrypt(cleartext, messLen, enc_iv); // Encryption 210 | sprintf(ciphertext, "%s", encrypted.c_str()); // to char array 211 | 212 | Serial.print("Sending: "); 213 | esp_err_t result = esp_now_send(peer_addr, (uint8_t *)&ciphertext, sizeof(savedCounter)); // Transmission 214 | Serial.print("Send Status: "); 215 | if (result == ESP_OK) { 216 | Serial.println("Success"); 217 | } else if (result == ESP_ERR_ESPNOW_NOT_INIT) { 218 | // How did we get so far!! 219 | Serial.println("ESPNOW not Init."); 220 | } else if (result == ESP_ERR_ESPNOW_ARG) { 221 | Serial.println("Invalid Argument"); 222 | } else if (result == ESP_ERR_ESPNOW_INTERNAL) { 223 | Serial.println("Internal Error"); 224 | } else if (result == ESP_ERR_ESPNOW_NO_MEM) { 225 | Serial.println("ESP_ERR_ESPNOW_NO_MEM"); 226 | } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) { 227 | Serial.println("Peer not found."); 228 | } else { 229 | Serial.println("Not sure what happened"); 230 | } 231 | } 232 | 233 | // callback when data is sent from Master to Slave 234 | void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { 235 | char macStr[18]; 236 | snprintf(macStr, sizeof(macStr), " % 02x: % 02x: % 02x: % 02x: % 02x: % 02x", 237 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 238 | Serial.print("Last Packet Sent to: "); Serial.println(macStr); 239 | Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); 240 | } 241 | 242 | void setup() { 243 | Serial.begin(115200); 244 | //Set device in STA mode to begin with 245 | WiFi.mode(WIFI_STA); 246 | Serial.println("ESPNow / Basic / Master Example"); 247 | // This is the mac address of the Master in Station Mode 248 | Serial.print("STA MAC: "); Serial.println(WiFi.macAddress()); 249 | // Init ESPNow with a fallback logic 250 | InitESPNow(); 251 | // Once ESPNow is successfully Init, we will register for Send CB to 252 | // get the status of Trasnmitted packet 253 | esp_now_register_send_cb(OnDataSent); 254 | 255 | if (!EEPROM.begin(EEPROM_SIZE)) { 256 | Serial.println("failed to initialise EEPROM"); delay(1000000); 257 | } 258 | EEPROM.get(0, savedCounter); 259 | Serial.println(savedCounter.magic); 260 | if (savedCounter.magic != MAGIC) { 261 | savedCounter.magic = MAGIC; 262 | EEPROM.put(0, savedCounter); 263 | Serial.println ("...................Please pair.................."); 264 | EEPROM.commit(); 265 | } 266 | cryptoInit(); 267 | 268 | } 269 | 270 | void loop() { 271 | // In the loop we scan for slave 272 | ScanForSlave(); 273 | // If Slave is found, it would be populate in `slave` variable 274 | // We will check if `slave` is defined and then we proceed further 275 | if (slave.channel == CHANNEL) { // check if slave channel is defined 276 | // `slave` is defined 277 | // Add slave as peer if it has not been added already 278 | bool isPaired = manageSlave(); 279 | if (isPaired) { 280 | // pair success or already paired 281 | // Send data to device 282 | savedCounter.counter++; 283 | sendData(savedCounter.counter); // Encription done here 284 | EEPROM.put(0, savedCounter); 285 | EEPROM.commit(); 286 | Serial.println(savedCounter.counter); 287 | 288 | } else { 289 | // slave pair failed 290 | Serial.println("Slave pair failed!"); 291 | } 292 | } 293 | else { 294 | // No slave found to process 295 | } 296 | 297 | // wait for 3seconds to run the logic again 298 | delay(2000); 299 | } 300 | --------------------------------------------------------------------------------