is there a problem on this simple code

D

Dennis Lee Bieber

Brain fart... unpack converts the raw bytes to integer
values with the "B" format character. You're thinking
of what would happen with a "1c" format.
Ah, right... I think a bit of C crept into my mind last night...

Though unpack may still be overkill for a 1-byte item... would
ord() be suitable? Or does it encounter high-bit encoding problems with
the encroachment of UTF handling? (and chr() for the other direction of
1-byte items)


--
 
D

Dennis Lee Bieber

@ sir Peter
so you mean that it is correct (at least on the unpack() part)

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...
Have you considered NOT running it from IDLE (use IDLE for
editing, save edited file)... Open a command prompt and set it to the
side of the screen, CD to the directory of your source file, and run it
via "python <whatever.py>"

That should get any IDLE overhead out of the way, and should
also let any "regular" output show up in realtime...

Except for very small programs, this has become my normal mode
of operation, as there is no confusion over whether stdin/stdout are
"real" console, or something passed through another layer...


--
 
J

John Machin

Jan said:
@ 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
 
J

jrlen balane

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 'int'>

but here:

2)rx_data_command = ser.read()
(rx_command) = unpack('1B', rx_data_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...
 
J

John Machin

jrlen said:
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 'int'>

but here:

2)rx_data_command = ser.read()

Are you sure you have really have read() -- which will read all
available data -- or read(1) -- which will read just one byte???
(rx_command) = unpack('1B', rx_data_command)

<type 'tuple'>

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

unpack returns a tuple. In 1) you unpack it. In 2) you don't unpack it.

either do this:

(rx_command,) = unpack('1B', rx_data_command) # unpack tuple

or this:

rx_command = unpack('1B', rx_data_command)[0] # grab 1st element of
tuple

or, simply, to get what you want, just do this:

rx_command = ord(ser.read(1))
@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...

It wasn't doing that before; In the second posting with examples, there
were some that were a MIXTURE of (a) 70 as the first byte of 10 (b) 70
as the fourth byte of 10 (128 128 103 70 2 6 64 64 192 0)
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.

How large is 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.

OK, so NOW you are saying that the microcontroller is pumping out data
continuously, it's not one response to each of your "67" commands???

In that case what I'd suggest you do is to read 19 bytes from the
serial port (with time-out, I'd suggest; give up if you don't get 19
bytes returned), and for each k in range(9), test for:

(a) byte[k] == 70
(b) byte[k+2] == 6
(c) checksum(byte[k:k+10]) == 0

If you don't get a valid data packet, give up.

This should snatch one valid data packet (if there are any) from the
torrent.
 
J

jrlen balane

@sir John
could you please show me how to do this exactly? it's in the "tip of
my toungue" but i just can get it, please...


jrlen said:
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 'int'>

but here:

2)rx_data_command = ser.read()

Are you sure you have really have read() -- which will read all
available data -- or read(1) -- which will read just one byte???
(rx_command) = unpack('1B', rx_data_command)

<type 'tuple'>

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

unpack returns a tuple. In 1) you unpack it. In 2) you don't unpack it.

either do this:

(rx_command,) = unpack('1B', rx_data_command) # unpack tuple

or this:

rx_command = unpack('1B', rx_data_command)[0] # grab 1st element of
tuple

or, simply, to get what you want, just do this:

rx_command = ord(ser.read(1))
@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...

It wasn't doing that before; In the second posting with examples, there
were some that were a MIXTURE of (a) 70 as the first byte of 10 (b) 70
as the fourth byte of 10 (128 128 103 70 2 6 64 64 192 0)
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.

How large is 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.

OK, so NOW you are saying that the microcontroller is pumping out data
continuously, it's not one response to each of your "67" commands???

In that case what I'd suggest you do is to read 19 bytes from the
serial port (with time-out, I'd suggest; give up if you don't get 19
bytes returned), and for each k in range(9), test for:

(a) byte[k] == 70
(b) byte[k+2] == 6
(c) checksum(byte[k:k+10]) == 0

If you don't get a valid data packet, give up.

This should snatch one valid data packet (if there are any) from the
torrent.
 
J

John Machin

jrlen said:
@sir John
could you please show me how to do this exactly? it's in the "tip of
my toungue" but i just can get it, please...

You've had far too much help already for a school project. Asking for
someone to write the code for you is "over the fence".
 
D

Dennis Lee Bieber

You've had far too much help already for a school project. Asking for
someone to write the code for you is "over the fence".

The repetition /is/ getting tedious, isn't it...

At the least, getting a formal definition of the protocol the
microcontroller uses would be nice. If it is continuously sending "70"
status reports, WITHOUT handshaking (RTS/CTS), then I'd strongly
recommend making the reader code a separate thread -- hopefully one
won't lose bytes during other processing. When a valid status report is
found, put it onto a Queue, which the main code can read when ever it
finds time.

Heck, at this point in time... I'd remove everything involved
with /sending/ commands. Start with coding something that only reads the
status from the microcontroller (since it sounds like the controller is
always sending). When the reader works correctly, then start trying to
add the command writer.

--
 
J

jrlen balane

rx_data = ser.read(19)
byte[] = unpack('19B', rx_data)

for k in range(9):
if byte[k] == 70
if byte[k+2] == 6
if byte[k+9] ==
-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff
print byte[k:k+9]
====================================
what i am doing here is creating an array from based on the unpacked data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my received
data from that point. then if the succeding tests are confirmed, i can
get my data.

please help....(again) :(
 
J

jrlen balane

did some editing:

rx_data = ser.read(19)
byte[0:18] = unpack('19B', rx_data)

for k in range(9):
if byte[k] == 70:
if byte[k+2] == 6:
if byte[k+9] ==
-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff:
print byte[k:k+9]
====================================
heres the error:
Traceback (most recent call last):
File "C:\Python23\practices\serialnewesttest2.py", line 28, in -toplevel-
byte[0:18] = unpack('19B', rx_data)
error: unpack str size does not match format

what i am doing here is creating an array from based on the unpacked data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my received
data from that point. then if the succeding tests are confirmed, i can
get my data.

please help....(again) :(
 
J

John Machin

jrlen said:
did some editing:

The error means that you received less than 19 bytes of data.
rx_data = ser.read(19)
!rx_len = len(rx_data)
!print 'rx_len', rx_len
byte[0:18] = unpack('19B', rx_data)
!# trash the above, do this
!byte = [ord(x) for x in rx_data]
!print 'received', byte
!if rx_len < 10:
! print 'it is not pumping data out as fast as we assumed!'
! sys.exit(1)
!for k in range(rx_len - 9):
if byte[k] == 70:
if byte[k+2] == 6:
if byte[k+9] ==
-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff:

Yuk!

(1) use 'and'
(2) when you find yourself typing repetitive crap like that, your brain
should be shrieking "There must be a better way!!"

if byte[k] == 70 \
and byte[k+2] == 6 \
and sum(byte[k:k+10]) & 0xff == 0:


print byte[k:k+9] <<<<<<=== you probably mean 10, not nine
====================================
heres the error:
Traceback (most recent call last):
File "C:\Python23\practices\serialnewesttest2.py", line 28, in -toplevel-
byte[0:18] = unpack('19B', rx_data)
error: unpack str size does not match format

what i am doing here is creating an array from based on the unpacked data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my received
data from that point. then if the succeding tests are confirmed, i can
get my data.

please help....(again) :(
 
J

jrlen balane

will this be correct???
what i want to happen is saved every received data (6 data bytes) to
an array for each one.

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])

if time.sleep(300) == True:
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

and after x minutes of of receiving data, the arrays will be emptied
of its contents.

thanks again for the help.
jrlen said:
did some editing:

The error means that you received less than 19 bytes of data.
rx_data = ser.read(19)
!rx_len = len(rx_data)
!print 'rx_len', rx_len
byte[0:18] = unpack('19B', rx_data)
!# trash the above, do this
!byte = [ord(x) for x in rx_data]
!print 'received', byte
!if rx_len < 10:
! print 'it is not pumping data out as fast as we assumed!'
! sys.exit(1)
!for k in range(rx_len - 9):
if byte[k] == 70:
if byte[k+2] == 6:
if byte[k+9] ==
-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff:

Yuk!

(1) use 'and'
(2) when you find yourself typing repetitive crap like that, your brain
should be shrieking "There must be a better way!!"

if byte[k] == 70 \
and byte[k+2] == 6 \
and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+9] <<<<<<=== you probably mean 10, not nine
====================================
heres the error:
Traceback (most recent call last):
File "C:\Python23\practices\serialnewesttest2.py", line 28, in -toplevel-
byte[0:18] = unpack('19B', rx_data)
error: unpack str size does not match format

what i am doing here is creating an array from based on the unpacked data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my received
data from that point. then if the succeding tests are confirmed, i can
get my data.

please help....(again) :(
 
J

jrlen balane

ok heres the code, i'm trying on IDLE:

import sys
import serial
import sys, os
import serial
import string
import time
from struct import *

data_file = open('C:/Documents and Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

ser = serial.Serial()
ser.baudrate = 9600
ser.port = 0
ser

ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

while( current_time >= start_time + 300):

data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current

current_time = time.time()

while theres no error in the output, there is also no response from
the hardware or maybe communication is off.

could somebody out there help me.

by the way, here is a working code: though here the data to be
transmitted is just incrementing and not read from a text file:

import serial
import string
import time
from struct import *
import os

ser = serial.Serial()

ser.baudrate = 9600
ser.port = 0
ser.timeout = 1
ser


ser.open()
tx_command = 67
tx_message_no = 1
tx_no_databyte = 2
item=10000
for item in range(10000, 30001, 10):

data_hi, data_lo = divmod(item, 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no +
tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no, tx_no_databyte,
data_lo, data_hi, tx_checksum))
#print tx_command, tx_message_no, tx_total_data, data_lo, data_hi,
tx_checksum


rx_data = ser.read(19)
rx_len = len(rx_data)
#print 'rx_len', rx_len
byte = [ord(x) for x in rx_data]
#print 'received', byte


if rx_len < 10:
print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+10]
===================================
outputs:
[70, 2, 6, 54, 197, 253, 230, 231, 211, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
....
....

will this be correct???
what i want to happen is saved every received data (6 data bytes) to
an array for each one.

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])

if time.sleep(300) == True:
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

and after x minutes of of receiving data, the arrays will be emptied
of its contents.

thanks again for the help.
jrlen said:
did some editing:

The error means that you received less than 19 bytes of data.
rx_data = ser.read(19)
!rx_len = len(rx_data)
!print 'rx_len', rx_len
byte[0:18] = unpack('19B', rx_data)
!# trash the above, do this
!byte = [ord(x) for x in rx_data]
!print 'received', byte
!if rx_len < 10:
! print 'it is not pumping data out as fast as we assumed!'
! sys.exit(1)
!for k in range(rx_len - 9):
if byte[k] == 70:
if byte[k+2] == 6:
if byte[k+9] ==
-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff:

Yuk!

(1) use 'and'
(2) when you find yourself typing repetitive crap like that, your brain
should be shrieking "There must be a better way!!"

if byte[k] == 70 \
and byte[k+2] == 6 \
and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+9] <<<<<<=== you probably mean 10, not nine
====================================
heres the error:
Traceback (most recent call last):
File "C:\Python23\practices\serialnewesttest2.py", line 28, in -toplevel-
byte[0:18] = unpack('19B', rx_data)
error: unpack str size does not match format

what i am doing here is creating an array from based on the unpacked data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my received
data from that point. then if the succeding tests are confirmed, i can
get my data.

please help....(again) :(
 
J

jrlen balane

please post your suggestions? please ...


ok heres the code, i'm trying on IDLE:

import sys
import serial
import sys, os
import serial
import string
import time
from struct import *

data_file = open('C:/Documents and Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

ser = serial.Serial()
ser.baudrate = 9600
ser.port = 0
ser

ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

while( current_time >= start_time + 300):

data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current

current_time = time.time()

while theres no error in the output, there is also no response from
the hardware or maybe communication is off.

could somebody out there help me.

by the way, here is a working code: though here the data to be
transmitted is just incrementing and not read from a text file:

import serial
import string
import time
from struct import *
import os

ser = serial.Serial()

ser.baudrate = 9600
ser.port = 0
ser.timeout = 1
ser

ser.open()
tx_command = 67
tx_message_no = 1
tx_no_databyte = 2
item=10000
for item in range(10000, 30001, 10):

data_hi, data_lo = divmod(item, 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no +
tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no, tx_no_databyte,
data_lo, data_hi, tx_checksum))
#print tx_command, tx_message_no, tx_total_data, data_lo, data_hi,
tx_checksum


rx_data = ser.read(19)
rx_len = len(rx_data)
#print 'rx_len', rx_len
byte = [ord(x) for x in rx_data]
#print 'received', byte

if rx_len < 10:
print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+10]
===================================
outputs:
[70, 2, 6, 54, 197, 253, 230, 231, 211, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
...
...

will this be correct???
what i want to happen is saved every received data (6 data bytes) to
an array for each one.

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])

if time.sleep(300) == True:
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

and after x minutes of of receiving data, the arrays will be emptied
of its contents.

thanks again for the help.
jrlen balane wrote:
did some editing:


The error means that you received less than 19 bytes of data.

rx_data = ser.read(19)
!rx_len = len(rx_data)
!print 'rx_len', rx_len
byte[0:18] = unpack('19B', rx_data)
!# trash the above, do this
!byte = [ord(x) for x in rx_data]
!print 'received', byte
!if rx_len < 10:
! print 'it is not pumping data out as fast as we assumed!'
! sys.exit(1)

!for k in range(rx_len - 9):
if byte[k] == 70:
if byte[k+2] == 6:
if byte[k+9] ==

-(byte[k]+byte[k+1]+byte[k+2]+byte[k+3]+byte[k+4]+byte[k+5]+byte[k+6]+byte[k+7]+byte[k+8])
& 0xff:

Yuk!

(1) use 'and'
(2) when you find yourself typing repetitive crap like that, your brain
should be shrieking "There must be a better way!!"

if byte[k] == 70 \
and byte[k+2] == 6 \
and sum(byte[k:k+10]) & 0xff == 0:

print byte[k:k+9] <<<<<<=== you probably mean 10,
not nine
====================================
heres the error:
Traceback (most recent call last):
File "C:\Python23\practices\serialnewesttest2.py", line 28, in
-toplevel-
byte[0:18] = unpack('19B', rx_data)
error: unpack str size does not match format

what i am doing here is creating an array from based on the unpacked
data
then i am searching for the array member that is equal to "70" since
it is going to be my reference. once i find it, i'll based my
received
data from that point. then if the succeding tests are confirmed, i
can
get my data.

please help....(again) :(
 
J

John Machin

jrlen balane wrote:

[from further down in the message]
could somebody out there help me.

You could try helping yourself. Insert some print statements at salient
points. [see examples below; you'll need to get the indentation
correct, of course] Try to understand what is happening.
ok heres the code, i'm trying on IDLE:

import sys
import serial
import sys, os
import serial
import string
import time
from struct import *

data_file = open('C:/Documents and
Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

ser = serial.Serial()
ser.baudrate = 9600
ser.port = 0
ser

I'll ask, for the 3rd time, what the @#$% is the above line meant to
achieve?
ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

print 'before while stmt', j, start_time, current time
while( current_time >= start_time + 300):

print 'inside while stmt', j, start_time, current time

data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current

current_time = time.time()

print 'after while stmt', j, start_time, current time
 
T

Tim Roberts

jrlen balane said:
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 'int'>

but here:

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

<type 'tuple'>

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

Did you get an answer to this? I couldn't see any responses. The answer
is either:

rx_command = unpack('1B', rx_data_command)[0]

or

(rx_command,) = unpack('1B', rx_data_command)
 
D

Dennis Lee Bieber

please post your suggestions? please ...
Since we don't have your hardware, nor have you been able supply
the formal documentation of the protocol in use, all we can do is
comment on coding styles and obvious errors in the code... If there is
an flaw in the implementation of the protocol, we have no way to tell.

How about cleaning that up... You've imported serial twice, and
sys twice.
data_file = open('C:/Documents and Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

Well, this is legal, though confusing to stuff a function
definition between lines of the main program. Common is to put the
"def"s after the "imports" (though defining "constants" may be okay in
there)

If "process" is only used once, it might not even be worth the
"def"...
Delete that -- you've been told that it is meaningless for days
now... If you don't want to take advice, why ask?
ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

while( current_time >= start_time + 300):
If current time is < start+300, the entire loop will be skipped
-- a condition that is quite likely to happen unless you have a /very/
slow machine.
data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current
All these are lists, do you really mean to print the entire list
each time, or only the most recent data value?
current_time = time.time()

while theres no error in the output, there is also no response from
the hardware or maybe communication is off.

could somebody out there help me.

by the way, here is a working code: though here the data to be
transmitted is just incrementing and not read from a text file:

import serial
import string
import time
from struct import *
import os

ser = serial.Serial()

ser.baudrate = 9600
ser.port = 0
ser.timeout = 1
ser

ser.open()
tx_command = 67
tx_message_no = 1
tx_no_databyte = 2
item=10000
for item in range(10000, 30001, 10):

data_hi, data_lo = divmod(item, 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no +
tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no, tx_no_databyte,
data_lo, data_hi, tx_checksum))
#print tx_command, tx_message_no, tx_total_data, data_lo, data_hi,
tx_checksum


rx_data = ser.read(19)
rx_len = len(rx_data)
#print 'rx_len', rx_len
byte = [ord(x) for x in rx_data]
#print 'received', byte

if rx_len < 10:
print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+10]
===================================
outputs:
[70, 2, 6, 54, 197, 253, 230, 231, 211, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
...
...

And please trim... You don't need to quote the same text over
and over... We've all seen it by now, or can retrieve it using the
message headers.

-=-=-=-=-=-=-=-=-=-=-=-=-
"""
EVERYTHING THAT FOLLOWS IS THE RESULT OF "FREE ASSOCIATION"
THINKING. NONE OF IT HAS BEEN TESTED FOR CORRECTNESS OF
SYNTAX OR SEMANTICS -- IT SHOULD BEST BE CONSIDERED PSEUDO-
CODE, GIVING A GUIDELINE FROM WHICH TO PROCEED WITH REAL
DEVELOPMENT
"""

import serial #I don't have this, and don't have your hardware,
#so this is all guesswork, and untested
import os
import sys
import time
import threading
import Queue

DATA_FID = r"C:\\Documents and Settings\\nyer\\Desktop\\IRRADIANCE.txt"
#I definitely don't have a "nyer" user <G>

class DeviceHandler(object):
def _checksum(packet):
# compute checksum from packet (which should be a list)
return -sum(packet) & 0xFF

def _Reader(self):
# worker code for the reader /thread/, continuous
# loop, reading response packets and putting them
# (or some error message string) onto the queue
while 1:
# accept first three as response code, message count
# and data length
response = ord(self._ser.read(1))
count = ord(self._ser.read(1))
length = ord(self._ser.read(1))
# get the data bytes
data = []
for x in range(length):
data.append(ord(self._ser.read(1)))
# get the message checksum
check = ord(self._ser.read(1))
# format it all as a packet list
packet = [response, count, length] + data
packet = packet.append(check)
# check for out of sequence packet
if count != self._RX_count:
# notify via queue, then reset expected counter
self._queue.put("Receive packet number is out of
sequence")
self._RX_count = count
# confirm checksome and notify if needed
if _checksum(packet) != 0:
self._queue.put("Receive packet checksum is invalid")
# put the packet, regardless of validity, onto queu
self._queue.put(packet)
self._RX_count += 1 & 0xFF #quick & dirty modulo 256

def __init__(self, port, rate, queue):
# initialize handler instance
self._TX_count = 0
self._RX_count = 0
self._ser = serial.Serial()
self._ser.port = port
self._ser.baudrate = rate
self._ser.open()
self._queue = queue
self._reader = threading.Thread(target=self._Reader())
# make the reading thread a daemon, so it won't block
# main program from exiting
self._reader.setDaemon(True)
self._reader.start()

def close(self):
self.ser.close()

def sendPacket(self, Command=0x00, Data = None):
# format a packet list from input data
packet = [Command, self._TX_count, len(Data)] + Data
# append checksum
packet.append(self._checksum(packet))
# convert to string format -- all data better be
# 0x00 - 0xFF
output = "".join([chr(x) for x in packet])
self._ser.write(output)
# increment output counter
self._TX_count += 1 & 0xFF

# MAIN PROGRAM STARTS HERE
fdata = open(DATA_FID, "r")

# create response transfer queue, and serial port handler instance
myQ = Queue.Queue()
myDevice = DeviceHandler(port = 0, rate = 9600, queue = myQ)

for ln in fdata:
# NOTE: no TIMING of command output is performed, they
# go out as fast as the response queue can be emptied
# reset response data array
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

# extract all responses that have been received up to now
# note: this is NOT a loop until empty, only for whatever
# was available at the start of this pass
for i in range(myQ.qsize()):
resp = myQ.get_nowait()
if type(resp) is types.StringType:
print "Bad response packet: %s" % resp
elif resp[2] != 6 or resp[0] != 0x70:
print "Unexpected response:"
print " Code = %s\tCount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print " Data = ",
for j in range(resp[2]):
print resp[j + 3],
print "\tChecksum = %s" % resp[resp[2] +3]
else:
# capture data field
temp1.append(resp[3])
temp2.append(resp[4])
pyra1.append(resp[5])
pyra2.append(resp[6])
voltage.append(resp[7])
current.append(resp[8])
# display current data
print "Code = %s\tcount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print "temp1 = %s\ttemp2 = %s" % (resp[3], resp[4])
print "pyra1 = %s\tpyra2 = %s" % (resp[5], resp[6])
print "voltage = %s\tcurrent = %s" % (resp[7], resp[8])
print "\tchecksum = %s" % resp[9]

# process one input data value
dvalue = int(ln)
(d_high, d_low) = divmod(dvalue, 0x100)

# send the packet
myDevice.sendPacket(Command = 0x67, Data = [d_high, d_low])

#what do you want to do with the arrays that built up, as they get
#reset on the next loop pass
print "temp1", temp1
print "temp2", temp2
print "pyra1", pyra1
print "pyra2", pyra2
print "voltage", voltage
print "current", current

# end of input file, close file and exit
# NOTE: does not wait for response data to catch up
fdata.close()
myDevice.close()

-=-=-=-=-=-=-=-=-=-=-

Explore that and see if you can understand the modularization
(minimal) and processing logic.

--
 
J

jrlen balane

a simple question regarding threading and timer:

if i put my timer control inside the thread, will the thread be exited
every time there is a timer event???

please help...

def someThreadHere()
...
someTimer.start(3000)
....

def someTimerEvent()
.....



please post your suggestions? please ...
Since we don't have your hardware, nor have you been able supply
the formal documentation of the protocol in use, all we can do is
comment on coding styles and obvious errors in the code... If there is
an flaw in the implementation of the protocol, we have no way to tell.

How about cleaning that up... You've imported serial twice, and
sys twice.
data_file = open('C:/Documents and Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

Well, this is legal, though confusing to stuff a function
definition between lines of the main program. Common is to put the
"def"s after the "imports" (though defining "constants" may be okay in
there)

If "process" is only used once, it might not even be worth the
"def"...
Delete that -- you've been told that it is meaningless for days
now... If you don't want to take advice, why ask?
ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

while( current_time >= start_time + 300):
If current time is < start+300, the entire loop will be skipped
-- a condition that is quite likely to happen unless you have a /very/
slow machine.
data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current
All these are lists, do you really mean to print the entire list
each time, or only the most recent data value?
current_time = time.time()

while theres no error in the output, there is also no response from
the hardware or maybe communication is off.

could somebody out there help me.

by the way, here is a working code: though here the data to be
transmitted is just incrementing and not read from a text file:

import serial
import string
import time
from struct import *
import os

ser = serial.Serial()

ser.baudrate = 9600
ser.port = 0
ser.timeout = 1
ser

ser.open()
tx_command = 67
tx_message_no = 1
tx_no_databyte = 2
item=10000
for item in range(10000, 30001, 10):

data_hi, data_lo = divmod(item, 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no +
tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no, tx_no_databyte,
data_lo, data_hi, tx_checksum))
#print tx_command, tx_message_no, tx_total_data, data_lo, data_hi,
tx_checksum


rx_data = ser.read(19)
rx_len = len(rx_data)
#print 'rx_len', rx_len
byte = [ord(x) for x in rx_data]
#print 'received', byte

if rx_len < 10:
print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+10]
===================================
outputs:
[70, 2, 6, 54, 197, 253, 230, 231, 211, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
...
...

And please trim... You don't need to quote the same text over
and over... We've all seen it by now, or can retrieve it using the
message headers.

-=-=-=-=-=-=-=-=-=-=-=-=-
"""
EVERYTHING THAT FOLLOWS IS THE RESULT OF "FREE ASSOCIATION"
THINKING. NONE OF IT HAS BEEN TESTED FOR CORRECTNESS OF
SYNTAX OR SEMANTICS -- IT SHOULD BEST BE CONSIDERED PSEUDO-
CODE, GIVING A GUIDELINE FROM WHICH TO PROCEED WITH REAL
DEVELOPMENT
"""

import serial #I don't have this, and don't have your hardware,
#so this is all guesswork, and untested
import os
import sys
import time
import threading
import Queue

DATA_FID = r"C:\\Documents and Settings\\nyer\\Desktop\\IRRADIANCE.txt"
#I definitely don't have a "nyer" user <G>

class DeviceHandler(object):
def _checksum(packet):
# compute checksum from packet (which should be a list)
return -sum(packet) & 0xFF

def _Reader(self):
# worker code for the reader /thread/, continuous
# loop, reading response packets and putting them
# (or some error message string) onto the queue
while 1:
# accept first three as response code, message count
# and data length
response = ord(self._ser.read(1))
count = ord(self._ser.read(1))
length = ord(self._ser.read(1))
# get the data bytes
data = []
for x in range(length):
data.append(ord(self._ser.read(1)))
# get the message checksum
check = ord(self._ser.read(1))
# format it all as a packet list
packet = [response, count, length] + data
packet = packet.append(check)
# check for out of sequence packet
if count != self._RX_count:
# notify via queue, then reset expected counter
self._queue.put("Receive packet number is out of
sequence")
self._RX_count = count
# confirm checksome and notify if needed
if _checksum(packet) != 0:
self._queue.put("Receive packet checksum is invalid")
# put the packet, regardless of validity, onto queu
self._queue.put(packet)
self._RX_count += 1 & 0xFF #quick & dirty modulo 256

def __init__(self, port, rate, queue):
# initialize handler instance
self._TX_count = 0
self._RX_count = 0
self._ser = serial.Serial()
self._ser.port = port
self._ser.baudrate = rate
self._ser.open()
self._queue = queue
self._reader = threading.Thread(target=self._Reader())
# make the reading thread a daemon, so it won't block
# main program from exiting
self._reader.setDaemon(True)
self._reader.start()

def close(self):
self.ser.close()

def sendPacket(self, Command=0x00, Data = None):
# format a packet list from input data
packet = [Command, self._TX_count, len(Data)] + Data
# append checksum
packet.append(self._checksum(packet))
# convert to string format -- all data better be
# 0x00 - 0xFF
output = "".join([chr(x) for x in packet])
self._ser.write(output)
# increment output counter
self._TX_count += 1 & 0xFF

# MAIN PROGRAM STARTS HERE
fdata = open(DATA_FID, "r")

# create response transfer queue, and serial port handler instance
myQ = Queue.Queue()
myDevice = DeviceHandler(port = 0, rate = 9600, queue = myQ)

for ln in fdata:
# NOTE: no TIMING of command output is performed, they
# go out as fast as the response queue can be emptied
# reset response data array
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

# extract all responses that have been received up to now
# note: this is NOT a loop until empty, only for whatever
# was available at the start of this pass
for i in range(myQ.qsize()):
resp = myQ.get_nowait()
if type(resp) is types.StringType:
print "Bad response packet: %s" % resp
elif resp[2] != 6 or resp[0] != 0x70:
print "Unexpected response:"
print " Code = %s\tCount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print " Data = ",
for j in range(resp[2]):
print resp[j + 3],
print "\tChecksum = %s" % resp[resp[2] +3]
else:
# capture data field
temp1.append(resp[3])
temp2.append(resp[4])
pyra1.append(resp[5])
pyra2.append(resp[6])
voltage.append(resp[7])
current.append(resp[8])
# display current data
print "Code = %s\tcount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print "temp1 = %s\ttemp2 = %s" % (resp[3], resp[4])
print "pyra1 = %s\tpyra2 = %s" % (resp[5], resp[6])
print "voltage = %s\tcurrent = %s" % (resp[7], resp[8])
print "\tchecksum = %s" % resp[9]

# process one input data value
dvalue = int(ln)
(d_high, d_low) = divmod(dvalue, 0x100)

# send the packet
myDevice.sendPacket(Command = 0x67, Data = [d_high, d_low])

#what do you want to do with the arrays that built up, as they get
#reset on the next loop pass
print "temp1", temp1
print "temp2", temp2
print "pyra1", pyra1
print "pyra2", pyra2
print "voltage", voltage
print "current", current

# end of input file, close file and exit
# NOTE: does not wait for response data to catch up
fdata.close()
myDevice.close()

-=-=-=-=-=-=-=-=-=-=-

Explore that and see if you can understand the modularization
(minimal) and processing logic.

--
============================================================== <
(e-mail address removed) | Wulfraed Dennis Lee Bieber KD6MOG <
(e-mail address removed) | Bestiaria Support Staff <
============================================================== <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <
 
J

jrlen balane

hi! could anyone give their input on my previous post about timer and
threading...]
pleaseee...

my program seemed to just run first the thread then when it encounters
error on the thread that's the time that other part of the program got
the chance to be executed
even the timer even is not executed while the thread is running


a simple question regarding threading and timer:

if i put my timer control inside the thread, will the thread be exited
every time there is a timer event???

please help...

def someThreadHere()
...
someTimer.start(3000)
....

def someTimerEvent()
.....

please post your suggestions? please ...
Since we don't have your hardware, nor have you been able supply
the formal documentation of the protocol in use, all we can do is
comment on coding styles and obvious errors in the code... If there is
an flaw in the implementation of the protocol, we have no way to tell.
import sys
import serial
import sys, os
import serial

How about cleaning that up... You've imported serial twice, and
sys twice.
data_file = open('C:/Documents and Settings/nyer/Desktop/IRRADIANCE.txt', 'r')
data = data_file.readlines()

def process(list_of_lines):
data_points = []
for line in list_of_lines:
data_points.append(int(line))
return data_points

irradiance = process(data)

Well, this is legal, though confusing to stuff a function
definition between lines of the main program. Common is to put the
"def"s after the "imports" (though defining "constants" may be okay in
there)

If "process" is only used once, it might not even be worth the
"def"...
ser = serial.Serial()
ser.baudrate = 9600
ser.port = 0
ser
Delete that -- you've been told that it is meaningless for days
now... If you don't want to take advice, why ask?
ser.open()
tx_command = 67
tx_no_databyte = 2
tx_message_no = 1
tx_len = len (irradiance)

for j in range (tx_len) :
start_time = time.time()

temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

current_time = time.time()

while( current_time >= start_time + 300):
If current time is < start+300, the entire loop will be skipped
-- a condition that is quite likely to happen unless you have a /very/
slow machine.
data_hi, data_lo = divmod(irradiance[j], 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no
+ tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no,
tx_no_databyte, data_lo, data_hi, tx_checksum))

rx_data = ser.read(19)
rx_len = len(rx_data)
byte = [ord(x) for x in rx_data]

if rx_len < 10:
#print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10])
& 0xff == 0:
#print byte[k:k+10]

temp1.append(byte[k+3])
temp2.append(byte[k+4])
pyra1.append(byte[k+5])
pyra2.append(byte[k+6])
voltage.append(byte[k+7])
current.append(byte[k+8])
print temp1, temp2, pyra1, pyra2, voltage, current
All these are lists, do you really mean to print the entire list
each time, or only the most recent data value?
current_time = time.time()

while theres no error in the output, there is also no response from
the hardware or maybe communication is off.

could somebody out there help me.
by the way, here is a working code: though here the data to be
transmitted is just incrementing and not read from a text file:

import serial
import string
import time
from struct import *
import os

ser = serial.Serial()

ser.baudrate = 9600
ser.port = 0
ser.timeout = 1
ser

ser.open()
tx_command = 67
tx_message_no = 1
tx_no_databyte = 2
item=10000
for item in range(10000, 30001, 10):

data_hi, data_lo = divmod(item, 0x100)
tx_checksum = -(data_hi + data_lo + tx_command + tx_message_no +
tx_no_databyte) & 0xff
ser.write(pack('6B', tx_command, tx_message_no, tx_no_databyte,
data_lo, data_hi, tx_checksum))
#print tx_command, tx_message_no, tx_total_data, data_lo, data_hi,
tx_checksum


rx_data = ser.read(19)
rx_len = len(rx_data)
#print 'rx_len', rx_len
byte = [ord(x) for x in rx_data]
#print 'received', byte

if rx_len < 10:
print 'it is not pumping data out as fast as we assumed'
sys.exit(1)

for k in range (rx_len-9):
if byte[k] == 70 and byte [k+2] == 6 and sum(byte[k:k+10]) & 0xff == 0:
print byte[k:k+10]
===================================
outputs:
[70, 2, 6, 54, 197, 253, 230, 231, 211, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
[70, 3, 6, 54, 197, 253, 230, 231, 210, 26]
[70, 3, 6, 54, 197, 253, 230, 231, 211, 25]
...
...

And please trim... You don't need to quote the same text over
and over... We've all seen it by now, or can retrieve it using the
message headers.

-=-=-=-=-=-=-=-=-=-=-=-=-
"""
EVERYTHING THAT FOLLOWS IS THE RESULT OF "FREE ASSOCIATION"
THINKING. NONE OF IT HAS BEEN TESTED FOR CORRECTNESS OF
SYNTAX OR SEMANTICS -- IT SHOULD BEST BE CONSIDERED PSEUDO-
CODE, GIVING A GUIDELINE FROM WHICH TO PROCEED WITH REAL
DEVELOPMENT
"""

import serial #I don't have this, and don't have your hardware,
#so this is all guesswork, and untested
import os
import sys
import time
import threading
import Queue

DATA_FID = r"C:\\Documents and Settings\\nyer\\Desktop\\IRRADIANCE.txt"
#I definitely don't have a "nyer" user <G>

class DeviceHandler(object):
def _checksum(packet):
# compute checksum from packet (which should be a list)
return -sum(packet) & 0xFF

def _Reader(self):
# worker code for the reader /thread/, continuous
# loop, reading response packets and putting them
# (or some error message string) onto the queue
while 1:
# accept first three as response code, message count
# and data length
response = ord(self._ser.read(1))
count = ord(self._ser.read(1))
length = ord(self._ser.read(1))
# get the data bytes
data = []
for x in range(length):
data.append(ord(self._ser.read(1)))
# get the message checksum
check = ord(self._ser.read(1))
# format it all as a packet list
packet = [response, count, length] + data
packet = packet.append(check)
# check for out of sequence packet
if count != self._RX_count:
# notify via queue, then reset expected counter
self._queue.put("Receive packet number is out of
sequence")
self._RX_count = count
# confirm checksome and notify if needed
if _checksum(packet) != 0:
self._queue.put("Receive packet checksum is invalid")
# put the packet, regardless of validity, onto queu
self._queue.put(packet)
self._RX_count += 1 & 0xFF #quick & dirty modulo 256

def __init__(self, port, rate, queue):
# initialize handler instance
self._TX_count = 0
self._RX_count = 0
self._ser = serial.Serial()
self._ser.port = port
self._ser.baudrate = rate
self._ser.open()
self._queue = queue
self._reader = threading.Thread(target=self._Reader())
# make the reading thread a daemon, so it won't block
# main program from exiting
self._reader.setDaemon(True)
self._reader.start()

def close(self):
self.ser.close()

def sendPacket(self, Command=0x00, Data = None):
# format a packet list from input data
packet = [Command, self._TX_count, len(Data)] + Data
# append checksum
packet.append(self._checksum(packet))
# convert to string format -- all data better be
# 0x00 - 0xFF
output = "".join([chr(x) for x in packet])
self._ser.write(output)
# increment output counter
self._TX_count += 1 & 0xFF

# MAIN PROGRAM STARTS HERE
fdata = open(DATA_FID, "r")

# create response transfer queue, and serial port handler instance
myQ = Queue.Queue()
myDevice = DeviceHandler(port = 0, rate = 9600, queue = myQ)

for ln in fdata:
# NOTE: no TIMING of command output is performed, they
# go out as fast as the response queue can be emptied
# reset response data array
temp1 = []
temp2 = []
pyra1 = []
pyra2 = []
voltage = []
current = []

# extract all responses that have been received up to now
# note: this is NOT a loop until empty, only for whatever
# was available at the start of this pass
for i in range(myQ.qsize()):
resp = myQ.get_nowait()
if type(resp) is types.StringType:
print "Bad response packet: %s" % resp
elif resp[2] != 6 or resp[0] != 0x70:
print "Unexpected response:"
print " Code = %s\tCount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print " Data = ",
for j in range(resp[2]):
print resp[j + 3],
print "\tChecksum = %s" % resp[resp[2] +3]
else:
# capture data field
temp1.append(resp[3])
temp2.append(resp[4])
pyra1.append(resp[5])
pyra2.append(resp[6])
voltage.append(resp[7])
current.append(resp[8])
# display current data
print "Code = %s\tcount = %s\tLength = %s" % (resp[0],
resp[1],
resp[2])
print "temp1 = %s\ttemp2 = %s" % (resp[3], resp[4])
print "pyra1 = %s\tpyra2 = %s" % (resp[5], resp[6])
print "voltage = %s\tcurrent = %s" % (resp[7], resp[8])
print "\tchecksum = %s" % resp[9]

# process one input data value
dvalue = int(ln)
(d_high, d_low) = divmod(dvalue, 0x100)

# send the packet
myDevice.sendPacket(Command = 0x67, Data = [d_high, d_low])

#what do you want to do with the arrays that built up, as they get
#reset on the next loop pass
print "temp1", temp1
print "temp2", temp2
print "pyra1", pyra1
print "pyra2", pyra2
print "voltage", voltage
print "current", current

# end of input file, close file and exit
# NOTE: does not wait for response data to catch up
fdata.close()
myDevice.close()

-=-=-=-=-=-=-=-=-=-=-

Explore that and see if you can understand the modularization
(minimal) and processing logic.

--
============================================================== <
(e-mail address removed) | Wulfraed Dennis Lee Bieber KD6MOG <
(e-mail address removed) | Bestiaria Support Staff <
============================================================== <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <
 
P

Peter Hansen

jrlen said:
hi! could anyone give their input on my previous post about timer and
threading...]
pleaseee...

A few bits of unrequested advice which might help you get
more and better responses (though the ones you have got
in the past already appear to be above and beyond the call
of duty, given your apparent lack of actually following
advice you are given):

1. It's most annoying that you are not taking even a bit
of time to "prune" the useless quoted material from your
messages (notice how I've done it in this one). From
a netiquette point of view, that's considered rude and reduces
the level of respect you will be shown.

1.5. Don't "top-post"! That's when you put your reply
*above* the material you are replying to, and it's very
frustrating and against widely followed conventions.
Take the time to prune quoted material to the minimum,
then add your comments inline as I've done in this
message, not all at the top.

1.6. Always start a new thread when you have a new request.
One reason you might not have got replies to this latest
request yet is that you posted it as a followup to the
previous thread. Many people have already done their
version of "hitting the 'k' key" and killed the thread,
meaning they won't see any additional messages that are
posted in reply to existing messages in this thread.

2. Pay closer attention to the requests you get from those
trying to help you. For example, you were asked a number
of times to clean up some of the unnecessary or confusing
or redundant code in the programs you were posting, but
you never bothered. Here it looks like you are not willing
to make an effort.

3. Trust that in this newsgroup, more than perhaps almost
any other, if you don't get a reply it's not because nobody
read your message, and begging will just annoy people. In
any event, be patient, then assume that your request was
inadequate in some way and don't just try reposting, try
instead to figure out what you did wrong and when you post
again, *improve* your request in some way. It might help
if you study and follow some of the advice in the essay at
http://www.catb.org/~esr/faqs/smart-questions.html .
my program seemed to just run first the thread then when it encounters
error on the thread that's the time that other part of the program got
the chance to be executed
even the timer even is not executed while the thread is running

I suspect the reason no one replied (and here I really hope
you'll refer to item 2. above), is that you didn't post
anything resembling working code, and out of context it's
unclear what you are talking about. There are dozens of
ways of interpreting your code and your request, and it's
impossible to guess exactly which you meant.

For example, it seems like you might have meant to say
"will the thread be executed" instead of "exited", but
I'm not sure.

And you don't show the imports you used, so nobody can
tell for sure whether you are referring to the "threading"
module and the "timer" module, or just to threading
and maybe timers in general. wxPython, for example,
also has a timer object.

More importantly, your code can't be executed, so
we're just shooting in the dark if we try to figure
out how you are getting "someTimerEvent" to execute,
if indeed it is a function. The "def" statements
don't have colons after them, so we're not even sure
you are asking about how to do something, or perhaps
you have code that is just not compiling because it
is syntactically incorrect.

In a nutshell, do the most you possibly can to help
us out, and you'll get timely and effective help.
Otherwise you may get silence, and "pleaseee" will
just sound like whining.

Please take this in the helpful spirit in which it
was intended.

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top