0

I am trying to set up two ESP32s so that they can be updated via OTA and at the same time send sensor readings using ESP-NOW, from Sender Board to Receiver Board.

For this to work both boards must connect to wifi and simultaneously send messages over ESP-NOW.

I don't mind using a mode where a button is pressed and Wifi is only then enabled but switching wifi on and off seems to have intermittent success.

I have tried setting the channels to the same on both boards but this does not work.

In the example below I have stripped all the OTA code out and the code needed for ESP-NOW and just the line for WIFI enable

WiFi.begin(ssid, password);

which when enabled causes the delivery to fail.

Here is my Sender Code:

        #include <esp_now.h>
        #include <WiFi.h>
        #include <Wire.h>
        #define ssid "MYNETWORKSSID"
        #define password "mynetworkpassword"
        
         const int sNine = 33;
        
         #define CHAN_AP 2
        
        
        uint8_t broadcastAddress[] = {0x24, 0x62, 0xAB, 0xDC, 0x70, 0x90};
        int hall;
        
        String success;
        
        typedef struct struct_message {
            int hall;
        } struct_message;
        struct_message hallReadings;
        
        
        // Callback when data is sent
        void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
          Serial.print("\r\nLast Packet Send Status:\t");
          Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
          if (status ==0){
            success = "Delivery Success :)";
          }
          else{
            success = "Delivery Fail :(";
          }
        }
        
        void setup() {
          // Init Serial Monitor
          Serial.begin(115200);
          WiFi.mode(WIFI_STA);
         WiFi.begin(ssid, password); // PROBLEMATIC LINE
    
          // Init ESP-NOW
          if (esp_now_init() != ESP_OK) {
            Serial.println("Error initializing ESP-NOW");
            return;
          }
          // Once ESPNow is successfully Init, we will register for Send CB to
          // get the status of Trasnmitted packet
          esp_now_register_send_cb(OnDataSent);
        
          // Register peer
          esp_now_peer_info_t peerInfo;
          memcpy(peerInfo.peer_addr, broadcastAddress, 6);
          peerInfo.channel = CHAN_AP;
          peerInfo.encrypt = false;
        
          // Add peer
          if (esp_now_add_peer(&peerInfo) != ESP_OK){
            Serial.println("Failed to add peer");
            return;
          }
        }
        
        void loop() {
          // getReadings();
        
           hallReadings.hall = analogRead(sNine);
        
          esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &hallReadings, sizeof(hallReadings));
        
          if (result == ESP_OK) {
            Serial.println("Sent with success");
          }
          else {
            Serial.println("Error sending the data");
          }
          delay(100);
        }

Here is my Receiver code:

#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>

 const int sNine = 15;


//Wi-Fi channel (must match the gateway wi-fi channel as an access point)
#define CHAN_AP 2


// Define variables to store incoming readings
int incomingHall;

//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
    int hall;
} struct_message;

// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;

void updateDisplay(){

  Serial.print(incomingReadings.hall);
}

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
  incomingHall = incomingReadings.hall;
}

void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

  updateDisplay();
  delay(100);
}
2
  • what is your specific question? – jsotola Aug 7 '20 at 3:11
  • How can I have OTA enabled on both boards and also use ESP-now? when I activate wifi ESPnow stops working. Thanks! – Jaspal Singh Rathour Aug 7 '20 at 15:50
2

If you want to switch the softAP connection On/OFF you can do like StefanL38 suggests and have the Receiver transmit a ESP-NOW message with a value to the Sender, but you don't need a reboot. You can drop softAP and come up as STA or vise versa, for example.

    if(incomingid == 3){
      incomingValue = incomingReadings.Value;

      // to allow OTA, using Elegant OTA, haven't tried others.
          
    if(incomingValue == 1){
      WiFi.softAP(ssid,password,6);
      Serial.print("Connecting to ESP32 SSID ");
      Serial.println(ssid);  
      IPAddress IP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(IP);
      WiFi.printDiag(Serial);
    }

      // to disconnect and allow ESP-NOW via Station mode.

   else if(incomingValue == 0){
      WiFi.softAPdisconnect(true);
      delay(1000);
      WiFi.mode(WIFI_STA);
      delay(1000);
      WiFi.printDiag(Serial); // STA Defaults to channel 1
      esp_wifi_set_promiscuous(true);
      esp_wifi_set_channel(6, WIFI_SECOND_CHAN_NONE); // channel 6 setup
      esp_wifi_set_promiscuous(false);
      WiFi.printDiag(Serial);
    }
  }
2

I do something similar on a ESP8266 retrieving time from a NTP-server. Though it is just a "work around".

  • I connect to the router retrieving the NTP-time.
  • storing the time-information into RTC-RAM including a flag that indicates "time received"
  • then do a software-RESET
  • the setup-function checks this flag to decide if the ESP8266 shall connect to the router or shall keep WiFi OFF and activate ESP-NOW

if you want to use this for OTA it could "work" like this

sending a special ESP-NOW-Message initiating setting a flag "do_OTA" in RTC-RAM and then re-boot the setup-function looks for this flag "do_OTA" to be set does what its name says clearing the "do_OTA"-flag

What I don't know is writing new code into flash is a different thing than just re-booting through a software-reset. So maybe the content of the RTC-RAM gets lost through the update-process.

If so you could write the flag into flash using LittleFS

best regards Stefan

2

Another method that works if you don't mind having both at the same time:

Instead of WiFi.begin(ssid, password); I use WiFi.softAp(ssid,password,channel); for both Sender and Receiver.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.