is there a problem on this simple code

John Machin sjmachin at lexicon.net
Sun Mar 13 16:06:16 EST 2005


Jan Rienyer Gadil wrote:
> @ sir Peter
> so you mean that it is correct (at least on the unpack() part)

No he doesn't mean that at all. All it means is that minor scuffles
have broken out among the spectators. Don't worry about them, batons &
water cannon will fix them; you concentrate on the football match :-)

>
> when i run this program on IDLE , Python 2.3 (enthought edition),
> nothing is outputted on the shell, until i decide to close the shell,
> wherein it tells me if i would like to kill a process...

So you did some elementary debugging, like putting in some print
statements at various places, as shown below, and what happened?

>
> import serial
> import string

Redundant.

> import time
> from struct import *
>
> ser = serial.Serial()
>
> ser.baudrate = 9600
> ser.port = 0
> ser

What is the above line meant to do? It actually does nothing.

> ser.close()
> ser.open()
>
> command = 67
> message_no = 1
> total_data = 2
>
> item = 10000

Redundant.
>

print "DEBUG: before outer loop"


> for item in range(10000, 30001, 250):

print "DEBUG: inside outer loop; item =", repr(item)

>    data_hi, data_lo = divmod(item, 0x100)
>    checksum = -(data_hi + data_lo + 0x46) & 0xff

You obviouly haven't taken the advice to generalise your checksum
calculation.

>    ser.write(pack('6B', command, message_no, total_data, data_lo,
>                 data_hi, checksum))
>
>    rx_data1=0

print "DEBUG: before inner loop"

>    while (rx_data1 != 0x46):
>            rx_data1 = ser.read(1)
>            (rx_command) = unpack('1B', rx_data1)

print "DEBUG: inside inner loop; rx_data1 =", repr(rx_data1), ";
rx_command =", repr(rx_command)

And if you had have done that, you would/should have realised that you
have a:
!! CODING BUG !!
ser.read(1) will return a STRING, so even if you get the byte you are
looking for, rx_data1 will refer to 'F' == chr(70) == chr(0x46) ==
'\x46' none of which are == 0x46, and you will loop forever (if the
hardware is continuously outputting data) or hang waiting for data from
the hardware.

!! DESIGN BUG !!
HOWEVER, as Dennis and I have been trying to tell you, it is WRONG to
be looping trying to sync on the first character in the packet. You
need to fix your data loss problem, not try to kludge your way around
it. I'll say it again, but only once: go back to the code of your
original posting. That code was not losing data. Among whatever else is
needed to revert to the first-shown code, put back the sleep() between
iterations.
As advised earlier, make sure that you use separate rx_command and
tx_command so that you don't accidentally start sending 70 as the
command.
Then show us what happened.

>     rx_data2=ser.read(9)
>     (rx_msg_no, rx_no_databyte, temp1, temp2, pyra1, pyra2, voltage,
>              current, rx_checksum) = unpack('9B', data)

!! CODING BUG !!
You read into "rx_data2" but unpack from "data". The result, when you
reach it after fixing the earlier bug, will be either an exception or
an utter nonsense, depending on what "data" is bound to at the time (if
anything).

>      print rx_command, rx_msg_no, rx_no_databyte, temp1, temp2,
pyra1,
>              pyra2, voltage, current, rx_checksum
>

You obviously haven't taken the advice from Dennis and myself to
validate the packet you receive -- (1) checksum is OK (2)
rx_no_databyte == 6

> ser.close()

HTH,
John




More information about the Python-list mailing list