Problem transmitting float values

Does anyone see any issues with the float y value below? This is on the receiving end of the ESP-NOW protocol, as you can see I pretty much used the standard sample supplied and modify the value based on my needs, from integer to float. It works perfectly if it were interger, when I change over to float cuz the number is decimal, it is no longer working and showing irrelevant numbers.

On the sender side it is showing the correct float value without issues

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-many-to-one-esp8266-nodemcu/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
    int id;
    int x;
    float y;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;

// Create an array with all the structures
struct_message boardsStruct[2] = {board1, board2};

// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac_addr, uint8_t *incomingData, uint8_t len) {
  char macStr[18];
  Serial.print("Packet received from: ");
  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.println(macStr);
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
  // Update the structures with the new incoming data
  boardsStruct[myData.id-1].x = myData.x;
  boardsStruct[myData.id-1].y = myData.y;
  Serial.printf("x value: %d \n", boardsStruct[myData.id-1].x);
  Serial.printf("y value: %d \n", boardsStruct[myData.id-1].y);
  Serial.println();
}
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    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_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(OnDataRecv);

   pinMode(LED_BUILTIN, OUTPUT);
}

void loop(){
  // Access the variables for each board
  /*int board1X = boardsStruct[0].x;
  int board1Y = boardsStruct[0].y;
  int board2X = boardsStruct[1].x;
  int board2Y = boardsStruct[1].y;
  */
   

}

What does the sender code look like?

No issues with sender code as I saw in serial monitor it is showing value with 2 decimal places

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-many-to-one-esp8266-nodemcu/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 2

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
    int id;
    int x;
    float y;
} struct_message;

// Create a struct_message called test to store variables to be sent
struct_message myData;

unsigned long lastTime = 0;
unsigned long timerDelay = 10000;

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("\r\nLast 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);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  } 
  // Set ESP-NOW role
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);

  // Once ESPNow is successfully init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  
  pinMode(D3,INPUT);
  pinMode(A0,INPUT);
 
}
 
void loop() {
    
  if ((millis() - lastTime) > timerDelay) {
    // Set values to send
    myData.id = BOARD_ID;
    myData.x = digitalRead(D3);
    myData.y = analogRead(A0)/63.35;
    Serial.println(digitalRead(D3));
    Serial.println(myData.y);

    // Send message via ESP-NOW
    esp_now_send(0, (uint8_t *) &myData, sizeof(myData));
    lastTime = millis();
  }
}

Time to debug. I'd send a fixed number in the float and dump the bytes you see on the receiver and verify them against what was sent.

Just tried with a float fixed number, there is the issue, it is not the number but the float data type causing the issue, can you check my receiver side if there is something odd?

How big does the compiler think your structs are and how many bytes do you receive?

I recevied 12 bytes, and the compilers I am not familiar unfortunately... only simple programming I know. I was thinking the recevier side is restricting float data type... the number from sender side is 7.57 however once reached recevier it is showing 1139998720

Do the sender and receiver both use 4 bytes for a float, or is one defaulting to double (8 bytes)?

No idea how would I be able to check that

Now that you know that there are different representations of "float", you could do some reading and research on the topic.

But it is probably not necessary to transmit floats, if integers work. Scale the data any way you like.

Help me out guys please I am not good at this. This is the last before I can finish this project

It would be better to avoid using float for technicality. My formulae is the sensor value divided by 64, I can multiply the value by 100 to make integer number however how I can keep out the decimal places ?

Just send the analogRead value, which is an integer. Dividing by 63.35 gets you absolutely nothing at this point, and if needed can be done on the receiving end.

Just send the integer as @jremington suggests.

To see what the compiler thinks of your structs, print sizeof mydata on sender and receiver. I have a suspicion that they aren't the same. What hardware are you using?

I see you don't check that 'len' is the same value as 'sizeof(myData)'. You should probably check that before you copy the received data.

Have you tried displaying the data directly from myData instead of copying the fields into the array first?

Does anyone know how can I assign a name to each board so when the data gets transmitted over I know which board is coming. Currently it is set as board_ID 1 , 2 and so on. I would like to label them as names.

Change your struct so that the board ID is a character array with the name instead of an integer. You will use strcpy to initialize a value into the id.

typedef struct struct_message {
    //int id;
   char id[16];
    int x;
    //float y;
   int y;//for analogRead() value
} struct_message;

Instead of labeling them with names, continue to use ID's to reduce the size of data transfers and have an array of board names:

enum BOARD_ID { KITCHEN, LIVINGROOM, GUESTROOM, GARDEN, SHED };
char* BOARD_NAME[] = { "Kitchen", "Livingroom", "Guestroom", "Garden", "Shed" };

struct MESSAGE { BOARD_ID board_id, int data };

MESSAGE msg;
read(&msg, sizeof(msg));

printf("Board ID: %d, Name: %s, Data %d", msg.board_id, BOARD_NAME[msg.board_id], msg.data);

Untested example.

Precisely which boards are on the sending and receiving sides?

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