High frequency messages with ESP_NOW

mdemet
Posts: 1
Joined: Wed Aug 28, 2024 2:31 pm

High frequency messages with ESP_NOW

Postby mdemet » Wed Aug 28, 2024 2:48 pm

Hello, I am working on a project that requires multiple devices to transmit IMU data at 20Htz. I need multiple transmitters sending their IMU data that will need to end up on a PC.

I am using multiple (4-8) ESP32-S3 as the data transmitters and another ESP32-S3 as a receiver. The transmitters are sending the data using ESP_NOW and the receiver is connected to a web-socket server and passes on the received data to the PC. This setup works ok with up to 4 transmitters but once I introduce a 5th transmitter my receiver stops responding after a minute or so.

Here is the relevant code of the receiver device:

Code: Select all

struct IMUReading {
  int deviceID;
  float accelX;
  float accelY;
  float accelZ;
  float gyroX;
  float gyroY;
  float gyroZ;
  float magX;
  float magY;
  float magZ;
};

bool isWebSocketConnected = false;
const int IMU_READINGS_PER_BATCH = 5;
IMUReading imuReadings[IMU_READINGS_PER_BATCH];

void onReceiveData(const uint8_t *mac_addr, const uint8_t *incomingData, int len) {
  if (isWebSocketConnected) {

    memcpy(imuReadings, incomingData, sizeof(imuReadings));

    String output = "Msg from: d" + String(imuReadings[0].deviceID) + " ";

    for (int i = 0; i < IMU_READINGS_PER_BATCH; i++) {
      output += "Accel: (" + String(imuReadings[i].accelX) + ", " + String(imuReadings[i].accelY) + ", " + String(imuReadings[i].accelZ) + "), ";
      output += "Gyro: (" + String(imuReadings[i].gyroX) + ", " + String(imuReadings[i].gyroY) + ", " + String(imuReadings[i].gyroZ) + "), ";
      output += "Mag: (" + String(imuReadings[i].magX) + ", " + String(imuReadings[i].magY) + ", " + String(imuReadings[i].magZ) + ") - ";
    }

    webSocket.sendTXT(output);
}
I would appreciate it if someone can tell me if I can optimize any of the above code in order to avoid my receiver device crashing.

Furthermore, could I achieve the functionality of sending data from multiple ESP32 (at 20Htz) that will end up on a PC using a different, more efficient approach? I have tried using Serial print from the receiver and reading the serial data on the PC but that is much slower than the web-socket solution.

Thank you in advance.

rin67630
Posts: 139
Joined: Sun Mar 11, 2018 5:13 pm

Re: High frequency messages with ESP_NOW

Postby rin67630 » Sat Sep 07, 2024 7:40 pm

I am transmitting over UDP sendersthe raw structure mem-copied 1:1 into a char array that has the same length.
On the receiving side, I mem-copy the received char into the same structure on the other side.

If you have several senders, just add some bytes to the respective raw structure to get a different payload length length for every sender and copy on the receiving site depending on the message length.

That is extremely primitive, uses no header, no check-sum, no conversion, no decoding, but that makes it unbeatably fast and I never had any problem over years.

Code: Select all

// === (Getting Sound / Battery values from another ESP over UDP
// I use a quick and dirty method called 'type punning' copying the memory block of a structure into an array of chars,
// transmitting this array, and copying back the memory block of the array into the same structure on the other side.
// I dont use any header info, only the difference of size permits to assign the received packets to sound or battery.
// it is quick and damn efficient, but NOT portable and YOU must take care to have the same structures on both systems
// and different sizes for Battery and Sound...

#if defined (UDP_IS_SEND)
  memcpy(UDPBatPayload, &payload, sizeof(payload));
  UDP.beginPacket(ESP_UDP_ADDR, ESP_UDP_PORT);
  UDP.write(UDPBatPayload, sizeof(payload));
  UDP.endPacket();
#endif

#if defined (UDP_IS_RECEIVE)
  if (WiFi.status() == WL_CONNECTED)
  {
    digitalWrite(GRNLED, true);
    int packetSize = UDP.parsePacket();
    if (packetSize == sizeof(payload))
    {
      UDP.read(UDPBatPayload, UDP_TX_PACKET_MAX_SIZE);
      memcpy(&payload, UDPBatPayload, sizeof(payload));
    }
  }
#endif

Who is online

Users browsing this forum: DonEvans and 88 guests