Includes:

Features:

____________________________________
(                                    )
|                                    |
(            Internet                )
|                                    |
(____________________________________)
                     ^
                     |MQTT
                     |
+--------------------|-------+
| RaspberryPi        V       |
|-------------+   +--+-------|
| MeshGateway |<->| MQTT     |     +-------------------------------------+
|             |   | broker   |     |    ESPNOW mesh network              |
+-----+-------+---+----------+     |                             Node6   |
      ^                            |     Node1        Node3              |
      |    USB(SerialData)         |  +------------+   Node3     Node5   |
      +------------------------------>| USBAdapter |           Node4     |
                                   |  | (Master)   |  NodeX    Node7     |
                                   |  +------------+                     |
                                   +-------------------------------------+

Flooding mesh network

In this network example ttl must be >= 5

               SlaveNode
                   |
                   |         Message from master to BatteryNode
                   |   ---------------------------+
                   | ttl=5               ttl=4    |
SlaveNode-------MasterNode-------------SlaveNode  |
                   |                     |        |
                   |                     |        |
                   |                     |        |
                   |                     |        |
               SlaveNode                 |        |
                   |                     |        |
                   |                     |        |
                   |                     |        +------------------------------------------------>
                   |                     | ttl=3         ttl=2              ttl=1
SlaveNode-------SlaveNode-------------SlaveNode-------SlaveNode-------------SlaveNode---------BatteryNode
   |               |                     |
   |               |                     |
   |               |                     |
   |               |                     |
   +-----------SlaveNode-----------------+

Message relay

The Master sends a request to the farthest node and the farthest node replies. 

alt text

Arduino libraries (dependencies):

Slave Node examples

Early demo video

Mesh usb adapter

Mesh slave node codes

MeshGateway software for RaspberryPi (conversation between mesh and mqtt broker)

Slave node code example

Slave node updates the button's state to topic device1/switch/led/value. The led state can be controlled with topic device1/switch/led/set on/off.

#include <EspNowFloodingMesh.h>
#include<SimpleMqtt.h>

/********NODE SETUP********/
#define ESP_NOW_CHANNEL 1
const char deviceName[] = "device1";
unsigned char secredKey[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
unsigned char iv[16] = {0xb2, 0x4b, 0xf2, 0xf7, 0x7a, 0xc5, 0xec, 0x0c, 0x5e, 0x1f, 0x4d, 0xc1, 0xae, 0x46, 0x5e, 0x75};
const int ttl = 3;
const int bsid = 0x112233;
/*****************************/

#define LED 1
#define BUTTON_PIN 2

SimpleMQTT simpleMqtt = SimpleMQTT(ttl, deviceName);

bool setLed;
bool ledValue;

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

  pinMode(LED, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  espNowFloodingMesh_secredkey(secredKey);
  espNowFloodingMesh_setAesInitializationVector(iv);
  espNowFloodingMesh_setToMasterRole(false, ttl);
  espNowFloodingMesh_begin(ESP_NOW_CHANNEL, bsid);

  espNowFloodingMesh_ErrorDebugCB([](int level, const char *str) {
    Serial.print(level); Serial.println(str); //If you want print some debug prints
  });


  if (!espNowFloodingMesh_syncWithMasterAndWait()) {
    //Sync failed??? No connection to master????
    Serial.println("No connection to master!!! Reboot");
    ESP.restart();
  }

  //Handle MQTT events from master. Do not call publish() inside of call back. --> Endless event loop and crash
  simpleMqtt.handleEvents([](const char *topic, const char* value) {
    simpleMqtt._ifSwitch(VALUE, "led", [](MQTT_switch value){ //<--> Listening topic switch/led/value/value
      if(value==SWITCH_ON) {
        ledValue = true;
      }
      if(value==SWITCH_OFF) {
        ledValue = false;
      }
    });
    simpleMqtt._ifSwitch(SET, "led", [](MQTT_switch set){ //<-->Listening topic device1/switch/led/set
      if(set==SWITCH_ON) {
        setLed = true;
      }
      if(set==SWITCH_OFF) {
        setLed = false;
      }
    });
  });

  if (!simpleMqtt._switch(SUBSCRIBE, "led")) { //Subscribe topic device1/switch/led/set and get topic device1/switch/led/value from cache
    Serial.println("MQTT operation failed. No connection to gateway");
  }
}

bool buttonStatechange = false;

void loop() {
  espNowFloodingMesh_loop();

  int p = digitalRead(BUTTON_PIN);

  if (p == HIGH && buttonStatechange == false) {
    buttonStatechange = true;
    setLed = true;
  }
  if (p == LOW && buttonStatechange == true) {
    buttonStatechange = false;
    setLed = false;
  }

  if (ledValue == true && setLed == false) {
    ledValue = false;
    Serial.println("LED_OFF");
    //digitalWrite(LED,HIGH);
    if (!simpleMqtt._switch(PUBLISH, "led", SWITCH_OFF)) { //publish topic device1/switch/led/value off
      Serial.println("Publish failed... Reboot");
      Serial.println(ESP.getFreeHeap());
      ESP.restart();
    }
  }

  if (ledValue == false && setLed == true) {
    ledValue = true;
    Serial.println("LED_ON");
    if (!simpleMqtt._switch(PUBLISH, "led", SWITCH_ON)) { //publish topic device1/switch/led/value on
      Serial.println("Publish failed... Reboot");
      Serial.println(ESP.getFreeHeap());
      ESP.restart();
    }
  }

  delay(100);
}

Config file for MeshGateway on RasperryPi

module.exports = {
  "usbPort": "/dev/ttyUSB0",
  "mesh": {
    "secredKey": [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
    "ttl": 3,
    "channel": 1
  },
  "dbCacheFile":"./cache.json",
  "mqtt": {
    "host": "mqtt://localhost",
    "root": "mesh/"
  }
}