For my project I need two serial ports and I need to monitor both and act accordingly.
Example of what I need to do: Port A and Port B Monitor all the time Port A and when message is received, I need to forward it to Port B and wait for reply. At the same time as above, I need to send a particular message (not the one received) to port B, I would say, every 0.5 seconds and wait for a reply on Port B.
I have it working but I miss a lot of messages... can't poll it too fast and not sure what to do to improve it.
import serial
from time import sleep
import threading
from dataclasses import dataclass
import string
lock_statusfile = threading.Lock()
global_tmr_between_readings = 10
@dataclass
class Config_STATUS:
status_alarm: string
status_gain1: string
status_gain2: string
status_gain3: string
status_gain4: string
status_mode: string
status_band: string
status_ext: string
status_change: string
status_lock: string
status_contrast: string
status_gain_res: string
status_serial: string
status_baud: string
status_address: string
status_parity: string
status_bits: string
status_stop: string
#global variavles use to serial commands
# unit in local cannot accept command
global_msg_unit_local = "x"
serial_port_A = serial.Serial(
port='/dev/ttyAMA0',
baudrate = 9600,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.SEVENBITS,
timeout=1
)
serial_port_B = serial.Serial(
port='/dev/ttyAMA1',
baudrate = 9600,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.SEVENBITS,
timeout=1
)
#saves message received on serial port
global_serial_message_received_B = ""
global_serial_message_received_A = ""
#send command to port B
def Send_cmd_PortB(cmd):
msg_received=""
print("SEND STATUS TO PORT B")
serial_port_B.write(cmd.encode(encoding='UTF-8'))
i=0
while i<10:
msg_received = serial_port_B.read(100)
if len(msg_received.decode(encoding='UTF-8')) > 19:
i = 10
print("RECEIVE STATUS FROM PORT B")
else:
i=i+1
sleep(0.1)
return msg_received.decode(encoding='UTF-8')
def Read_Status():
with lock_statusfile:
#Send status command on portB to DIGI and update status class
aux = "A"
msg_received = Send_cmd_PortB("{" + aux + "A}\\")
if len(msg_received) == 22:
Config_STATUS.status_alarm = msg_received[14]
Config_STATUS.status_gain1 = msg_received[4:6] + "." + msg_received[6]
Config_STATUS.status_gain2 = msg_received[8:10] + "." + msg_received[10]
Config_STATUS.status_mode = msg_received[12]
return msg_received
######################################################################
# Monitoring serial port B
def Monitoring_SerialPort_B_thr():
global global_tmr_between_readings
while(True):
# #while monitoring Com port read DIGI status
if global_tmr_between_readings <= 10 and global_tmr_between_readings >=0:
global_tmr_between_readings = global_tmr_between_readings -1
else:
msg_received = Read_Status()
if len(msg_received) != 22:
print("Loading Data from port B: time out")
global_tmr_between_readings = 10
#read from port B
serial_message_B = serial_port_B.read(100)
#message from port B is valid?
if len(serial_message_B) > 3 and len(serial_message_B) < 30:
aux = serial_message_B.decode('UTF-8')
print("RECEIVED FROM Port B: " + aux)
#send message received on portB from DIGI to portA to PC
serial_port_A.write(serial_message_B)
print("FOWARD FROM portB to portA: " + aux)
######################################################################
# Monitoring serial port A
def Monitoring_SerialPort_A_thr():
while(True):
#read portA
serial_message_A = serial_port_A.read(100)
#if valid message send it to portB
if len(serial_message_A) > 3 and len(serial_message_A) < 30:
aux = serial_message_A.decode('UTF-8')
print("RECEIVED FROM portA: " + aux)
#send message received on portA to portB
serial_port_B.write(serial_message_A)
print("FOWARD FROM portA to portB: " + aux)
if __name__ == "__main__":
Monitoring_SerialPort_B_thread = threading.Thread(target = Monitoring_SerialPort_B_thr)
Monitoring_SerialPort_A_thread = threading.Thread(target = Monitoring_SerialPort_A_thr)
Monitoring_SerialPort_B_thread.start()
Monitoring_SerialPort_A_thread.start()
Monitoring_SerialPort_B_thread.join()
Monitoring_SerialPort_A_thread.join()