1

I am trying to write four values relating to energy (current, power, energy, and peak demand) via a SoftwareSerial connection from my Arduino UNO to my Raspberry Pi 4. However, two things are occurring:

  1. All of the values should be different, but they are printing to the RPi terminal as if they're identical.

  2. It seems as if the values I'm writing are merging together(?), creating a nonsense value. For example, if the values that I'm sending are 0.24, 28, 0.05, and 71, they appear in the RPI terminal looking like this:

Current: 54543878
Power: 54543878
Energy: 54543878
Peak Power: 54543878

This is a snip of my Arduino code that writes to the Bluetooth serial connection (uses HC-06):

  bluetoothSerial.write(RMSCurrent);
  bluetoothSerial.write(RMSPower);
  bluetoothSerial.write(kilos);
  bluetoothSerial.write(peakPower);

This is a snip of the Python script that receives it:

while 1:
try:
    received_data = bluetoothSocket.recv(1024)
    RMSCurrent = int.from_bytes(received_data,byteorder='big')
    RMSPower = int.from_bytes(received_data,byteorder='big')
    kilos = int.from_bytes(received_data,byteorder='big')
    peakPower = int.from_bytes(received_data,byteorder='big')

    print("Current (A): %d" % RMSCurrent)
    print("Power (W): %d" % RMSPower)
    print("Energy (kWh): %d" % kilos)
    print("Peak Demand: %d" % peakPower)
    
except KeyboardInterrupt:
    print("keyboard interrupt detected")
    break
bluetoothSocket.close()

Does anyone have any ideas of what is going on? Two of my values are floats and two are integers. I've tried to fix this for the past 12 hours, but to no avail.

3
  • printing to the RPi terminal as if they're identical ... why are you surprised? ... it appears that you are setting all four to the same value .... print the value of received_data instead
    – jsotola
    Commented Jul 15, 2021 at 2:39
  • @jsotola I get a hex ASCII code when received_data is printed. I guess I'm just not sure how to parse the values I want from that and assign them to the four different variables. Commented Jul 15, 2021 at 3:09
  • 0.24 is not an int. You python code expects ints only (and reads the first bytes of received_data four times).
    – Mat
    Commented Jul 15, 2021 at 6:14

1 Answer 1

1

You will save yourself a lot of headaches by sending the data in ASCII instead of binary:

bluetoothSerial.print("RMSCurrent: ");
bluetoothSerial.println(RMSCurrent);

Of course, you will then have to parse the data stream on the Python side.

If you really want to send binary data, then be aware that the write() method you are using is intended for sending single bytes. Every number you write() is converted to an integer (truncated if it's a float), reduced modulo 256 to the range [0, 255], then sent as a single byte. You can loose quite a bit of information in this process.

To send a binary object larger than a byte, you have to use an overload of write() that takes both a pointer (the address of the object) and a number of bytes to send. For example:

bluetoothSerial.write((uint8_t *) &RMSCurrent, sizeof RMSCurrent);

But then, you have to be aware that some numeric types do not have the same binary representation on the Arduino and on the Pi. For instance:

  • an int is 2 bytes on the Arduino and 4 bytes on the Pi
  • a double is 4 bytes on the Arduino and 8 bytes on the Pi

I recommend you only use fixed-size integer types (uint16_t and such) and float.

Also, be aware that the Arduino is little-endian, like the Pi, and unlike what your Python code currently assumes.

Oh, and the serial link does not have a notion of data packets. If there happens to be some leftover crap in the serial buffer when you start your Python program, it will get out of sync with the Arduino, and you will only read garbage. There are ways around this problem (search for “packet framing”) but they add quite a bit of complexity.

As I said, you will save yourself a lot of headaches by sending the data in ASCII instead of binary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.