ESP22 to ESP32 network

I’ve got a SPI-TRONIC Pro 3600 Digital Protractor that give serial data out and did make it work using NRF24L01’s with an GLCD running from a 18650 battery, I got all this working and now I thought it’s time to upgrade to some ESP32’s and nokia 5110 screen( I tried an TFT but not good in the sun light) all in the aid to reduce power been drawn and make it last longer on battery.

I found the great Tutorial for it on the random nerd Tutorials site for this and ported over the code from version 1, This is working great but I’d like to add like a fail safe system. The range part should no be a problem has these will be working out doors and line of site and max about 150 Feet apart.

The part I can’t get to grips with is how to carry out is if the sender does not receive any serial data from the Digital Protractor I.E cable between the Digital Protractor and the sender or the battery goes flat or off on the Digital Protractor.

How to send zero’s to the receiver so the operator knows something is wrong ?

The Sender will not have a display only the receiver will on it so the operator can see the angles when the unit moves.

Has the code stand’s at the moment it just give serial data for debugging.
Sender code:

/*********
   #### TX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  – 4.32
  – 179.9
*********/
//include the libraries
#include <esp_now.h>
#include <WiFi.h>

uint8_t broadcastAddress[] = {0X24, 0X6F, 0X28, 0XB3, 0XF3, 0XE0}; //MAC adress been sent to
const byte numChars = 8; //This is amount of data coming in
char receivedChars[numChars];   // an array to store the received data
boolean newData = false; // End of recieving Serial data

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  char macStr[18];
  Serial.print("Packet to: ");
  // Copies the sender mac address to a string
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print(macStr);
  Serial.print(" send status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup() {
  Serial.begin(9600); // Set the Serial baud of the Pro 3600 Digital Protractor
  WiFi.mode(WIFI_STA);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  esp_now_register_send_cb(OnDataSent);

  // register peer
  esp_now_peer_info_t peerInfo;
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }

}

void loop() {
  recvWithEndMarker();
  showNewData();
}
//Read the incoming serial Data
void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}
//Send the data out
void showNewData() {
  if (newData == true) { //added this fo the end marker to make sure I get only good data
    Serial.print("This just in ... "); //Just for debuging
    Serial.println(receivedChars);//Just for debugging
    Send_data();
  }
  else {
    receivedChars[8] = 00.00;
    Send_data();
  }



}
void Send_data() {
  esp_err_t result1 = esp_now_send(
                        broadcastAddress,
                        (uint8_t *) &receivedChars,
                        sizeof(receivedChars));
  newData = false;
  if (result1 == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");

  }
}

receiver code:

/*********
  #### RX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  – 4.32
  – 179.9
*********/

#include <esp_now.h>
#include <WiFi.h>
const byte numChars = 8; //This is amount of data coming in
char receivedChars[numChars];   // an array to store the received data

//callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&receivedChars, incomingData, sizeof(receivedChars));
  Serial.print("Bytes received: ");
  Serial.println(receivedChars);

}

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

  //Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  //Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

}

Has it stands at the moment when I turn off the Digital Protractor the last value is always displayed so the operator would not think that the angle has been altered.

So the Receiver knows this and just display’s all zero’s

On the receiver side, what about embedding the setting of a timer in the function OnDataRecv(). Something like :

lastDataReceivedAtMs = millis() ; // global volatile uint32_t

In the loop(), test if the timer has expired:

if ( millis() - lastDataReceivedAtMs > 10000 ) {
// no data received so cancel reading and warn user
}

The sender then should not send any data if there is an error in collecting that data.

6v6gt:
On the receiver side, what about embedding the setting of a timer in the function OnDataRecv(). Something like :

lastDataReceivedAtMs = millis() ; // global volatile uint32_t

In the loop(), test if the timer has expired:

if ( millis() - lastDataReceivedAtMs > 10000 ) {
// no data received so cancel reading and warn user
}

The sender then should not send any data if there is an error in collecting that data.

Sorry I don't quite follow you.

When I turn off the digital Protractor the sender is sending the last stored value for example -0.32 and the receiver just displays -0.32 until I turn it back on and move it.

Would that be just be the same result at the receiver would not know any difference ?

The idea is to notice that no new data has arrived for a certain time, then react.
Immediately new data has been received from the protractor, record the value of millis() by setting a timer.
You could set the timer on the sender side in function recvWithEndMarker() where you set newdata = true.

If that time stamp goes stale, which you determine by a test in the loop(), you do something like clean out the old data by setting it to zero.

I have this task on a ESP32:

void fmqttWatchDog( void * paramater )
{
  int UpdateImeTrigger = 86400; //seconds in a day
  int UpdateTimeInterval = 85000; // get another reading when = UpdateTimeTrigger
  int maxNonMQTTresponse = 12;
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 5000; //delay for mS
  for (;;)
  {
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY ); // update mqttOK
    mqttOK++;
    xSemaphoreGive( sema_mqttOK );
    if ( mqttOK >= maxNonMQTTresponse )
    {
      ESP.restart();
    }
    UpdateTimeInterval++; // trigger new time get
    if ( UpdateTimeInterval >= UpdateImeTrigger )
    {
      TimeSet = false; // sets doneTime to false to get an updated time after a days count of seconds
      UpdateTimeInterval = 0;
    }
  }
  vTaskDelete( NULL );
} //void fmqttWatchDog( void * paramater )

The task runs, increments the mqttOK variable, checks to see if the variable has reached a count of 5, and if so do a reboot.

This task resets mqttOK to zero.

void DoTheBME680Thing( void *pvParameters )
{
  SPI.begin(); // initialize the SPI library
  vTaskDelay( 10 );
  if (!bme.begin()) {
    log_i("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }
  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
  //wait for a mqtt connection
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 250 );
  }
  xEventGroupSetBits( eg, evtWaitForBME );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 1000 * 15; //delay for mS
  for (;;)
  {
    x_eData.Temperature = bme.readTemperature();
    x_eData.Temperature = ( x_eData.Temperature * 1.8f ) + 32.0f; // (Celsius x 1.8) + 32
    x_eData.Pressure    = bme.readPressure();
    x_eData.Pressure    = x_eData.Pressure / 133.3223684f; //converts to mmHg
    x_eData.Humidity    = bme.readHumidity();
    x_eData.IAQ         = fCalulate_IAQ_Index( bme.readGas(), x_eData.Humidity );
    //log_i( " temperature % f, Pressure % f, Humidity % f IAQ % f", x_eData.Temperature, x_eData.Pressure, x_eData.Humidity, x_eData.IAQ);
    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    if ( MQTTclient.connected() )
    {
      MQTTclient.publish( topicInsideTemp, String(x_eData.Temperature).c_str() );
      vTaskDelay( 3 ); // gives the Raspberry Pi 4 time to receive the message and process
      MQTTclient.publish( topicInsideHumidity, String(x_eData.Humidity).c_str() );
      vTaskDelay( 3 ); // delay for RPi
      MQTTclient.publish( topicInsidePressure, String(x_eData.Pressure).c_str() );
      vTaskDelay( 3 ); // delay for RPi
      MQTTclient.publish( topicInsideIAQ, String(x_eData.IAQ).c_str() );
    }
    xSemaphoreGive( sema_MQTT_KeepAlive );
    xSemaphoreGive( sema_PublishPM ); // release publish of dust density
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
    mqttOK ++;
    xSemaphoreGive( sema_mqttOK );
    xQueueOverwrite( xQ_eData, (void *) &x_eData );// send data to display
    //
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    // log_i( "DoTheBME280Thing high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete ( NULL );
}

Perhaps such a scheme could be incorporated into your project or not?

I’ve had a bit for time well been trying all night to sort this out, I think its the way I read the serial data coming in.
I’ve found once the Serial data stops between the sender and the Protractor the Newdata variable does not get set to true and there for Send_Data() function will not happen and no data gets sent to he receiver.

I’ve tried to move the Send_data() outside the If (NewData == True) But then this screws everything up.

I’ve gone back to basic and looked at Robin2’s how to receive serial data and have tried to use Example 2 (which is the original way I’ve done it in the code above. So I’ve looked at example Example 3.

This what I’ve tried (Bare basic no Sending Data, just trying to leaving the Serial read routine and display 10 when not receiving serial data) Example 2.

// Example 2 - Receive with an end-marker
/*********
   #### TX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  – 4.32
  – 179.9
*********/
const byte numChars = 8;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;
int lost;
void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;
unsigned long lastDataReceivedAtMs = millis() ;  // global volatile uint32_t
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
      if ( millis() - lastDataReceivedAtMs  > 500) {
  lost = 10;
  lastDataReceivedAtMs = millis();
}
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.print(receivedChars[0]);
    Serial.print(receivedChars[1]);
    Serial.print(receivedChars[2]);
    Serial.print(receivedChars[3]);
    Serial.print(receivedChars[4]);
    Serial.print(receivedChars[5]);
    Serial.print(receivedChars[6]);
    Serial.println(receivedChars[7]);
    // Send all receivedChars out at onnce
    // Serial.print("This just in ... ");
    //  Serial.println(receivedChars);
    newData = false;
      }
      if (lost == 10) {
        Serial.println(lost);
      }
  
}

And this what the output I’m seeing on the serial moniotr.

This just in ... -  8.26
This just in ... - 11.24
This just in ... - 16.36
This just in ... - 19.30
This just in ... - 19.05
This just in ... - 11.57

So I’ve tried example 3 way.

// Example 3 - Receive with start- and end-markers
/*********
   #### TX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  – 4.32
  – 179.9
*********/
const byte numChars = 8;
char receivedChars[numChars];

boolean newData = false;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char Plus_sign = '+';
  char Minus_sign = '-';
  char endMarker =  '\n';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == Plus_sign ||  Minus_sign) {// Start Maker either plus/minus start bit
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {

    Serial.print("This just in ... ");
    Serial.print(receivedChars[0]);
    Serial.print(receivedChars[1]);
    Serial.print(receivedChars[2]);
    Serial.print(receivedChars[3]);
    Serial.print(receivedChars[4]);
    Serial.print(receivedChars[5]);
    Serial.print(receivedChars[6]);
    Serial.println(receivedChars[7]);

    // Send all receivedChars out at onnce
    //Serial.print("This just in ... ");
    //  Serial.println(receivedChars);
    newData = false;
  }
}

But did not go any further with it has it doe not display the correct data.

This just in ...   8.22
This just in ...  12.78
This just in ...  14.82

The +/- sign is missing which I changed example 3 has I think the start marker is the +/- sign from looing at the data format coming out of the Protractor.

The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  – 4.32
  – 179.9

How can I jump out or the while loop if no serial data is coming in or do it so that I can just get LOST DATA printing on the serial monitor until serial data starts coming in again ?

The data send from your spirit-level starts with a “+” or a “-” and ends with carriage-return line feed in short CR-LF
which is is ASCII-code 13 - 10

So the code of the ESP32 that is connected to the spirit-level has to check for “+” or “-” as start-character and has to check for the two characters decimal-values 13 10 as ending characters.

If I understand right the spirit-level sends a datapacket each 533 milliseconds.
Whenever there is more than 1 second between two datapackets the spirit-levels is not received anymore by your ESP32( connected to the spirit-level).

after looking inside your ocde I saw

else if (rc == Plus_sign ||  Minus_sign)

this code does the following operations:
compare rc with Plus_sign the result can be true or false
then do a logical OR with value “Minus_sign”

let’s say rc is “+”
if ("+" == “+” || “-”) evaluates to

if (true || 45)

let’s say rc is “2”
if (“2” == “+” || “-”) evaluates to

if (false || 45)

What you really need is

else if (  (rc == Plus_sign) ||  (rc == Minus_sign)    )[color=#000000][/color]

do you see the difference?

else if ( (rc == Plus_sign) || (rc == Minus_sign) )

To analyse problems like this you can add debugoutput like this

else if (  (rc == Plus_sign) || Minus_sign)    ) {

  if (rc == Plus_sign) {
    serial.print("(rc == Plus_sign) evaluates to true");
    serial.print("rc=#"); // print titel and "embrace-start-character
    serial.print(rc);  // print value of rc itself
    serial.print("#"); // print "embrace-end-character

    serial.print(" Plus_sign=#"); // print titel and "embrace-start-character
    serial.print(Plus_sign);  // print value of rc itself
    serial.println("#"); // // print "embrace-end-character

    serial.print("else if (");
    serial.print(rc);
    serial.print(" == ");
    serial.print(Plus_sign));

  {
  else
    serial.print("(rc == Plus_sign) evaluates to false"); // ...

pretty much to write but gives th most clearness about all details what your variables contain and what any condition evaluates to true or false

writing down thsi debug-code needs time - of course
the alternative is to guess around trying this trying that
needs more time with and it is not 100% sure to find the bug

posting a question in the userforum and waiting for an answer needs time too.[/color]

So the first option is the one that needs time to finish your program but adds value by learning more about programming in parallel to analysing the bug

best regards Stefan [/color]

Thanks for that StefanL38 and very well explained I changed this line

else if (rc == Plus_sign ||  Minus_sign)

To this line

else if (  (rc == Plus_sign) ||  (rc == Minus_sign)    )

Has you said and I needed to change this numChars =8 to this numChars = 9 has I was only getting part of the last part of the 13, Once I changed it,
It now works like it does in example 2 code but I now know that I’m getting all the bytes from the spirit-level every time.
I’ve now added the EPS_now code and can see that it’s transmitting but on the receiver side I don’t see the myData.receivedChars I know that I’ve got 9 bytes coming acoeding to the serial data that is been printed.
Sender code:

// Example 3 - Receive with start- and end-markers
/*********
   #### TX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  - 4.32
  - 179.9
*********/
#include <esp_now.h>
#include <WiFi.h>
#include <HardwareSerial.h>
HardwareSerial MySerial(1);// MySerial.begin(9600, SERIAL_8N1, 16, 17);
const byte numChars = 9;
char receivedChars[numChars];
uint8_t broadcastAddress[] = {0X24, 0X6F, 0X28, 0XB3, 0XF3, 0XE0}; //MAC adress been sent to
boolean newData = false;
typedef struct Data_struct {
// int test =10;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct Data;

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  char macStr[18];
  // Serial.print("Packet to: ");
  // Copies the sender mac address to a string
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print(macStr);
  Serial.print(" send status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
  Serial.begin(115200);
  MySerial.begin(9600, SERIAL_8N1, 16, 17);
  Serial.println("<Arduino is ready>");
  WiFi.mode(WIFI_STA);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  esp_now_register_send_cb(OnDataSent);

  // register peer
  esp_now_peer_info_t peerInfo;
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char Plus_sign = '+';
  char Minus_sign = '-';
  char endMarker =  '\n';
  char rc;

  while (MySerial.available() > 0 && newData == false) {
    rc = MySerial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if ((rc == Plus_sign) ||  (Minus_sign)) {// Start Maker either plus/minus start bit
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
    Send_data();
  }
}
void Send_data() {
  esp_err_t result1 = esp_now_send(broadcastAddress, (uint8_t *) &Data, sizeof(Data));
}

Receiver code:

#include <esp_now.h>
#include <WiFi.h>
const byte numChars = 9; //This is amount of data coming in
//Structure example to receive data
//Must match the sender structure
typedef struct test_struct {
  int test;
  char receivedChars[numChars];   // an array to store the received data
} test_struct;

//Create a struct_message called myData
test_struct myData;

//callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("y: ");
  Serial.print(myData.test); // This prints ok
  //All others reamin blank
  Serial.println(myData.receivedChars); // print the whole receivedChars
  /*
    Serial.println(myData.receivedChars[0]);//show signle receivedChars
    Serial.println(myData.receivedChars[1]);//show signle receivedChars
    Serial.println(myData.receivedChars[2]);//show signle receivedChars
    Serial.println(myData.receivedChars[3]);//show signle receivedChars
    Serial.println(myData.receivedChars[4]);//show signle receivedChars
    Serial.println(myData.receivedChars[5]);//show signle receivedChars
    Serial.println(myData.receivedChars[6]);//show signle receivedChars
    Serial.println(myData.receivedChars[7]);//show signle receivedChars
    Serial.println(myData.receivedChars[8]);//show signle receivedChars
  */
}

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

  //Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  //Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

}

This is what’s coming in

21:08:38.323 -> Bytes received: 9
21:08:38.323 -> y: 
21:08:39.367 -> Bytes received: 9
21:08:39.367 -> y: 
// This is once I added the test variable of 10 21:25:01.642 -> Bytes received: 16
21:25:44.763 -> Bytes received: 16
21:25:44.763 -> y: 10

I added another dummy variable an int as 10 and this changed the Bytes received from 9 to 16 and is serial prints the 10 ok, Which is good so I know it’s transmiting from the sender ok.
So I just need to look into this as why non of the receivedChars are printing or not been sent and then see how about adding an fail safe to it once I know the other bits are working.
Once again thankyou for your time, This has given me a better under standing of how it works and about the debugging part

Scrap above stuff, I’ve figured out where I went I was not adding the Data.receivedChars in the sender code. And I need to print the receivedChars individually.
Latest Sender code:

// Example 3 - Receive with start- and end-markers
/*********
   #### TX CODE ####
  Wireless SPI-TRONIC Pro 3600 Digital Protractor
  General Information
  The Pro 3600 has an ASCII-format RS-232 compatible serial port for remote angle readout.
  The T&B Ansley 609-1027 connector on the back of the Pro3600 mates with industry
  standard cables. Angles are calculated and transmitted every 8/15 second (533 msec)
  Angle Output Format:
  The ASCII angle output may be read by a computer, or may directly drive a printer. Measured
  angles cover a full 360° range and the readout is between -180.00° and +180.00°.
  Format:
  <sign> XXX.XX <carriage return><line feed>
  examples:
  + 124.50
  + 32.70
  + 9.38
  - 4.32
  - 179.9
*********/
#include <esp_now.h>
#include <WiFi.h>
#include <HardwareSerial.h>
HardwareSerial MySerial(1);// MySerial.begin(9600, SERIAL_8N1, 16, 17);
const byte numChars = 9;
char receivedChars[numChars];
uint8_t broadcastAddress[] = {0X24, 0X6F, 0X28, 0XB3, 0XF3, 0XE0}; //MAC adress been sent to
boolean newData = false;
typedef struct Data_struct {
  int test =10;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct Data;

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  char macStr[18];
  // Serial.print("Packet to: ");
  // Copies the sender mac address to a string
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print(macStr);
  Serial.print(" send status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
  Serial.begin(115200);
  MySerial.begin(9600, SERIAL_8N1, 16, 17);
  Serial.println("<Arduino is ready>");
  WiFi.mode(WIFI_STA);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  esp_now_register_send_cb(OnDataSent);

  // register peer
  esp_now_peer_info_t peerInfo;
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char Plus_sign = '+';
  char Minus_sign = '-';
  char endMarker =  '\n';
  char rc;

  while (MySerial.available() > 0 && newData == false) {
    rc = MySerial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        Data.receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        Data.receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
        
      }
    }

    else if ((rc == Plus_sign) ||  (Minus_sign)) {// Start Maker either plus/minus start bit
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(Data.receivedChars);
    newData = false;
    Send_data();
  }
}
void Send_data() {
  esp_err_t result1 = esp_now_send(broadcastAddress, (uint8_t *) &Data, sizeof(Data));
}

Latest Reciever Code:

#include <esp_now.h>
#include <WiFi.h>
const byte numChars = 9; //This is amount of data coming in
//Structure example to receive data
//Must match the sender structure
typedef struct test_struct {
  int test;
  char receivedChars[numChars];   // an array to store the received data
} test_struct;

//Create a struct_message called myData
test_struct myData;

//callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("y: ");
  Serial.print(myData.test); // This prints ok
  //All others reamin blank
 // Serial.println(myData.receivedChars); // print the whole receivedChars
 
    Serial.print(myData.receivedChars[0]);//show signle receivedChars
    Serial.print(myData.receivedChars[1]);//show signle receivedChars
    Serial.print(myData.receivedChars[2]);//show signle receivedChars
    Serial.print(myData.receivedChars[3]);//show signle receivedChars
    Serial.print(myData.receivedChars[4]);//show signle receivedChars
    Serial.print(myData.receivedChars[5]);//show signle receivedChars
    Serial.print(myData.receivedChars[6]);//show signle receivedChars
    Serial.print(myData.receivedChars[7]);//show signle receivedChars
    Serial.println(myData.receivedChars[8]);//show signle receivedChars
 
}

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

  //Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  //Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

}

I just now to need to add a fail safe so it the spritlevel does not send data to the EPS32 this show’s up in the receiver code.
6v6gt I did try to add the code like you mentioned and all that did when I had the display connected was causing it to flash the text while the sprit-level was sending data to the eps32. Will look at trying other ways

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.