0

I'm struggling with my first steps with Python and PySerial. I have one Arduino which reads impulses from an electricity power meter, passes the counts over to another Arduino over an RF link and then sends the data over to an Raspberry Pi. The Arduino to Arduino communication works well. However the last step of passing this to the RPi fails.

The MeterValue from the Arduino side is an unsigned Long (32 bits) and therefore split in 4 pieces of 8-bit transmissions plus a frame start and frame end:

[0x01] Frame start
[0xMeterValueByte0]
[0xMeterValueByte1]
[0xMeterValueByte2]
[0xMeterValueByte3]
[0x04] Frame end

This is my Arduino code continuously sent to the RPi in debug purpose :

void loop() {
//static test loop
Serial.write(0x01); //start frame
Serial.write(0x00);
Serial.write(0x00);
Serial.write(0x02);
Serial.write(0x04); //end frame
delay(3000);

}   

This is my Python code:

Import serial
ser = serial.Serial('/dev/ttyACM0',9600)
print("Connected to: " + ser.portstr)

inputbuffer=[]
inputbuffer = [0 for i in range(10)]

while True: 
    if ser.inWaiting() > 0:
        inputbuffer = ser.read(1)
        print "Byte received"
        print "Inputbuffer[0]: " + hex(ord(inputbuffer[0]))

        j = inputbuffer[0]
        print "j= " + hex(ord(j))

This check of the "j" parameter somehow fails:

        if (j == 0x1): #look for start of frame
            print "Start found\n"
            print "Filling buffer\n"
            while ser.inWaiting() < 5: #hold here until 5 bytes arrived
                pass #proceed here
            inputbuffer +=ser.read(5) #read 5 bytes

            if inputbuffer[5] == 4: #check that the message has frame end
                RXval = inputbuffer[1]
                RXval |= (inputbuffer[2] << 8)
                RXval |= (inputbuffer[3] << 16)
                RXval |= (inputbuffer[4] << 24)
                print "RXval: ", RXval
            else:
                print "RX error, no frame end\n"
        inputbuffer = []

This is the Python output:

Connected to: /dev/ttyACM0
Byte received
Inputbuffer[0]: 0x1
j= 0x1
Byte received
Inputbuffer[0]: 0x0
j= 0x0
Byte received
Inputbuffer[0]: 0x0
j= 0x0
Byte received
Inputbuffer[0]: 0x2
j= 0x2
Byte received
Inputbuffer[0]: 0x4
j= 0x4

And then it repeats. Obviously the Python code doesn't realize j == 1. How should I handle the checking of the received bytes?

1 Answer 1

2

I think the problem is that you can't count ;)

Spot the difference:

0: [0x01] Frame start
1: [0xMeterValueByte0]
2: [0xMeterValueByte1]
3: [0xMeterValueByte2]
4: [0xMeterValueByte3]
5: [0x04] Frame end

and:

0: Serial.write(0x01); //start frame
1: Serial.write(0x00);
2: Serial.write(0x00);
3: Serial.write(0x02);
4: Serial.write(0x04); //end frame

Your receiver is looking for a pattern of 6 bytes, but your Arduino sketch is only sending a pattern of 5 bytes.

Your check for the start character is simple enough - you solved it fine a few lines above:

print "j= " + hex(ord(j))

But you forgot to do something similar for the check:

if (j == 0x1):

That should really be:

if (ord(j) == 0x1):
3
  • Helpful, but it still doesn't solve the problem with the checking of the first byte, does it?
    – Dejvid_no1
    Dec 29, 2015 at 14:40
  • @Dejvid_no1 Check my edit
    – Majenko
    Dec 29, 2015 at 14:43
  • Excellent, that did it! So I'm getting a character via the UART and what I really wanted was the Integer Unicode representation of that character which ord() solves. One step at a time...
    – Dejvid_no1
    Dec 29, 2015 at 15:29

Your Answer

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

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