Last active
September 16, 2024 11:01
-
-
Save ZanzyTHEbar/5cc372b86fcf1bf591f3b33f817df04b to your computer and use it in GitHub Desktop.
ESPNow and Wifi simultaneously
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use ESP-NOW to do something based on a message from another device | |
// and also connect to WiFi to display a web page, deal with MQTT etc | |
// in this case just light an LED and get UNIX timestamp from an NTP server | |
// NOTE: WiFi router must be on Channel 1 for this simple version to work | |
// Compiled using Arduino 1.8.19, and ESP32 v2.0.2 | |
// Compiled for board: ESP32 Dev Module | |
// (but running on an AI Thinker ESP-CAM since I have a bunch of them) | |
// Based on "ResponderA_22A.ino v01 | |
// ...... program information | |
char programName[] = "ResponderA_22A"; | |
char versionNumber[] = "v01"; | |
char programDate[] = "2022-09-25"; | |
char programAuthor[] = "Donald Weiman"; | |
// ...... required libraries | |
#include <esp_now.h> | |
#include <WiFi.h> | |
#include "esp_sntp.h" // ntp | |
// define data structure for received data | |
struct s_message { | |
int i_id; | |
int i_count; | |
char c_level[20]; | |
} ; | |
// create structured data object | |
s_message s_switchInfo; // from initiator | |
// ...... LED | |
const byte flashLedPin = 4; // white led on AI Thinker ESP-CAM board | |
#define flashLedOff 0 // active high | |
const byte builtinLedPin = 33; // red led on AI Thinker ESP-CAM board | |
#define builtinLedOff 1 // active low | |
// ...... misc | |
char thisDeviceMac[20] ; // Mac address for this device (for info only) | |
bool newDataFlag = false; | |
// ...... WiFi | |
const char* ssid = "plugh"; // on WiFi channel 1 | |
const char* pass = "xyzzy"; | |
// ...... NTP | |
char ntpPool[] = "pool.ntp.org"; | |
char ntpTzEnvData[] = "EST+5EDT,M3.2.0/2:00:00,M11.1.0/2:00:00"; // US/Eastern | |
bool ntpUpdateFlag = false; | |
bool changeNtpSync = true; // false --> use default 3600 seconds | |
const uint32_t ntpSyncInterval = 120; // true --> use this interval (seconds) | |
// ...... timing parameters (for example procedure in loop()) | |
time_t timestampNow; | |
// .................................................................................... | |
void setup() { | |
Serial.begin(115200); | |
delay(1000); | |
// ...... display sign-on message | |
Serial.println(); | |
Serial.println(); | |
Serial.print(programName); | |
Serial.print(" "); | |
Serial.print(versionNumber); | |
Serial.print(" "); | |
Serial.print(programDate); | |
Serial.print(" "); | |
Serial.print(programAuthor); | |
Serial.print("\n"); | |
// ...... display MAC address (of this device) | |
WiFi.macAddress().toCharArray(thisDeviceMac, 20); | |
Serial.printf("\nMAC address: %s", thisDeviceMac); | |
// ...... WiFi | |
WiFi.mode(WIFI_AP_STA); // AP needed to maintain ESP-NOW | |
WiFi.begin(ssid, pass); | |
// Wait for connection | |
Serial.println(""); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.print("Connected to "); | |
Serial.println(ssid); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
// ...... NTP | |
Serial.print("\nconnecting to NTP time server"); | |
connectToNtp(); | |
// ...... esp-now | |
// initalize ESP-NOW | |
if (esp_now_init() != ESP_OK) { | |
Serial.println("Error initializing ESP-NOW"); | |
return; | |
} | |
// register callback function | |
esp_now_register_recv_cb(OnDataRecv); | |
// ...... LEDs | |
pinMode(flashLedPin, OUTPUT); // turn LEDs off | |
digitalWrite(flashLedPin, flashLedOff); | |
pinMode(builtinLedPin, OUTPUT); | |
digitalWrite(builtinLedPin, builtinLedOff); | |
// ...... end of setup | |
Serial.print("\nsetup complete\n"); | |
} | |
// .................................................................................... | |
void loop() { | |
// act on received data if appropriate | |
if(newDataFlag == true) { | |
newDataFlag = false; | |
// act on received data | |
if(strcmp (s_switchInfo.c_level, "HIGH") == 0) { | |
digitalWrite(flashLedPin, !flashLedOff); | |
digitalWrite(builtinLedPin, builtinLedOff); | |
} else { | |
digitalWrite(flashLedPin, flashLedOff); | |
digitalWrite(builtinLedPin, !builtinLedOff); | |
} | |
} | |
// NTP | |
timestampNow = time(nullptr); | |
if(ntpUpdateFlag == true) { | |
ntpUpdateFlag = false; | |
Serial.print("\n *** NTP update *** "); | |
Serial.print(timestampNow); | |
} | |
// do something else ... | |
} | |
// .................................................................................... | |
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { | |
// extract the received data | |
char receivedData[100]; | |
memcpy(&s_switchInfo, incomingData, sizeof(s_switchInfo)); | |
// deal with received data | |
newDataFlag = true; // handled in loop() | |
// display received data - (interesting, but not essential) | |
char recvStr[50]; | |
snprintf(recvStr, sizeof(recvStr), "\n %u %u %s", | |
s_switchInfo.i_id, s_switchInfo.i_count, s_switchInfo.c_level); | |
Serial.print(recvStr); | |
// display MAC of sending device - (interesting, but not essential) | |
char macStr[20]; | |
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", | |
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | |
Serial.print(" Received from "); | |
Serial.print(macStr); | |
// display UNIX timestamp obtained from NTP server | |
Serial.print(" at "); | |
Serial.print(timestampNow); | |
} | |
// .................................................................................... | |
// NTP time synchronization callback | |
// this callback will place the current UNIX timestamp that was obtained | |
// via NTP into a structure of type 'timeval' which is defined in time.h | |
// it looks like this must be done even if the data isn't subsequently used | |
// NOTE: This is apparently being executed in a different core from the | |
// main program. Any Serial.print data here may be interspersed with | |
// Serial.print data from the main program. | |
void time_is_set (struct timeval *bogus) { | |
ntpUpdateFlag = true; | |
} | |
// .................................................................................... | |
void connectToNtp() { | |
// possibly change NTP sync interval (default = 3600 seconds) | |
if(changeNtpSync == true) { | |
sntp_set_sync_interval(ntpSyncInterval * 1000); | |
} | |
// register a callback to notify about the time synchronization process | |
sntp_set_time_sync_notification_cb(time_is_set); | |
// obtain system time from an NTP server, do not adjust for timezone or dst here | |
configTime(0, 0, ntpPool); // obtain time from an NTP server | |
// set the TZ environment variable to the correct value for the device location | |
setenv("TZ", ntpTzEnvData, 1); | |
// update the C library runtime data for the new time zone | |
tzset(); | |
} | |
// .................................................................................... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use ESP-NOW to send input level information to another device | |
// input can be from switch, PIR sensor, light sensor, etc. | |
// Compiled using Arduino 1.8.19, and ESP32 v2.0.2 | |
// Compiled for board: ESP32 Dev Module | |
// (but running on an AI Thinker ESP-CAM since I have a bunch of them) | |
// ...... program information | |
char programName[] = "InitiatorA_22A"; | |
char versionNumber[] = "v01"; | |
char programDate[] = "2022-09-25"; | |
char programAuthor[] = "Donald Weiman"; | |
// ...... hardware connections | |
// Push-button switch between Vcc and GPIO13 | |
// or | |
// HC-SR501 PIR Motion Detector module connected to GPIO13 | |
// ...... required libraries | |
#include <esp_now.h> | |
#include <WiFi.h> | |
// ...... esp-now | |
// remote MAC Address | |
uint8_t responderAddress[] = {0x34, 0x94, 0x54, 0x24, 0x3D, 0xE0}; | |
// specify where to store information about the other devices | |
// NOTE: this structure is defined in 'esp_now.h' | |
esp_now_peer_info_t responderInfo; | |
// define data structure for transmitted data | |
struct s_message { | |
int i_id; | |
int i_count; | |
char c_level[20]; | |
} ; | |
// create structured data object | |
s_message s_switchInfo; // to responder | |
// ...... switch | |
const byte inputPin = 13; | |
int oldValue = 0; | |
bool newValueFlag = false; | |
int lowCount = 0; | |
int highCount = 0; | |
// ...... misc | |
char thisDeviceMac[20] ; // Mac address for this device (for info only) | |
int unitId = 102; // arbitrary 'unit id' | |
// .................................................................................... | |
void setup() { | |
Serial.begin(115200); | |
delay(1000); | |
// ...... display sign-on message | |
Serial.println(); | |
Serial.println(); | |
Serial.print(programName); | |
Serial.print(" "); | |
Serial.print(versionNumber); | |
Serial.print(" "); | |
Serial.print(programDate); | |
Serial.print(" "); | |
Serial.print(programAuthor); | |
Serial.print("\n"); | |
// ...... display MAC address (of this device) | |
WiFi.macAddress().toCharArray(thisDeviceMac, 20); | |
Serial.printf("\nMAC address: %s", thisDeviceMac); | |
// ...... switch | |
pinMode(inputPin, INPUT_PULLDOWN); // active HIGH | |
// ...... WiFi | |
WiFi.mode(WIFI_STA); | |
// ...... esp-now | |
// initalize ESP-NOW | |
if (esp_now_init() != ESP_OK) { | |
Serial.println("Error initializing ESP-NOW"); | |
return; | |
} | |
// register callback function | |
esp_now_register_send_cb(OnDataSent); | |
// register peer (remote device) | |
// put peer information into the 'responderInfo' data structure | |
memcpy(responderInfo.peer_addr, responderAddress, 6); // address has 6 bytes | |
responderInfo.channel = 0; // use current channel | |
responderInfo.encrypt = false; // don't encrypt | |
// add peer to paired device list | |
if (esp_now_add_peer(&responderInfo) != ESP_OK) { | |
Serial.println("Failed to add peer"); | |
return; | |
} | |
// ...... end of setup | |
Serial.print("\nsetup complete\n"); | |
} | |
// .................................................................................... | |
void loop() { | |
checkInputLevel(); | |
// send message if appropriate | |
if(newValueFlag == true) { | |
newValueFlag = false; | |
if(esp_now_send(responderAddress, (uint8_t *) &s_switchInfo, sizeof(s_switchInfo)) != ESP_OK) { | |
Serial.println("Failed to send the data"); | |
} | |
} | |
// do something else ... | |
} | |
// .................................................................................... | |
void OnDataSent(const uint8_t *macAddr, esp_now_send_status_t status) { | |
// callback when data is sent | |
Serial.print("\nMessage sent"); | |
// display MAC of where the data was sent | |
char macStr[25]; | |
snprintf(macStr, sizeof(macStr)," to %02X:%02X:%02X:%02X:%02X:%02X", | |
macAddr[0], macAddr[1], macAddr[2], | |
macAddr[3], macAddr[4], macAddr[5]); | |
Serial.print(macStr); | |
// display the status returned by the other device | |
Serial.print(", status: "); | |
Serial.print(status == ESP_NOW_SEND_SUCCESS ? "OK" : "Fail"); | |
// display the data that was sent | |
displayTransmittedData(); | |
} | |
// .................................................................................... | |
void displayTransmittedData() { | |
// desired data is in 's_switchInfo' structure | |
char dataStr[50]; | |
snprintf(dataStr, sizeof(dataStr), "\n Device number %u, Level %s, Count %u ", | |
s_switchInfo.i_id, s_switchInfo.c_level, s_switchInfo.i_count); | |
Serial.print(dataStr); | |
} | |
// .................................................................................... | |
void checkInputLevel() { | |
int value = digitalRead(inputPin); | |
if (value != oldValue) { | |
newValueFlag = true; | |
oldValue = value; | |
if(value == 1) { | |
Serial.print("\n--> level has gone high"); | |
++highCount; | |
s_switchInfo.i_id = unitId; | |
s_switchInfo.i_count = highCount; | |
strcpy(s_switchInfo.c_level, "HIGH"); | |
} | |
else { | |
if(value == 0) | |
Serial.print("\n--> level has gone low"); | |
++lowCount; | |
s_switchInfo.i_id = unitId; | |
s_switchInfo.i_count = lowCount; | |
strcpy(s_switchInfo.c_level, "LOW"); | |
} | |
delay(10); // crude debounce | |
} | |
} | |
// .................................................................................... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use ESP-NOW to do something based on a message from another device | |
// in this case just light an LED | |
// Compiled using Arduino 1.8.19, and ESP32 v2.0.2 | |
// Compiled for board: ESP32 Dev Module | |
// (but running on an AI Thinker ESP-CAM since I have a bunch of them) | |
// ...... program information | |
char programName[] = "ResponderA_22A"; | |
char versionNumber[] = "v01"; | |
char programDate[] = "2022-09-25"; | |
char programAuthor[] = "Donald Weiman"; | |
// ...... required libraries | |
#include <esp_now.h> | |
#include <WiFi.h> | |
// define data structure for received data | |
struct s_message { | |
int i_id; | |
int i_count; | |
char c_level[20]; | |
} ; | |
// create structured data object | |
s_message s_switchInfo; // from initiator | |
// ...... LED | |
const byte flashLedPin = 4; // white led on AI Thinker ESP-CAM board | |
#define flashLedOff 0 // active high | |
const byte builtinLedPin = 33; // red led on AI Thinker ESP-CAM board | |
#define builtinLedOff 1 // active low | |
// ...... misc | |
char thisDeviceMac[20] ; // Mac address for this device (for info only) | |
bool newDataFlag = false; | |
// .................................................................................... | |
void setup() { | |
Serial.begin(115200); | |
delay(1000); | |
// ...... display sign-on message | |
Serial.println(); | |
Serial.println(); | |
Serial.print(programName); | |
Serial.print(" "); | |
Serial.print(versionNumber); | |
Serial.print(" "); | |
Serial.print(programDate); | |
Serial.print(" "); | |
Serial.print(programAuthor); | |
Serial.print("\n"); | |
// ...... display MAC address (of this device) | |
WiFi.macAddress().toCharArray(thisDeviceMac, 20); | |
Serial.printf("\nMAC address: %s", thisDeviceMac); | |
// ...... WiFi | |
WiFi.mode(WIFI_STA); | |
// ...... esp-now | |
// initalize ESP-NOW | |
if (esp_now_init() != ESP_OK) { | |
Serial.println("Error initializing ESP-NOW"); | |
return; | |
} | |
// register callback function | |
esp_now_register_recv_cb(OnDataRecv); | |
// ...... LEDs | |
pinMode(flashLedPin, OUTPUT); // turn LEDs off | |
digitalWrite(flashLedPin, flashLedOff); | |
pinMode(builtinLedPin, OUTPUT); | |
digitalWrite(builtinLedPin, builtinLedOff); | |
// ...... end of setup | |
Serial.print("\nsetup complete\n"); | |
} | |
// .................................................................................... | |
void loop() { | |
// act on received data if appropriate | |
if(newDataFlag == true) { | |
newDataFlag = false; | |
// act on received data | |
if(strcmp (s_switchInfo.c_level, "HIGH") == 0) { | |
digitalWrite(flashLedPin, !flashLedOff); | |
digitalWrite(builtinLedPin, builtinLedOff); | |
} else { | |
digitalWrite(flashLedPin, flashLedOff); | |
digitalWrite(builtinLedPin, !builtinLedOff); | |
} | |
} | |
// do something else ... | |
} | |
// .................................................................................... | |
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { | |
// extract the received data | |
char receivedData[100]; | |
memcpy(&s_switchInfo, incomingData, sizeof(s_switchInfo)); | |
// deal with received data | |
newDataFlag = true; // handled in loop() | |
// display received data - (interesting, but not essential) | |
char recvStr[50]; | |
snprintf(recvStr, sizeof(recvStr), "\n %u %u %s", | |
s_switchInfo.i_id, s_switchInfo.i_count, s_switchInfo.c_level); | |
Serial.print(recvStr); | |
// display MAC of sending device - (interesting, but not essential) | |
char macStr[20]; | |
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", | |
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | |
Serial.print(" Received from "); | |
Serial.print(macStr); | |
} | |
// .................................................................................... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment