Search This Blog

Wednesday, 26 February 2014

Raspberry PI - Processing Serial data from Arduino in python

Data such as Odometry, Range Findings, Environmental information, and health of the Rover. 

Today, I'm doing this via SPI, but the question was asked about how this is done via Serial, and specifically how to read and process the Arduino Serial Data in python, on the Raspberry PI.

On the Arduino Side:
(I send a CRLF terminated line starting with a data type descriptor: in this case "SNSR" for sensor data)
void Send_Sensors() {
   Serial.print("SNSR,");
   Serial.print( now);   Serial.print(","); 
   Serial.print(motion);   Serial.print(",");
 
   Serial.print(AccScaled.XAxis);   Serial.print(","); 
   Serial.print(AccScaled.YAxis);   Serial.print(","); 
   Serial.print(AccScaled.ZAxis);   Serial.print(",");
   Serial.print(CurrentHeading);    Serial.print(",");
 
 
    Serial.print(DirectAhead); Serial.print(",");      Serial.print(DirectBehind);  Serial.print(",");
   Serial.print(DirectRight);  Serial.print(",");  Serial.print(DirectLeft); Serial.print(",");
   Serial.print(FrontRight);  Serial.print(",");  Serial.print(FrontLeft);   Serial.print(",");
   Serial.print(Temperature);  Serial.print(",");  Serial.print(Pressure);   Serial.print(",");
   Serial.print(Altitude);  Serial.print(",");  Serial.println(batvolt);
 


On the Raspberry Pi Python Side:
(Caveat: this is just a snippet from my code... it will not function fully as is:)

  • I import Serial
  • I declare a function to read and parse a line from Serial
  • I set up the serial port and open it.
  • I then wait for incoming data in my main loop.  If the first field matches what I'm looking for, I update my variables.


#! /usr/bin/python
#

import serial

########################################################################
# Global Variables   -  Yes I know these are bad...

accel_x = 0.0
accel_y = 0.0
accel_z = 0.0
heading = 0.0
directahead = 0.0
directbehind = 0.0
directleft = 0.0
directright = 0.0
voltage = 0

ready=0                        # ready to send command to arduino
timeout = 0                    # To avoid infinite wait state, we will count 100 loops and assume failure
line = None                     # Holds current response from Arduino Serial
line_len = 0                    # number of items in "line"


##########################################################################
# Declare functions

def get_arduino_response():
   global line
   global line_len
  
   if (arduino.inWaiting() > 0):              # Number of characters in arduino buffer  
       line = arduino.readline()
       line = line.split(",")
       line_len = len(line)
       print 'Receiving: line[0]= ' , line, 'Num Items= ', line_len, 'timeout= ', timeout


##########################################################################
# Set up serial port to Arduino
arduino = serial.Serial('/dev/ttyACM0', 115200, timeout = 10)
arduino.open()


time.sleep(10)    # Time for Arduino to reset and settle
arduino.flushInput()  


##########################################################################
# Main Loop

try:
    running = True

    while 1:                    # Continuous loop
       # os.system('clear')
       stamp = time.time()

       get_next_command()            # find the next available command to process

       get_arduino_response()                   # If data available from arduino, retrieve into "line"
      

       if line[0] == "SNSR" and line_len == 13:    # Ensure entire line came through
          ardtime = line[1]
              motion = line[2]
          accel_x = float(line[3])
          accel_y = float(line[4])
          accel_z = float(line[5])
          heading = float(line[6])
          directahead = float(line[7])
          directbehind = float(line[8])
          directleft = float(line[9])
          directright = float(line[10])
          voltage = line[11]
          UID = line[12]
          UID = UID.strip()


          print 'line ' , ardtime, accel_x, accel_y, accel_z, heading ,'done'


 
   

except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    print "\nKilling Thread..."
    db.close()
print "Done.\nExiting."