我正在尝试使用覆盆子pi和python的GSM900调制解调器,我正在尝试制作一个简单的库,用于使用ttl串行连接的GSM900 rpi板。
然而,当我导入库(Serialworker.py)并使用我的主python应用程序(sniffer.py)中的serialworker类的start()函数时,我遇到了使线程按预期工作的问题。在start()函数处阻塞并且不继续main.py代码
我有以下主要的python文件:
main.py
#!/usr/bin/python3
from time import sleep
try:
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT, initial=0)
except ImportError:
print("Could not control GPIO\n"
"Are you root?")
exit()
from serialworkerpi import serialworker
def powercycle():
try:
GPIO.output(17, 0)
sleep(0.2)
GPIO.output(17, 1)
except:
print("Setup Failed, Are you root?")
def online():
if not serworker.checkgsm900online():
print("GSM900 not online, cycling power")
powercycle()
while not serworker.checkgsm900online():
print("Waiting for GSM900")
else:
print("GSM900 connection found")
print("Completed boot cycle")
if __name__ == '__main__':
"""main loop"""
serworker = serialworker()
online()
serworker.start()
try:
while serworker.check():
print("loop")
sleep(0.5)
except KeyboardInterrupt:
serworker.stop()
print("Shutting down threads")
和这个包含start()函数的库类
Serialworker.py:
class serialworker():
"""This Class instantiates a serial thread and has functions for facilitating communication
to the serial interface as well as some GSM900 specific functions"""
def __init__(self, port='/dev/ttyAMA0', baud=115200, timeout=5, pollspeed=0.1):
"""Initialises the variables used in this class, baud=, timeout= and pollspeed= can be adjusted
But have initial values of 115200, 5 and 0.1 respectively, in the future i could add stopbits and parity here"""
self.port = port
self.baud = baud
self.timeout = timeout
self.pollspeed = pollspeed
self.run = False
self.ser = serial.Serial
"""Command variable description:
self.command = Command to write in next while cycle
self.commandwait = Bool used to determine if write buffer contains a command for writing in the next while cycle
self.commandstat = Variable used to hold the return status of the command that was submitted
self.commandret = Bool used to determine if a command was written to the buffer, as to allow the output to be read in the next while cycle
self.respwait = Bool used to determine if commandstat is ready to be read
"""
self.command = ""
self.commandwait = False
self.commandstat = ""
self.commandret = False
self.respwait = False
def start(self):
"""Starts a thread of the _readwriteloop() funtion"""
#TODO add thread checking, only 1 thread per serial interface should be allowed
self.run = True
t1 = threading.Thread(target=self.readwriteloop())
t1.start()
print("started")
def checkgsm900online(self):
"""Checks if the GSM900 board is online"""
gsmser = serial.Serial(
port=self.port,
baudrate=self.baud,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=self.timeout,)
gsmcheck = ("AT"+"\r\n").encode()
gsmser.write(gsmcheck)
sleep(0.03)
gsmbuffer = gsmser.inWaiting()
if gsmbuffer == 0:
gsmser.flush()
gsmser.close()
return False
else:
gsmser.flush()
gsmser.close()
return True
def check(self):
"""Checks if a thread currently exists"""
return self.run
def stop(self):
"""stops running thread"""
self.run = False
def inputcommand(self, string, flag):
"""Allows for a single command to be inputted, sets the commandwait to true to tell the loop to check its queue.
Optionally you can set flag=False to not wait for a return stat on this command"""
self.command = (string+"\r\n").encode()
self.commandwait = True
print("waiting for resp")
if flag:
while not self.respwait:
sleep(0.1)
self.respwait = False
return self.commandstat
def readwriteloop(self):
"""Main function of the class that reads serial data from a buffer
And checks for new commands inputted by the inputcommand() function
which output status it will write to the commandstat buffer"""
#TODO write function for retrieving input command return data not just the status
ser = self.ser(
port=self.port,
baudrate=self.baud,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=self.timeout,)
while self.run:
ser.inWaiting()
buffer = ser.inWaiting()
if buffer != 0:
decodeline = ser.readline().decode('utf-8', "ignore").rstrip('\n')
if len(decodeline) > 2:
if self.commandret:
if 'ERROR' in decodeline:
self.commandstat = decodeline
self.commandret = False
self.respwait = True
elif 'OK' in decodeline:
self.commandstat = decodeline
self.commandret = False
self.respwait = True
elif 'NO CARRIER' in decodeline:
self.commandstat = decodeline
self.commandret = False
self.respwait = True
if self.commandwait:
ser.write(self.command)
#print(self.command)
self.commandwait = False
self.commandret = True
sleep(self.pollspeed)
奇怪的是,当我从Serialworker.py本身运行类时 例如,将此代码附加到文件的末尾:
if __name__ == '__main__':
x = serialworker()
x.start()
i = 0
while i != 1000:
i += 1
x.check()
sleep(0.01)
pin = "0000"
pinconvert = "AT+CPIN=\"%s\"" % pin
succeed = x.inputcommand(pinconvert, True)
print(succeed)
while i != 10000:
i += 1
x.check()
sleep(0.01)
x.stop()
isonline = x.checkgsm900online()
print(isonline)
它按预期工作,只要while循环继续运行,start()函数就不会阻塞和运行
答案 0 :(得分:0)
问题在于你正在调用一个应由线程执行的函数:
Thread(target=self.readwriteloop())
应该是
Thread(target=self.readwriteloop)