Wemos D1 Mini - communication to Wemos D1 Minis - wireless

Hi,

the question here is, what is an easy fix of having 8 wemos (or similar) talking to each other, without a cable.

I've got a master Wemos that has buttons, if a button is pressed a servo on another wemos should rotate.

What kind of communication would suit here best?

Adding here a picture

thanks for advice and maybe a link to a tutorial for setting up such a connection.

Use a GND wire and a Wemos master digital output conncted to an input of the other controllers.

1 Like

the communication between the button-wemos and the servo-wemos should be wirefree

Another way would be to use http. The wemos with servos each act as a server. The wemos with the buttons acts as the client. When a button is pressed, the client wemos sends an http request to the wemos with the servo.

The wemos can all join a local wi-fi network in your home/school, or one of the wemos (probably the one with the buttons) can act as an Access point and create a network for the others to join.

some alternatives

  1. ESP-NOW as suggested by @UKHeliBob - have a look at Basic controller, slave with ESP-NOW
  2. you could run a TCP server on one of the devices - the other devices connect TCP clients to it
  3. use UDP datagrams to pass data between the devices - even use UDP multicast

thanks, esp-now seems to be a good start.

esp-now vs UDP, which would you recommend?

probably ESP-NOW is the simplests and quickest approach
you also get confirmation of recipt which you don't by defult with UDP

ESP-Now sounds like a good way to go.

here is another tutorial that might be handy

I have managed to connect the esp now controller a nodemcu HW to 2 slaves successfully. I want to integrate my app to my program, which is required to activate LEDs according to commands broadcast to the slaves. Will be helpful for any guidance. Thanks

Where are you stuck ?

If you have got the two systems communicating then you can send a command from one to the other and having received the command, test its value and act on it

the command I send is received but the program does not execute. thats my problem.
thanks.

Post the code of both your transmitter and receiver so that we can see what you are doing

The Controller code.

#include <ESP8266WiFi.h>
#include <espnow.h>

uint8_t broadcastAddress1[] = {0x3C, 0x61, 0x05, 0xD4, 0xDE, 0xF6};//
uint8_t broadcastAddress2[] = {0xEC, 0xFA, 0xBC, 0x5F, 0x73, 0x29}; //



// Structure example to send data
// Must match the receiver structure

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

// Create a struct_message called myData
struct_message myData;

unsigned long lastTime = 0;
unsigned long timerDelay = 2000;  // send readings timer

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0) {
    Serial.println("Delivery success");
  }
  else {
    Serial.println("Delivery fail");
  }
}

void setup() {
  // Init Serial Monitor
  Serial.begin(115200);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("ESP8266 Board MAC Address:  ");
  Serial.println(WiFi.macAddress());

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    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_set_self_role(ESP_NOW_ROLE_CONTROLLER);
  esp_now_register_send_cb(OnDataSent);

  // Register peer
  esp_now_add_peer(broadcastAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  esp_now_add_peer(broadcastAddress2, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  Serial.setTimeout(1000000L);    // set so Serial.readString() won't timeout
}

void loop() {
  if ((millis() - lastTime) > timerDelay) {
   
    Serial.print("  ");
    myData.d = Serial.readStringUntil('\n');     // <<<< read string
    
    // Send message via ESP-NOW
    esp_now_send(broadcastAddress1, (uint8_t *) &myData, sizeof(myData));
    esp_now_send(broadcastAddress2, (uint8_t *) &myData, sizeof(myData));

    lastTime = millis();
  }

}

post the code of the receiver?

The Receiver code

#include <BufferedInput.h>
#include <BufferedOutput.h>
#include <loopTimer.h>
#include<ESP8266WiFi.h>
#include<espnow.h>
#include <PinFlasher.h>
#include <SafeString.h>
#include <SafeStringReader.h>
#include <SafeStringStream.h>
#include <SerialComs.h>
#include <SafeString.h>
struct __attribute__((packed)) dataPacket {
char a[32]; 
};
const byte maxRcvdBytes = 10;

// personal naming-convention suffix _SS indicates a S)afe-S)tring
createSafeString(newCommand_SS, (maxRcvdBytes) ); //+1 for the terminating zero
createSafeString(Command_SS,    (maxRcvdBytes) );

const byte Red   = 12;
const byte Green = 14;
const byte Blue  = 16;

const char endChar = 0x0D; // carriage return is hex-value 0D and is used as the terminating byte

int idx = 0;
char rcvdChar;
void dataReceived(uint8_t *senderMac, uint8_t *data, uint8_t dataLength) {
  char macStr[18];
  dataPacket packet;  

  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", senderMac[0], senderMac[1], senderMac[2], senderMac[3], senderMac[4], senderMac[5]);

  Serial.println();
  Serial.print("Received data from: ");
  Serial.println(macStr);
  
  memcpy(&packet, data, sizeof(packet));
  
 // Serial.print("sensor1: ");
  
}


void setup() {
  pinMode(12,  OUTPUT);
  pinMode(14,OUTPUT);
  pinMode(16, OUTPUT);

  Command_SS = "off";
  newCommand_SS = "";
  Serial.begin(115200);
 Serial.println();
  Serial.println();
  Serial.println();
  Serial.print("Initializing...");
  
  Serial.print("My MAC address is: ");
  Serial.println(WiFi.macAddress());

  WiFi.mode(WIFI_STA);
  if(esp_now_init() != 0) {
    Serial.println("ESP-NOW initialization failed");
    return;
  }

  esp_now_register_recv_cb(dataReceived);   // this function will get called once all data is sent

  Serial.println("Initialized.");
}

  



void readFromSerial() {
  while (Serial.available() > 0)  {
    char rcvdChar = Serial.read();
    // for debuging purposes uncomment these lines
    //to see each received character in the serial monitor
    
      Serial.print("reveived #");
      Serial.print(rcvdChar);
      Serial.println("#");
    

    if ( (rcvdChar == endChar) ) { // End of input or max Command_SS-length reached

      Command_SS = newCommand_SS;
      newCommand_SS = "";

      Serial.print("Command_SS received: ");
      Serial.println(Command_SS);

      idx = 0;
    }
    else {
      newCommand_SS += rcvdChar; // add new received char to SafeString
      idx++;
    }
  }
}

void setLights() {
  

  if (Command_SS == "dog")
  {
  digitalWrite(14, HIGH);
   delay(1000);
    digitalWrite(14, LOW);
    delay(500);
  digitalWrite(16, HIGH);
  delay(1000);
  digitalWrite(16, LOW);
delay (2000);
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);
  delay(1000);
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);              
 exit(0);
  }
  if (Command_SS == "cat")
  {
  digitalWrite(16, HIGH);
   delay(1000);
    digitalWrite(16, LOW);
    delay(500);
  digitalWrite(14, HIGH);
  delay(1000);
  digitalWrite(14, LOW);
delay (2000);
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);
  delay(1000);
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);              
 exit(0);
  }
  if (Command_SS == "goat")
  {
  digitalWrite(14, HIGH);
   delay(1000);
    digitalWrite(14, LOW);
    delay(500);
  digitalWrite(14, HIGH);
  delay(1000);
  digitalWrite(14, LOW);
delay (2000);
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);
  delay(1000);
  digitalWrite(16, HIGH);
  delay(500);
  digitalWrite(16, LOW);
  delay(500); 
  digitalWrite(14, HIGH);
  delay(500);
  digitalWrite(14, LOW);
  delay(1000);             
 exit(0);
  }

}


void loop() {
  readFromSerial();



  setLights();
}

can you show a sample Serial Monitor output of the sender and the receiver?
why have you

exit(0);

in loop()?


I added exit in loop to stop the serial after executing command once

your command "dog" is being received as three seperate bytes
in receiver try

void readFromSerial() {
  while (Serial.available() > 0)  {
    char rcvdChar = Serial.readStringUntil('\n');

in the sender you will probably have add the '\n' back in
also print the result so you know what you are sending, e.g.

void loop() {
  if ((millis() - lastTime) > timerDelay) { 
    Serial.print("  ");
    myData.d = Serial.readStringUntil('\n')+"\n";     // <<<< read string
    Serial.println(myData.d);

did not compile with this error result