How to have 1 esp8266 send data to a 2nd esp8266 and display it on lcd

I have a arduino nano in the trunk of my car that reads a sensor and controls a pwm driver based on that input. I would like to display the output spped onto a lcd that I can see in the driver seat but I don't want to run multiple wires or even a single wire through my car. I have 2 esp8266 wifi boards link and I have one of these lcd displays, link.

I want to send a voltage value from the nano to one of the esp8266 between 0-3.3v to display the output readings. I plan on using a map function to convert the voltage range to display the correct output reading. I just don't know how to go about having the first esp8266 send data to the 2nd esp8266 and then having that board display it on a lcd screen. I can't find any tutorials that are similar enough to get me started on this project.

ESP-NOW is one way for 2 ESPs to talk to one another.

here is a demo-code that shows the principle use of ESP-NOW.

ESP-NOW is very good suited for your purpose because it works without the use of a WLAN-router
and the transimission does not need any kind of process of a “register in WLAN”
Just send the bytes you want to send to the MAC-adress of the receiver.

Send/receive data with the ESP-NOW-protocol is a bit more complex than blinking a LED
You have to do several things to make it work. The MAC-Adresses have to be adjusted inside your code.

This demo-code has some comments and does serial-output that will help understand how it all works.
Though you have to do additional reading and/or asking questions .

#include <ESP8266WiFi.h> // for use with ESP32 use file "WiFi.h"
#include <espnow.h>      // for use with ESP32  use file "esp_now.h" (underline in the middle)
// don't try to adapt this code to ESP32-modules
// ESP32-modules need another library with SUBSTANTIAL differencies
// go search for a demo-code that is written for ESP32



// if you want to receive ESP-NOW-messages reliably you have to strictly avoid 
// the command delay(). Delay blocks the whole CPU and if a ESP-NOW-Message
// is send while the receivers CPU  is blocked the receiving will fail
// so use a timing-function based on millis() like the one below instead.
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}

unsigned long SendDataTimer;

//#############################################################################################
// list of MAC-Adresses of all receivers:

// important note: ESP-NOW sending is based on the RECEIVERS Mac-adress.
// this means for every ESP8266-modul that shall receive a ESP-NOW-Messages
// you have to execute register a peer in the Setup-function
// esp_now_add_peer(ESP_NOW_MAC_adr Of Recv, ESP_NOW_ROLE_COMBO, 1, NULL, 0); 

// and you have to execute the command 
// esp_now_send(ESP_NOW_MAC_adr Of Recv, (uint8_t *) &myESP_NOW_Data, sizeof(myESP_NOW_Data));
uint8_t ESP_NOW_MAC_adrOfRecv[] = { 0xF4, 0xCF, 0xA2, 0xD1, 0x3D, 0x28 }; // Board 0x06 sendet an Board 0x28

char MAC_adrOfRecv_as_AoC[18];

//##############################################################################################


// Structure example to send data. Must match the receiver structure
typedef struct MyESP_NOW_Data_type {
  char MyESP_NOW_MsgStr[128];
  int  MyESP_NOW_Int;
} MyESP_NOW_Data_type;

// Create a "variable" called myESP_NOW_Data of variable-type MyESP_NOW_Data_type
MyESP_NOW_Data_type my_received_ESP_NOW_Data;      //neu 2020.07.14-15:00
MyESP_NOW_Data_type my_READYtoSEND_ESP_NOW_Data;   //neu 2020.07.14-15:00

void ESP_NOW_SendData()
{
  // Set values to send
  strcpy(my_READYtoSEND_ESP_NOW_Data.MyESP_NOW_MsgStr, "HI I'M SENDING EVERY TWO SECONDS COUNTiNG UP + 6");
  my_READYtoSEND_ESP_NOW_Data.MyESP_NOW_Int = my_READYtoSEND_ESP_NOW_Data.MyESP_NOW_Int + 6; 

  // Send message via ESP-NOW  
  esp_now_send(ESP_NOW_MAC_adrOfRecv, (uint8_t *) &my_READYtoSEND_ESP_NOW_Data, sizeof(my_READYtoSEND_ESP_NOW_Data));
  Serial.println("esp_now_send(ESP_NOW_MAC_adrOfRecv, (uint8_t *) &my_READYtoSEND_ESP_NOW_Data, sizeof(my_READYtoSEND_ESP_NOW_Data)); done");
  Serial.print("I am the board with the MAC-Adress ");
  Serial.println(WiFi.macAddress()); 
  Serial.print("and I try to send my ESP-NOW-Data to the board with MAC-Adress ");
  Serial.println(MAC_adrOfRecv_as_AoC); 
  
  // if sending has finished function OnDataSent is called
}


void ESP_Now_setup()
{
  WiFi.mode(WIFI_STA);
  Serial.println("WiFi.mode(WIFI_STA); done");
  WiFi.disconnect(); // for strange reasons WiFi.disconnect() makes ESP-NOW work
  Serial.println("WiFi.disconnect(); done");
  
  // Init ESP-NOW
  if (esp_now_init() != 0) 
  {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  Serial.println("esp_now_init() was successful");

  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
  Serial.println("esp_now_set_self_role(ESP_NOW_ROLE_COMBO) done");

  esp_now_register_recv_cb(OnDataRecv);
  Serial.println("esp_now_register_recv_cb(OnDataRecv); done");
  
  esp_now_register_send_cb(OnDataSent);
  Serial.println("esp_now_register_send_cb(OnDataSent); done");
  
  // each receiving unit must be registered. Register peer
  esp_now_add_peer(ESP_NOW_MAC_adrOfRecv, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  Serial.println("esp_now_add_peer(MAC_adressOfReceivingUnit, ESP_NOW_ROLE_COMBO, 1, NULL, 0) done");  

  for (int i=0;i<6;i++) {
    strcat (MAC_adrOfRecv_as_AoC, hex02str(ESP_NOW_MAC_adrOfRecv[i])   );
    if (i < 6) {
      strcat (MAC_adrOfRecv_as_AoC, ":" );    
    }  
  }  
  MAC_adrOfRecv_as_AoC[17] = 0;
  strupr(MAC_adrOfRecv_as_AoC); // make letters UPPERCASE
  Serial.print("MAC-Adress of Receiver is ");
  Serial.println(MAC_adrOfRecv_as_AoC);
}

void PrintFileNameDateTime()
{
  Serial.print("Code running comes from file ");
  Serial.println(__FILE__);
  Serial.print("compiled ");
  Serial.print(__DATE__);
  Serial.println(__TIME__);  
}

// print macadress of THIS device 
// prepared for inserting code by copy & paste
// that will be flashed into receiving partner 

void PrintWiFiMacAdress()
{
  char MacAdr_AoC[18];  //suffix _AoC for easier remembering variable-type is ArrayOfChar
  char HexByteDigits[3];
  
  for (uint8_t i = 0; i < 18; i = i + 1)
  { 
    MacAdr_AoC[i] = WiFi.macAddress()[i];
  } 
  MacAdr_AoC[17] = 0; // zero to terminate the string
  Serial.print("ESP Board Wifi.macAddress:  ");
  Serial.println(MacAdr_AoC);
  
  Serial.println();
  Serial.println("copy the line below and replace the codeline");
  Serial.println("uint8_t ESP_NOW_MAC_adrOfRecv[] = { 0x60, 0x01, 0x94, 0x70, 0xAE, 0x7B };");
  Serial.println("inside the code with the copied line from the serial monitor");
   
  Serial.println();
  Serial.print("uint8_t ESP_NOW_MAC_adrOfRecv[] = {");
  for (uint8_t i = 0; i < 16; i = i + 3)
  { 
    HexByteDigits[0] = MacAdr_AoC[i];
    HexByteDigits[1] = MacAdr_AoC[i+1];
    HexByteDigits[2] = 0; // zero for terminating the string
    Serial.print("0x");
    Serial.print(HexByteDigits);
    if (i < 14) Serial.print(", ");
  }  
  Serial.println(" };");
  Serial.println();      
}

char* hex02str(uint8_t b)  {
 static char str[]="FF"; // RAM für einen 2-Zeichen string reservieren.
  snprintf(str,sizeof(str),"%02x",b);
  return str;
}


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

// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t NoOfBytesRcv) 
{ 
  // copy data bytewise from variable incomingData to variable myData
  memcpy(&my_received_ESP_NOW_Data, incomingData, sizeof(my_received_ESP_NOW_Data));

  //these lines must match the variables inside the ESP_NOW-data-structure
  Serial.print("No of Bytes received: ");
  Serial.println(NoOfBytesRcv);
  Serial.print("Array of Char: ");
  Serial.println(my_received_ESP_NOW_Data.MyESP_NOW_MsgStr);
  Serial.print("Int: ");
  Serial.println(my_received_ESP_NOW_Data.MyESP_NOW_Int);

  Serial.println();
}

 
void setup() 
{
  // Init Serial Monitor
  Serial.begin(115200);
  Serial.println();  // a carriage return to make sure serial-output begins in colum 1 of a new line
  PrintFileNameDateTime();
  // Set device as a Wi-Fi Station
  ESP_Now_setup();

  PrintWiFiMacAdress();  
}
 
void loop() 
{ 
  // check if timer-intervall is over
  if (TimePeriodIsOver(SendDataTimer,2000) )  //neu 2020.07.14-15:00
    {
     Serial.println("SendData");
     ESP_NOW_SendData();
     Serial.println("SendData done");
    }
}

best regards Stefan

additional comment:

As you use an Arduino nano as the microcontroller that reads a sensor and creates a PWM-signal. you have to connect the Arduino-nano to one ESP8266 through a serial-connection.

You could do this by using the hardware-serial-connection this means using the same serial connection as for uploading and debug-output. So only uploading OR serial-communication with the Arduino-nano is possible

or you use a software-serial-connection.

Another solotion is to let do the ESP8266 the sensor-reading and creating the PWM and sending data with ESP-NOW. the naked ESP8266-chip and some ESP8266-boards need a maximum of 1.0 Volt as analog-voltage-input. Some of them have a voltage-divider so they need 3.3V Please post the exact type of ESP8266 you are using.

If you haven't bought them yet I recommend considering buying two ESP32 modules type nodeMCU32 instead. $6 to $12 per board. ESP32 have multiple ADC-channels. An ESP8266 has only one ADC-channel.

With an ESP32 you need a different library for ESP-NOW. Not a problem. Just important to know.

best regards Stefan

I want to send a voltage value from the nano to one of the esp8266 between 0-3.3v to display the output readings.

as Stefan mentioned, you will need to communicate digitally between the nano & esp, analog is not going to work. a nodeMCU has only 1 ADC channel, because you usually only need 1 to read multiple sensors. Simply power the sensor you want to read, read the ADC, turn power of to the sensor you want to read. (keep in mind that the ADC of a nodeMCU reads a value between 0-1v i think) If you let the Nano do the reading, you will have multiple channels as well, but the extra complication of communicating between boards. One extra thing to consider with using Arduinos in a car is that while the engine is running there is a lot of noise on the power & GND lines, ESP units are even more sensitive to that than Arduinos.

Deva_Rishi: ... One extra thing to consider with using Arduinos in a car is that while the engine is running there is a lot of noise on the power & GND lines, ESP units are even more sensitive to that than Arduinos.

So what do you suggest for filtering away the noise? Would quite electrolytic capacitors be sufficient.

best regards Stefan

Would quite electrolytic capacitors be sufficient

in combination with diodes on the V+ & GND end of any circuit, yes it would probably enough. The regulator (to 3.3v ) that is present on a nodeMUC has a maximum input voltage of 12v, but a 7805 as an extra buffer in between puts out 5v with is a much more safe level to power a nodeMCU with.

StefanL38: additional comment:

As you use an Arduino nano as the microcontroller that reads a sensor and creates a PWM-signal. you have to connect the Arduino-nano to one ESP8266 through a serial-connection.

You could do this by using the hardware-serial-connection this means using the same serial connection as for uploading and debug-output. So only uploading OR serial-communication with the Arduino-nano is possible

or you use a software-serial-connection.

Another solotion is to let do the ESP8266 the sensor-reading and creating the PWM and sending data with ESP-NOW. the naked ESP8266-chip and some ESP8266-boards need a maximum of 1.0 Volt as analog-voltage-input. Some of them have a voltage-divider so they need 3.3V Please post the exact type of ESP8266 you are using.

If you haven't bought them yet I recommend considering buying two ESP32 modules type nodeMCU32 instead. $6 to $12 per board. ESP32 have multiple ADC-channels. An ESP8266 has only one ADC-channel.

With an ESP32 you need a different library for ESP-NOW. Not a problem. Just important to know.

best regards Stefan

Thanks for your help and also, the links in my original post will take you to the exact esp8266 and lcd screen I currently have in my possession.