ESP32 - Error message when trying to send variable via AsyncUDP

Hi everyone

I'm trying to transmit sensor data from an MPU6050 accelerometer/gyroscope hooked up to an Adafruit HUZZAH32 – ESP32 Feather. I am using the board as a WiFi Access Point and want to send the data to my laptop.

I've managed to set up the access point and read out the sensor data, however, I get an error message when I try to send the data via UDP.

This is the error message I'm getting: > cannot bind non-const lvalue reference of type 'AsyncUDPMessage&' to an rvalue of type 'AsyncUDPMessage'

It appears to have to do with the way the Adafruit Unified Sensor driver references the data obtained from the sensor as a pointer instead of a variable, but I admit that I can't get my head around what's happening exactly and how and why they are used here (source).

Essentially, my question is twofold:

  1. Could anyone explain these two lines of code for me?
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

sensors_event_t is a data structure specific for the Adafruit Unified Sensors driver, but I don't quite understand technically what is exactly stored and why '&' is used here.

  1. How can I convert sensor data to a format I can send via UDP so that it doesn't throw me the above error message?

any help is much appreciated! best wishes -.-

here's my sketch in full:

// the purpose of this sketch is to send actual measurement data over wifi

#include "WiFi.h"                             // include libraries
#include "AsyncUDP.h"
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;                        

const char* ssid     = "ESP32_AP";
const char* password = NULL;          // set password, NULL; sets no password

AsyncUDP udp; 

void setup()
{
  Serial.begin(115200);                    // start serial connection

  /* initialize wifi Access Point */
  Serial.println("\n[*] Creating AP");     // print

  WiFi.mode(WIFI_AP);                      // ESP32 wifi in Access Point (AP) mode (as opposed to connecting to an existing wifi via router)
  WiFi.softAP(ssid, password);             // set AP name & password

  Serial.print("[+] AP Created with IP Gateway ");    // print
  Serial.println(WiFi.softAPIP());         // print IO host: 192.168.4.1 [client: 192.168.4.2]

  /* setup listening for incoming packets */
  if (udp.listen(1234)) {                  // listen on port 1234

    Serial.print("UDP Listening on IP: ");          // print
    Serial.println(WiFi.localIP());      // print local AP host IP (always 192.168.4.1.)

    udp.onPacket([](AsyncUDPPacket packet) {        // ???
      Serial.print("UDP Packet Type: ");
      Serial.print(packet.isBroadcast() ? "Broadcast" : packet.isMulticast() ? "Multicast" : "Unicast");
      Serial.print(", From: ");
      Serial.print(packet.remoteIP());
      Serial.print(":");
      Serial.print(packet.remotePort());
      Serial.print(", To: ");
      Serial.print(packet.localIP());
      Serial.print(":");
      Serial.print(packet.localPort());
      Serial.print(", Length: ");
      Serial.print(packet.length());
      Serial.print(", Data: ");
      Serial.write(packet.data(), packet.length());
      Serial.println();

      packet.printf("Got %u bytes of data", packet.length());     // reply to the client
    });
  }

  /* setup MPU6050 sensor */
  Serial.println("Adafruit MPU6050 test!");  // print

  /* Try to initialize! */
  if (!mpu.begin()) {                        // if .begin function returns false ... (= "Logical NOT results in a true if the operand is false and vice versa.")

    Serial.println("Failed to find MPU6050 chip");  // ... print failure message ...

    while (1) {                              // ... & create an endless loop to stop the program from doing anything useful. can only be reset manually via the 'reset' button
      delay(100);                            // orig.: 10ms
      Serial.println("MPU6050 init failure loop");   // little debug print loop to see where it stopped
    }
  }

  Serial.println("MPU6050 Found!");          // if not, proceed as planned

  /* set accelerometer range */
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);   // set the range of the accelerometer (a smaller range produces a more sensitive outcome) for sensor "mpu" which was defined above

  Serial.print("Accelerometer range set to: ");   // print

  switch (mpu.getAccelerometerRange()) {          // switch...case = if...then -> get function returns range that was set above
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");                       // print currently set range
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }

  /* set gyroscope range */
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);   // setting the gyroscope range in degrees/s. To get a more sensitive output response, set smaller degrees per second for the gyroscope range.

  Serial.print("Gyro range set to: ");

  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  /* set filter bandwidth */
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);       // this is done to ensure all the unnecessary frequencies are filtered out and a smoother, cleaner output is obtained.

  Serial.print("Filter bandwidth set to: ");

  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }

  Serial.println("");                       // print
  delay(100);                               // small delay
}

void loop()
{
  /* Get new sensor events with the readings, see https://learn.adafruit.com/using-the-adafruit-unified-sensor-driver?view=all */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  udp.broadcastTo(a.acceleration.x, 8000);

  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  //udp.broadcastTo(a.acceleration.y, 8000);

  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  //udp.broadcastTo(a.acceleration.z, 8000);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  //udp.broadcastTo(g.gyro.x, 8000);

  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  //udp.broadcastTo(g.gyro.y, 8000);

  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  //udp.broadcastTo(g.gyro.z, 8000);
  Serial.println(" rad/s");

  // Serial.print("Temperature: ");
  // Serial.print(temp.temperature);
  // Serial.println(" degC");

  Serial.println("");

  delay(500);
}

Please post the complete error message.

C:\Users\G***\Desktop\Arduino\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO.ino: In function 'void loop()':
AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO:154:34: error: cannot bind non-const lvalue reference of type 'AsyncUDPMessage&' to an rvalue of type 'AsyncUDPMessage'
   udp.broadcastTo(a.acceleration.x, 8000);
                   ~~~~~~~~~~~~~~~^
In file included from C:\Users\G***\Desktop\Arduino\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO.ino:4:
C:\Users\G***\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\libraries\AsyncUDP\src/AsyncUDP.h:32:5: note:   after user-defined conversion: 'AsyncUDPMessage::AsyncUDPMessage(size_t)'
     AsyncUDPMessage(size_t size=CONFIG_TCP_MSS);
     ^~~~~~~~~~~~~~~
In file included from C:\Users\G***\Desktop\Arduino\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO\AsyncUDPServer_combined-sensor-data-02-sendactualdata-REDUCEDFO.ino:4:
C:\Users\G***\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\libraries\AsyncUDP\src/AsyncUDP.h:143:12: note:   initializing argument 1 of 'size_t AsyncUDP::broadcastTo(AsyncUDPMessage&, uint16_t, tcpip_adapter_if_t)'
     size_t broadcastTo(AsyncUDPMessage &message, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);
            ^~~~~~~~~~~
Multiple libraries were found for "WiFi.h"
 Used: C:\Users\G***\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\libraries\WiFi
 Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
exit status 1
cannot bind non-const lvalue reference of type 'AsyncUDPMessage&' to an rvalue of type 'AsyncUDPMessage'

I'm not especially familiar with the AsyncUDP library, but if you look in AsyncUDP.h you'll see the prototypes for the overloads of the broadcastTo() function:

    size_t broadcastTo(uint8_t *data, size_t len, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);
    size_t broadcastTo(const char * data, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);

    size_t broadcastTo(AsyncUDPMessage &message, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);

None of them match what you're trying to do:

  udp.broadcastTo(a.acceleration.x, 8000);

Since a.acceleration.x is a float type. Perhaps you to convert the value to a c-string and use the second overload above?

BTW, "a" & "g" are exceptionally poor variables names. Being single-character, it's impossible to search for them in your code.

thanks, that solved it!

this is my solution now:

  char result[8]; // buffer big enough for 7-character float
  dtostrf(a.acceleration.x, 6, 2, result);
  udp.broadcastTo(result, 8000);

as for variable names, have to still clean that up, copied some of my code from the Adafruit example, but thanks for the heads up.

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