So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By 1CM69
#83404 Hi all,

I have a number of sensors (Masters) taking readings at set intervals & they send the readings via ESP-Now to my Slave unit.
This all works perfectly, I can see it all happening via the serial monitor of my Slave unit.

Now I wish to send these readings up to Adafruit Io & ThingSpeak at the same time from my Slave unit but I have tried over & over in placing the Adafruit & ThingSpeak code in my sketch but it does nothing.

Here is my full Slave unit sketch, I have starred out personal details.
Code: Select all/*
 Testing ESP-Now
 See https://espressif.com/en/products/software/esp-now/overview
 ESP-Now enables fast lightwieght connectionless communication between ESP8266's.
 So for example a remote sensor node could send a reading using ESP-Now in just a few
 hundred milliseconds and deepSleep the rest of the time and so get increased battery
 life compared to the node using a regular WiFi connection which could take 10 times
 as long to connect to WiFi and send a sensor reading.
 
 ESP-Now has the concept of controllers and slaves. AFAICT the controller is the remote
 sensor node and the slave is the always on "gateway" node that listens for sensor node readings.
 *** Note: to compile ESP-Now (with arduino/esp8266 release 2.3.0) need to edit
 * ~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/platform.txt
 * Search "compiler.c.elf.libs", and append "-lespnow" at the end of the line.
 * See: http://www.esp8266.com/viewtopic.php?p=44161#p44161
 ***
 **** This skecth is the slave/gateway node ****
 Ant Elder
 License: Apache License v2
*/
#include <ESP8266WiFi.h>
#include "ThingSpeak.h" //FOR THINGSPEAK
#include "AdafruitIO_WiFi.h" //FOR ADAFRUIT

unsigned long myChannelNumber = 842555; //FOR THINGSPEAK
const char * myWriteAPIKey = "******"; //FOR THINGSPEAK


extern "C" {
  #include <espnow.h>
}

const char* ssid = "******";
const char* password = "******";

#define AIO_USERNAME    "******" //FOR ADAFRUIT
#define AIO_KEY         "******" //FOR ADAFRUIT

AdafruitIO_WiFi io(AIO_USERNAME, AIO_KEY, ssid, password); //FOR ADAFRUIT

AdafruitIO_Feed *BedroomTempFeed = io.feed("bedroom"); //FOR ADAFRUIT

#define WIFI_CHANNEL 1

// keep in sync with sensor struct
struct SENSOR_DATA_DHT22 {
    String name_dht22;
    float temp_dht22;
    int hum_dht22;
    float t_dht22;
};

struct SENSOR_DATA_DS18B20_1 {
    String name_ds18b20_1;
    float temp_ds18b20_1;
    float t_ds18b20_1;
};

struct SENSOR_DATA_DS18B20_2 {
    String name_ds18b20_2;
    float temp_ds18b20_2;
    float t_ds18b20_2;
};

WiFiClient  client; //FOR THINGSPEAK

void setup() {
  Serial.begin(115200); Serial.println();

  ThingSpeak.begin(client); //FOR THINGSPEAK
     
  initWifi();

  io.connect(); //FOR ADAFRUIT

  if (esp_now_init()!=0) {
    Serial.println("*** ESP_Now init failed");
    ESP.restart();
  }

  Serial.print("This node AP mac: "); Serial.print(WiFi.softAPmacAddress());
  Serial.print(", STA mac: "); Serial.println(WiFi.macAddress());

  // Note: When ESP8266 is in soft-AP+station mode, this will communicate through station interface
  // if it is in slave role, and communicate through soft-AP interface if it is in controller role,
  // so you need to make sure the remote nodes use the correct MAC address being used by this gateway.
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_dht22, uint8_t len) {
    Serial.print("recv_cb, from mac: ");
    char macString[50] = {0};
    sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    Serial.print(macString);
   
    getReading_DHT22(data_dht22, len);
  });

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_1, uint8_t len) {
    Serial.print("recv_cb, from mac: ");
    char macString[50] = {0};
    sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    Serial.print(macString);
   
    getReading_DS18B20_1(data_ds18b20_1, len);
   
  });

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_2, uint8_t len) {
    Serial.print("recv_cb, from mac: ");
    char macString[50] = {0};
    sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    Serial.print(macString);
     
    getReading_DS18B20_2(data_ds18b20_2, len);
  });

}

void loop() {}

void getReading_DHT22(uint8_t *data_dht22, uint8_t len) {
  SENSOR_DATA_DHT22 tmp_dht22;
  memcpy(&tmp_dht22, data_dht22, sizeof(tmp_dht22));

  Serial.print(", parsed data, t="); Serial.println(tmp_dht22.t_dht22);
  Serial.print(tmp_dht22.name_dht22); Serial.print(" Temperature = "); Serial.print(tmp_dht22.temp_dht22); Serial.println("\u2103");
  Serial.print(tmp_dht22.name_dht22); Serial.print(" Humidity = "); Serial.print(tmp_dht22.hum_dht22); Serial.println("%");
}

void getReading_DS18B20_1(uint8_t *data_ds18b20_1, uint8_t len) {
 
  SENSOR_DATA_DS18B20_1 tmp_ds18b20_1;
  memcpy(&tmp_ds18b20_1, data_ds18b20_1, sizeof(tmp_ds18b20_1));
  io.run(); //FOR ADAFRUIT
  BedroomTempFeed->save(tmp_ds18b20_1.temp_ds18b20_1); //FOR ADAFRUIT
  ThingSpeak.writeField(myChannelNumber, 1, tmp_ds18b20_1.temp_ds18b20_1, myWriteAPIKey); //FOR THINGSPEAK
  Serial.print(", parsed data, t="); Serial.println(tmp_ds18b20_1.t_ds18b20_1);
  Serial.print(tmp_ds18b20_1.name_ds18b20_1); Serial.print(" Temperature = "); Serial.print(tmp_ds18b20_1.temp_ds18b20_1); Serial.println("\u2103");
}

void getReading_DS18B20_2(uint8_t *data_ds18b20_2, uint8_t len) {
  SENSOR_DATA_DS18B20_2 tmp_ds18b20_2;
  memcpy(&tmp_ds18b20_2, data_ds18b20_2, sizeof(tmp_ds18b20_2));
 
  Serial.print(", parsed data, t="); Serial.println(tmp_ds18b20_2.t_ds18b20_2);
  Serial.print(tmp_ds18b20_2.name_ds18b20_2); Serial.print(" Temperature = "); Serial.print(tmp_ds18b20_2.temp_ds18b20_2); Serial.println("\u2103");
}

void initWifi() {

  WiFi.mode(WIFI_AP_STA);
 
  WiFi.softAP("MyGateway", "12345678", WIFI_CHANNEL, 1);

  Serial.print("Connecting to "); Serial.print(ssid);
  if (strcmp (WiFi.SSID().c_str(), ssid) != 0) {
      WiFi.begin(ssid, password);
   }
 
  int retries = 20; // 10 seconds
  while ((WiFi.status() != WL_CONNECTED) && (retries-- > 0)) {
     delay(500);
     Serial.print(".");
  }
  Serial.println("");
  if (retries < 1) {
     Serial.print("*** WiFi connection failed"); 
     ESP.restart();
  }

  Serial.print("WiFi connected, IP address: "); Serial.println(WiFi.localIP());
}


Any help would be appreciated.

Kirk
User avatar
By 1CM69
#83410 I have solved this now, I had to completely re-engineer my code based on the Master & Slave sketches by

Andreas Spiess - The Guy With The Swiss Accent, his code: https://github.com/SensorsIot/ESP-Now-Tests

My Slave code now looks like this:

Code: Select all#include <ESP8266WiFi.h>
#include "ThingSpeak.h"
#include "AdafruitIO_WiFi.h"
extern "C" {
  //#include "user_interface.h"
  #include <espnow.h>
}

const char* ssid = "******"; //Starred out for security
const char* password = "******"; //Starred out for security

WiFiClient client;

unsigned long myChannelNumber =  ******; //Starred out for security
const char * myWriteAPIKey = "******"; //Starred out for security

#define AIO_USERNAME    "******" //Starred out for security
#define AIO_KEY         "******" //Starred out for security
const char* xssid = ""; //Purposely leave blank
const char* xpassword = ""; //Purposely leave blank

AdafruitIO_WiFi io(AIO_USERNAME, AIO_KEY, xssid, xpassword);

AdafruitIO_Feed *BedroomTempFeed = io.feed("bedroom");

// keep in sync with ESP_NOW sensor struct
struct SENSOR_DATA_DS18B20_1 {
    String name_ds18b20_1;
    float temp_ds18b20_1;
} sensorData_DS18B20_1;

volatile boolean haveReading = false;

int heartBeat;

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  Serial.println("ESP_Now Controller");
    Serial.println();

  WiFi.mode(WIFI_AP);
  Serial.print("This node AP mac: "); Serial.println(WiFi.softAPmacAddress());
  Serial.print("This node STA mac: "); Serial.println(WiFi.macAddress());

  initEspNow(); 
  Serial.println("Setup done");
}

void loop() {
 
  if (millis()-heartBeat > 30000) {
    Serial.println("Waiting for ESP-NOW messages...");
    heartBeat = millis();
  }

  if (haveReading) {
    haveReading = false;
    ThingSpeak.begin(client);
    wifiConnect();
    sendToThingSpeak();
    sendToAdafruit();
    delay(200);
    ESP.restart(); // <----- Reboots to re-enable ESP-NOW
  }
}

void sendToThingSpeak() {
  ThingSpeak.writeField(myChannelNumber, 1, String(sensorData_DS18B20_1.temp_ds18b20_1), myWriteAPIKey);
}

void sendToAdafruit() {
  io.run();
  BedroomTempFeed->save(String(sensorData_DS18B20_1.temp_ds18b20_1));
}

void initEspNow() {
  if (esp_now_init()!=0) {
    Serial.println("*** ESP_Now init failed");
    ESP.restart();
  }

  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_1, uint8_t len) {

    char macString[50] = {0};
    sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
   
    memcpy(&sensorData_DS18B20_1, data_ds18b20_1, sizeof(sensorData_DS18B20_1));

    Serial.print("Message received from device: "); Serial.print(macString);
    Serial.printf(" Temp = %0.2f", sensorData_DS18B20_1.temp_ds18b20_1); Serial.print("\u2103");
    Serial.println();
//    Serial.printf(" Temp=%0.1f, Hum=%0.0f%%, pressure=%0.0fmb\n",
//       sensorData.temp, sensorData.humidity, sensorData.pressure);   

    haveReading = true;
  });
}

void wifiConnect() {
  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("Connecting to "); Serial.print(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
     delay(250);
     Serial.print(".");
  } 
  Serial.print("\nWiFi connected, IP address: "); Serial.println(WiFi.localIP());
  //io.connect();
}


Regards..,

Kirk