微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用多个线程同时从gsm模块读写数据,而不会拦截

如何解决使用多个线程同时从gsm模块读写数据,而不会拦截

我正在使用通过UART连接到RaspBerry Pi 3B的Sim808 GSM模块。我可以成功将AT命令写入Sim808,并相应地读取响应。我想将SMS消息发送到Sim808,并使用Rpi处理它们(确实有效)。

我的问题是,由于Sim808在接收第二或第三条消息时正忙于处理第一条消息,因此无法在短时间内接收到多个SMS,因此无法读取它们或被中断。 Sim808的响应(在错误的过程中读取/写入传入消息的数据)。 为了读取每条传入的消息(或至少得到通知),我尝试在生产者/消费者模式中创建2个线程,如果新消息传入,则sim808通知接收者线程(生产者)(sim808发送存储位置和消息的相应索引)通过串行UART连接。然后,接收方将消息的索引放入队列中,在该队列中,调度程序线程(消费者)可以获取新到达的消息的索引。 如果我想使用调度程序线程读取新的SMS消息,则接收方线程会中断读取过程,因为为了使用调度程序线程读取消息,我必须向Sim808发送另一个AT命令,该命令会触发通过UART响应(通过串行接收输入)的接收器线程。然后,接收方线程读取响应(例如将其丢弃),将响应留在我的调度程序线程中。

因此,这里的问题显然是仅使用一个串行连接的2个线程的读/写连接。 我的第一个想法是使用Sim808的集成USB端口作为辅助串行端口,在这里我可以使用USB端口通知我的接收器线程,并使用标准UART与Sim808通信以处理消息处理等。 Sim808上的USB端口仅用于固件更新/调试目的。

所以我想知道是否有任何方法可以在处理过程中的任何时间点接收新消息,而不会导致线程互相干扰?我应该注意,接收每个传入消息绝对至关重要。如有必要,我也将求助于其他硬件来解决此问题。这是我的(摘要代码,其中包含一些其他信息作为注释:

# smstest.py
import serial
import RPi.GPIO as GPIO      
import os,time
import threading
import Queue
import logging
import signal
import sys
 
GPIO.setmode(GPIO.BOARD)    

logging.basicConfig(level=logging.DEBUG,format='(%(threadName)-9s) %(message)s',)

messages = []
index_queue = Queue.Queue(10)


# Enable Serial Communication
ser = serial.Serial("/dev/serial0",baudrate=9600,timeout=1)
ser.flush()
print("Serial Port Ready...")

#######################################################################
class Message:
    def __init__(self,phone_number,message):
        self.phone_number = phone_number
        self.message = message 
#######################################################################
#Producer
class ReceiverThread(threading.Thread):
    def __init__(self,group=None,target=None,name=None,args=(),kwargs=None,verbose=None):
        super(ReceiverThread,self).__init__()
        self.target = target
        self.name = name
        self.running = True

    def run(self):
        logging.debug("Starting ReceiverThread...")
        print("Listening for incoming SMS...")
        while self.running: 
            inc = ser.read(17) # read number of bytes in the buffer 
            if "CMTI" in inc:   #Check if the incoming response is an actual message 

I'm looking for the CMTI substring,because that's the response of the Sim808 when receiving a new SMS. I was trying to "filter" the responses.

                print("inc: " + str(inc))
                if not index_queue.full():
                    for char in inc: #loop throught +CMTI response and get message index

                        if char.isdigit():
                            index_queue.put(char)  #write message index to queue
                            print(list(index_queue.queue))
                            logging.debug('Putting Message with index ' + str(char) + ' : ' + str(index_queue.qsize()) + ' items in queue')
                            print("Listening for incoming SMS...")
        return
#######################################################################
#Consumer
class dispatcherThread(threading.Thread):
    def __init__(self,verbose=None):
        super(dispatcherThread,self).__init__()
        self.target = target
        self.name = name
        self.running = True
        return

    def run(self): 
        logging.debug("Starting dispatcherThread")
        while self.running: 
            if not index_queue.empty():
                num = index_queue.get()
                print("num: " + str(num))
## here is where the first problem occurs. I try to read the SMS and accidentally trigger my receiver ##  
                ser.write(str.encode("AT+CMGR=" +num+ "\r")) #read sms at index
                time.sleep(1)
                sms = ser.read(ser.inWaiting())
                print ("SMS received. Content: ")
                print (sms)  
## sms is empty ## 
                .... some processing ....


               
        return
#######################################################################

def main():

 .... setting up the GSM module and sending AT codes ....



    r = ReceiverThread(name='Receiver')
    r.start()
    
    d = dispatcherThread(name='dispatcher')
    d.start()
    try: 
        while True: 
            time.sleep(0.1)

    except(KeyboardInterrupt):
        print("quitting threads")
        r.running = False
        d.running = False
        
    
if __name__ == "__main__":
    main()


我知道我可以用不同的方式来处理接收消息(例如列出所有接收到的未读消息等),但这不能解决我的问题,因为同样,我的线程在处理时会互相中断。

我还读到了一些有关Sim808能够在内部运行多个线程的信息,但是我认为这不是正确的方法(到目前为止,我的知识也是如此)。

每个答案我都很高兴!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。