F
Frank Millman
Hi all
I am not sure if this question is about threading or serial i/o - it
has elements of both.
I want to capture the output from a hand-held scanner and write it to
a file. The scanner communicates with a base-station, which is
connected to the server via a serial port. The scanner is programmed
to input a code and quantity, and send the result directly to the
base-station in the form 'code' <tab> 'qty' <cr>.
Here is my first attempt - quick and dirty, but intended to prove the
concept.
#---------------------------------------------
import threading
x = 1
def main():
global x
print 'starting thread'
t = threading.Thread(target=scan)
t.start()
while x:
q = raw_input("Press 'q' to quit")
if q == 'q':
x = 0
print 'thread finished'
def scan():
p = file('/dev/ttyS0')
txt = []
while x:
ch = p.read(1)
if ord(ch) == 13:
print ''.join(txt)
txt = []
else:
txt.append(ch)
p.close()
print 'done'
if __name__ == '__main__':
main()
#---------------------------------------------
I use threading so that the user can control the program via the
keyboard at the same time as the program is reading the serial port.
It works ok, but I do not know how to stop it cleanly. When the user
presses 'q' to quit, it sets a variable to tell the thread to
terminate, but the thread is blocked at the read statement, so it does
not know it is supposed to terminate.
I can think of two theoretical solutions, but I do not know if either
of them are possible.
1. Turn the 'read' of the serial port into a 'non-blocking' read by
checking if there are any bytes waiting to be read before actually
issuing the read statement. I have done this in other languages, but I
cannot find anything in the Python documentation that explains how to
do this.
2. Have the main thread forcibly terminate the thread doing the
reading. I cannot find anything in the Python documentation that
explains how to do this.
Any advice will be much appreciated.
Thanks
Frank Millman
P.S. I have found a way of implementing point 1 above, that seems to
work. If you don't mind, I would still like to post this, to get some
feedback about whether this is a good approach.
#---------------------------------------------
import threading, os, time
x = 1
def main():
global x
print 'starting thread'
t = threading.Thread(target=scan)
t.start()
while x:
q = raw_input("Press 'q' to quit")
if q == 'q':
x = 0
time.sleep(0.1)
print 'thread finished'
def scan():
p = os.open('/dev/ttyS0',os.O_RDONLY|os.O_NONBLOCK)
txt = []
while x:
try:
ch = os.read(p,1)
if ord(ch) == 13:
print ''.join(txt)
txt = []
else:
txt.append(ch)
except OSError:
time.sleep(0.1)
os.close(p)
print 'done'
if __name__ == '__main__':
main()
#---------------------------------------------
Thanks
Frank
I am not sure if this question is about threading or serial i/o - it
has elements of both.
I want to capture the output from a hand-held scanner and write it to
a file. The scanner communicates with a base-station, which is
connected to the server via a serial port. The scanner is programmed
to input a code and quantity, and send the result directly to the
base-station in the form 'code' <tab> 'qty' <cr>.
Here is my first attempt - quick and dirty, but intended to prove the
concept.
#---------------------------------------------
import threading
x = 1
def main():
global x
print 'starting thread'
t = threading.Thread(target=scan)
t.start()
while x:
q = raw_input("Press 'q' to quit")
if q == 'q':
x = 0
print 'thread finished'
def scan():
p = file('/dev/ttyS0')
txt = []
while x:
ch = p.read(1)
if ord(ch) == 13:
print ''.join(txt)
txt = []
else:
txt.append(ch)
p.close()
print 'done'
if __name__ == '__main__':
main()
#---------------------------------------------
I use threading so that the user can control the program via the
keyboard at the same time as the program is reading the serial port.
It works ok, but I do not know how to stop it cleanly. When the user
presses 'q' to quit, it sets a variable to tell the thread to
terminate, but the thread is blocked at the read statement, so it does
not know it is supposed to terminate.
I can think of two theoretical solutions, but I do not know if either
of them are possible.
1. Turn the 'read' of the serial port into a 'non-blocking' read by
checking if there are any bytes waiting to be read before actually
issuing the read statement. I have done this in other languages, but I
cannot find anything in the Python documentation that explains how to
do this.
2. Have the main thread forcibly terminate the thread doing the
reading. I cannot find anything in the Python documentation that
explains how to do this.
Any advice will be much appreciated.
Thanks
Frank Millman
P.S. I have found a way of implementing point 1 above, that seems to
work. If you don't mind, I would still like to post this, to get some
feedback about whether this is a good approach.
#---------------------------------------------
import threading, os, time
x = 1
def main():
global x
print 'starting thread'
t = threading.Thread(target=scan)
t.start()
while x:
q = raw_input("Press 'q' to quit")
if q == 'q':
x = 0
time.sleep(0.1)
print 'thread finished'
def scan():
p = os.open('/dev/ttyS0',os.O_RDONLY|os.O_NONBLOCK)
txt = []
while x:
try:
ch = os.read(p,1)
if ord(ch) == 13:
print ''.join(txt)
txt = []
else:
txt.append(ch)
except OSError:
time.sleep(0.1)
os.close(p)
print 'done'
if __name__ == '__main__':
main()
#---------------------------------------------
Thanks
Frank