is there a problem on this simple code

jrlen balane nbbalane at gmail.com
Mon Mar 14 15:33:03 EST 2005


why is it that here:

1)rx_data = ser.read(10)
    (rx_command, rx_msg_no, rx_no_databyte, temp1, temp2, pyra1,
pyra2, voltage, current, rx_checksum) = unpack('10B', rx_data)
    print rx_command, rx_msg_no, rx_no_databyte, temp1, temp2, pyra1,
pyra2, voltage, current, rx_checksum
 
>>> type (rx_command)
<type 'int'>

but here:

2)rx_data_command = ser.read()
    (rx_command) = unpack('1B', rx_data_command)

>>> type (rx_command)
<type 'tuple'>

how can i make rx_command of type 'int' if i am to use 2)?

@sir John
the reason why my first post all starts with '70' , which is what i
really wanted to happen, is that it is buffered. the microcontroller
sends data at a very fast rate, that the program just retrieve data
from the buffer. so basically, they are not "real time". but there are
also cases where the command is in other position. the good thing is,
it remains in that position throughout...

i want to make the program show data in "real time" so everytime i am
able to read data, i immediately use flushInput(), to erase data from
the buffer.

so i what i want to do now is to search for the rx_command first
('70') just so i know where my data should start.

the checksum will be validated, but first, i must know where my checksum is!
if (rx_checksum != -(temp1 + temp2 + pyra1 + pyra2 + voltage + current
+  rx_command +               rx_message_no + rx_no_databyte) & 0xff):
    #then discard message, loop again to search for rx_command

plase help...

On 13 Mar 2005 13:06:16 -0800, John Machin <sjmachin at lexicon.net> wrote:
> 
> 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
> 
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list