1

I have 3 nodemcu's(ESP32) each connected with a sensor, from which I get data and send it to aws IoT-core. How can I send all 3 sensor's data by a single MQTT subscription? The below code is for a single MQTT using one nodemcu.

#include "SPIFFS.h"
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <PubSubClient.h>

float V_0 = 5.0; // supply voltage to the pressure sensor
float rho = 1.204; // density of air 

// parameters for averaging and offset
int offset = 0;
int offset_size = 10;
int veloc_mean_size = 20;
int zero_span = 2;

const char* ssid = ""; //Provide your SSID
const char* password = "";          // Provide Password
const char* mqtt_server = "a3mtl8k0aiowyx-ats.iot.us-east-2.amazonaws.com"; // Replace with your MQTT END point
const int mqtt_port = 8883;

String Read_rootca;
String Read_cert;
String Read_privatekey;
//=============================================================================================================================
#define BUFFER_LEN  256
long lastMsg = 0;
char msg[BUFFER_LEN];
int value = 0;
byte mac[6];
char mac_Id[18];
int count = 1;
int id=1;
//=============================================================================================================================

WiFiClientSecure espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP32-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish("ei_out", "connection success");
      // ... and resubscribe
      client.subscribe("ei_in");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
    for (int ii=0;ii<offset_size;ii++){
    offset += analogRead(34)-(1023/2);
  }
  offset /= offset_size;
  Serial.setDebugOutput(true);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(2, OUTPUT);
  setup_wifi();
  delay(1000);
  //=============================================================
  if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  //=======================================
  //Root CA File Reading.
  File file2 = SPIFFS.open("/AmazonRootCA1.pem", "r");
  if (!file2) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("Root CA File Content:");
  while (file2.available()) {
    Read_rootca = file2.readString();
    Serial.println(Read_rootca);
  }
  //=============================================
  // Cert file reading
  File file4 = SPIFFS.open("/9bcef01134-certificate.pem.crt", "r");
  if (!file4) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("Cert File Content:");
  while (file4.available()) {
    Read_cert = file4.readString();
    Serial.println(Read_cert);
  }
  //=================================================
  //Privatekey file reading
  File file6 = SPIFFS.open("/9bcef01134-private.pem.key", "r");
  if (!file6) {
    Serial.println("Failed to open file for reading");
    return;
  }
  Serial.println("privateKey File Content:");
  while (file6.available()) {
    Read_privatekey = file6.readString();
    Serial.println(Read_privatekey);
  }
  //=====================================================
  char* pRead_rootca;
  pRead_rootca = (char *)malloc(sizeof(char) * (Read_rootca.length() + 1));
  strcpy(pRead_rootca, Read_rootca.c_str());

  char* pRead_cert;
  pRead_cert = (char *)malloc(sizeof(char) * (Read_cert.length() + 1));
  strcpy(pRead_cert, Read_cert.c_str());

  char* pRead_privatekey;
  pRead_privatekey = (char *)malloc(sizeof(char) * (Read_privatekey.length() + 1));
  strcpy(pRead_privatekey, Read_privatekey.c_str());

  Serial.println("================================================================================================");
  Serial.println("Certificates that passing to espClient Method");
  Serial.println();
  Serial.println("Root CA:");
  Serial.write(pRead_rootca);
  Serial.println("================================================================================================");
  Serial.println();
  Serial.println("Cert:");
  Serial.write(pRead_cert);
  Serial.println("================================================================================================");
  Serial.println();
  Serial.println("privateKey:");
  Serial.write(pRead_privatekey);
  Serial.println("================================================================================================");

  espClient.setCACert(pRead_rootca);
  espClient.setCertificate(pRead_cert);
  espClient.setPrivateKey(pRead_privatekey);

  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  //====================================================================================================================
  WiFi.macAddress(mac);
  snprintf(mac_Id, sizeof(mac_Id), "%02x:%02x:%02x:%02x:%02x:%02x",
       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print(mac_Id);
  //=====================================================================================================================
}


void loop() {
    float adc_avg = 0;
    float veloc = 0.0;
  
// average a few ADC readings for stability
  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg+= analogRead(34)-offset;
  }
  adc_avg/=veloc_mean_size;
  
  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg>512-zero_span and adc_avg<512+zero_span){
  } else{
    if (adc_avg<512){
      veloc = -sqrt((-10000.0*((adc_avg/1023.0)-0.5))/rho);
    } else{
      veloc = sqrt((10000.0*((adc_avg/1023.0)-0.5))/rho);
    }
  }
//  Serial.println(veloc); // print velocity
//  delay(10); // delay for stability
  //===============================================

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 5000) {
    lastMsg = now;
    //=============================================================================================
    //String macIdStr = mac_Id;
    String sensor_id=String(id);
    String Velocity = String(veloc);
    snprintf (msg, BUFFER_LEN, "{\"sensor_id\" : \"%s\", \"Velocity\" : \"%s\"}", sensor_id.c_str(), Velocity.c_str());
    //"{\"mac_Id\" : \"%s\", \"Velocity\" : %s, \"sensor_id\" : \"%s\"}"
    Serial.print("Publish message: ");
    Serial.print(count);
    Serial.println(msg);
    client.publish("ei_out", msg);
    count = count + 1;
    //================================================================================================
  }
  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

ei_out is the topic I have subscribed in iot-core, I wish to have one more ei_out_1 from another nodemcu

5
  • ei_out is the topic I have subscribed in iot-core, I wish to have one more ei_out_1 from another nodemcu -- So... have another called ei_out_1...? I don't understand what you're asking. If you want to send to a different topic then send to a different topic.
    – Majenko
    May 1, 2021 at 12:52
  • How can I send all 3 sensor's data by a single MQTT subscription? .... same way that you would place three words on one piece of paper? .... BTW, data is sent by publishing, subscription is for receiving data
    – jsotola
    May 1, 2021 at 15:45
  • You're not subscribing to ei_out but only to a topic called ei_in (defined in reconnect()). What you want is to publish. At the moment, you're using only ei_out to publish (client.publish("ei_out") in loop()). You can freely create additional topics (with different names than "ei_out") to publish data from other sensors.
    – StarCat
    May 1, 2021 at 17:26
  • Publishing has to have an explicit topic. Subscribing has two wild cards # which means anything below this level in the hierarchy and + which means anything at the next level of the hierarchy. The division between hierarchical levels is the / character. So if sensor one publishes on sensor/1/out/temp1 and sensor two publishes on sensor/2/out/temp1 you can subscribe to sensor/+/out/temp1 to read from both sensors. You can subscribe on sensor/1/out/+ to read anything sent by sensor one. You can subscribe to sensor/# to read any output from any sensor.
    – Dougie
    May 2, 2021 at 13:52
  • change ei_out and ei_out_1 to ei/out and ei/out/1 to get the benefits of the hierarchical topic structure. The only hard part of this stuff is designing a sensible and coherent hierarchy for your topics.
    – Dougie
    May 2, 2021 at 13:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.