1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Rep Power

    Help with universal functions


    I am fairly new to python, have just been playing with the arduino for a while, but got kinda bored with the limitations so that's why i'm now going for raspberry pi and python to control the arduino's outputs and receiving temperature/humidity data and so on from it.

    The arduino only sends data when its requested from the pi, and the data integrity is checked by a crc32 checksum.

    What my problem is, is that I want a universal function to split sensor data, check integrity and then print it. I have written a code that reads up to 2 sensors, but its kinda lame to have to add to the code if I want more of them, after all I want it to be universal, easier to read and reusable for other people too.

    Would appreciate any pointers for how I could accomplish this! The code i'm now using has had alot of improvements since I started on it, but I still feel there's alot more to do. As this is the first "real" python program i'm writing, i'm learning alot! And I gotta say, python is great!

    Anyway here is the part I need help with.

    import time
    import serial
    import binascii
    import re
    ser = serial.Serial('/dev/ttyAMA0', 9600) # Arduino connected to raspberrypi's UART
    def ifIn(first,checksum,crc32,id,reading):
            if first == "TEMP" and checksum == crc32:       # Compare against types of readings and check that checksums match
                    print id + " Temperature: " + reading   # 
            elif first == "HUMI" and checksum == crc32:
                    print id + " Humidity: " + reading
            elif first == "DSDS" and checksum == crc32:
                    print id + " DS temp: " + reading
            elif first == "LDR" and checksum == crc32:
                    print id + " LDR: " + reading
                    print "Checksum failed, discarding reading!"
    def checkRec(n):                        # Requests the reading I want, splits it and checks integrity.
            ser.flushInput()                # Flushing the input to make sure its empty before requesting data
            ser.write(n)                    # Asking arduino something..
            answ = ser.readline()           # Read until \n
            length = len(answ)              # Store length of answer for comparison
            if length > 25:                 # If length is over 25, its a double reading so we need a different split and slice
                    a = re.split('-',answ)  # Split eading from arduino: TEMP:1:24.30:1024012001-TEMP:2:23.10:1240120414 #Checksums here are made up
                    b = a[0]                # Store sensor 1 data
                    c = a[1]                # Store sensor 2 data
                    split1 = re.split(':',b)# Split reading 1
                    split2 = re.split(':',c)# Split reading 2
                    first = split1[0]          # Type of sensor reading
                    id = split1[1]                     # Sensor ID
                    reading = split1[2]                # Sensor reading (concatenated float from arduino) 
                    checksum = int(split1[3])          # Make checksum integer for comparison
                    crc32 = (binascii.crc32(reading) & 0xffffffff)  # Calculate checksum of reading for comparison with checksum sent from arduino
                    ifIn(first,checksum,crc32,id,reading)           # Check integrity and print readings if correct
                    first2 = split2[0]                              # Type of sensor reading nr2
                    id2    = split2[1]
                    crc322 = (binascii.crc32(reading2) & 0xffffffff)
            else:                                                   # If length is under 25, do a single sensor split
                    split = re.split(':',answ)                      # Reading has : as separator between type,id,reading,checksum
                    first = split[0]
                    id   = split[1]
                    checksum= int(split[3])
                    crc32= (binascii.crc32(reading) & 0xffffffff)
  2. #2
  3. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Rep Power
    Generalizing ifIn
    def ifIn(first,checksum,crc32,id,reading,translation = dict(
            zip('TEMP HUMI DSDS LDR'.split(),
                'Temperature,humidity,DS temp,LDR'.split(',')))):
        if checksum != crc32:
            message = "Checksum failed, discarding reading!"
        elif first in translation:
            message = id + ' ' + translation[first] + ': ' + reading
            message = first + ' unknown'
    Assume your reader has neither raspberry pi nor Arduino. You want a more general function. What are the possible inputs? What output do you want for each input? Please describe input in Backus Naur form, if possible, and explain the output concisely. Thanks.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo