Notifications
Clear all

Serial Data Transfer from Arduino to Python

7 Posts
2 Users
1 Likes
6,797 Views
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

This post is an extension to Structures, Serialisation, XOR Checksums etc. thread.

The code published below is tested boilerplate code for serial transfer of data in the form of structs, from an Arduino to Python.

My thanks to both @frogandtoad and @ZeFerby for their tips and pointers.

An explanation: The values from sensors are gathered and stored in the Arduino in a pre-defined struct object and subsequently sent to Python as a data packet. This data packet is unwrapped by Python into a tuple (an array that can handle different data-types) for further processing.

It should be noted that to resolve any data misalignment the largest data-types are sent first with the smaller data types following in order of size (float = 4 bytes, int = 2 bytes, char = 1 byte).

First the Arduino sketch;

// to maintain data alignment the members of the struct object
// are ordered largest to smallest data type i.e. float = 4 bytes
// uint8_t = 1 byte

typedef struct{
  float afloat = -15.4; // 4 bytes
  uint8_t abyte = 12; // 1 byte
  uint8_t bbyte = 5; // 1 byte
  }data;

data myData; 


void setup() {
  Serial.begin(115200);

}

void loop() { 

  delay(5000);
  Serial.write((const byte*)&myData, sizeof(myData));

}

And now the cleaned up Python sketch:

import serial
import struct

my_comm_port = '/dev/cu.wchusbserial1460'; # *nix comm port notation

try:

# Change the baud rate here if different than 115200
ser = serial.Serial(
port='/dev/cu.wchusbserial1460',\
baudrate=115200,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=None
)

print("connected to: " + ser.portstr)

except IOError:

print("Invalid comm port!")
exit(1)

# f = float, B = unsigned Char (uint8_t equivalent)

size = struct.calcsize('fBB')
print(size)

def main():

while True:

data = ser.read(size)

#struct.unpack(format, bytestring)
tup = struct.unpack('fBB', data)
print(tup[0])
print(tup[1])
print(tup[2])

ser.close()

if __name__ == '__main__':
main ()

Have fun using this in your projects!


   
ZeFerby reacted
Quote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

Very nice short and concise code Steve.  Thanks for sharing.

I'm curious if this would work with SPI instead of using the serial ports?

Say I had the Python code running on a Raspberry Pi and I was connected to the Arduino via SPI. What would I need to change in these codes?   And would it still work with SPI?

Thanks.

 

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@robo-pi

My guess is YES!

Take a look at 

https://pypi.org/project/spidev/

 


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@robo-pi

Say I had the Python code running on a Raspberry Pi and I was connected to the Arduino via SPI. What would I need to change in these codes?   And would it still work with SPI?

This is where I would start experimenting, I doubt if this program would run correctly straight away, but it is my idea of a jumping-off point to be refined later.


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

@pugwash

Thanks for the links Steve, these will be very helpful. ? 

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@robo-pi

Did you have any luck with the Python sketch?

I can't test it myself as I don't own a RasbPi and I know that the SpiDev library will not compile on my Mac!


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

I'm not prepared to do it at the moment.   I don't currently have a rpi and an Arduino connected via SPI.   I just thought that since Bill is planning on using SPI for the rpi/Arduino communication I might go that route myself.   I've actually been using the Serial port when communicating between these two devices and I have never even used SPI for anything.  So I thought I might look into it.     So I'm saving this info for future ideas.

I might set up a rpi/Arduino SPI connection on the fly here to just gain some experience with it.   Right now I'm playing with setting up dimensions in Blender.  Too many toys I don't have time to play with them all.  ? 

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote