python3 通過(guò)serial讀取和發(fā)送串口數(shù)據(jù)進(jìn)行485口穩(wěn)定性測(cè)試

公司的設(shè)備有4個(gè)485的串口,近期需要做在做高低溫測(cè)試時(shí),驗(yàn)證458口的穩(wěn)定性。在網(wǎng)上查閱了一下資料,方案大體以下兩類(lèi):1.單個(gè)485口,通過(guò)485轉(zhuǎn)usb在windows系統(tǒng)上進(jìn)行收發(fā);2.有多個(gè)485口的情況下,對(duì)485進(jìn)行短接,在本地進(jìn)行收發(fā);綜合考慮后采樣在本地進(jìn)行短接的方式進(jìn)行測(cè)試;
485口設(shè)備,通過(guò)shell命令進(jìn)行讀寫(xiě),非常簡(jiǎn)單。在/dev/下面找到對(duì)應(yīng)485口的設(shè)備文件,類(lèi)似于ttyS1,ttyS2這樣的文件。1.通過(guò) cat /dev/ttyS1 讀取數(shù)據(jù) ;2. 發(fā)送數(shù)據(jù),echo 1111 > /dev/ttyS2 ;可以寫(xiě)個(gè)簡(jiǎn)單是shell腳本進(jìn)行測(cè)試,此處不行擴(kuò)展;
我們的設(shè)備里面,有python3的環(huán)境,因此用python實(shí)現(xiàn)了一個(gè)對(duì)4個(gè)口進(jìn)行測(cè)試腳本;我設(shè)備單次發(fā)送的數(shù)據(jù)在32個(gè)字節(jié)的樣子,發(fā)送間隔1分鐘。測(cè)試腳本的壓力是,單次發(fā)送48個(gè)字節(jié),發(fā)送間隔是100ms。當(dāng)485口通信異常時(shí),會(huì)打印到控制臺(tái)。測(cè)試時(shí)通過(guò)nohup 命令將控制臺(tái)輸出重定向到文件進(jìn)行記錄。代碼如下:

# -*- coding:utf-8 -*-
# @Time      :2020/6/1
# 485口檢測(cè)工具
# 依賴(lài) pyserial 模塊 安裝方式 pip install pyserial
# 1.將485口A對(duì)A,B對(duì)B 兩兩進(jìn)行短接,本機(jī)進(jìn)行測(cè)試
# 2 也可以外接設(shè)備進(jìn)行測(cè)試485口進(jìn)行收發(fā)測(cè)試

from sys import argv
import serial
import time
import _thread
from multiprocessing import Pool, freeze_support

# 串口編號(hào)和對(duì)應(yīng)設(shè)備文件的字典

port_dict = {
    '1': "/dev/ttyS7",
    '2': "/dev/ttyS6",
    '3': "/dev/ttyS3",
    '4': "/dev/ttyS4",
}


def recv_data(serial_FD, port_name=''):
    """
    接收函數(shù)
    :param serial_FD:
    :param port_name:串口編號(hào)
    :return:
    """
    print(f'{time.strftime("%Y-%m-%d %H:%M;%S", time.localtime())},runing recv thread[{port_name}] ,waiting 0.1s')
    time.sleep(0.1)
    while True:
        try:
            data_count = serial_FD.inWaiting()
            if data_count != 0:
                recv = serial_FD.read(48)
                # print(time.strftime("%Y-%m-%d %H:%M;%S", time.localtime()), " ---  data_recv lenth  --> ",
                #       len(recv.decode()))
                pass
            else:
                print(
                    f'{time.strftime("%Y-%m-%d %H:%M;%S", time.localtime())} ---  data_recv[{port_name}]   --> recv is error')
        except Exception as e:
            print(str(e))
        time.sleep(0.1)


def send_data(serial_FD):
    """
    發(fā)送方法
    :param serial_FD:
    :return:
    """
    # print(f'runing recv thread {time.strftime("%Y-%m-%d %H:%M;%S", time.localtime())},waiting 30s')
    # time.sleep(30)

    while 1:
        try:
            serial_FD.write(b'1' * 48)
        except Exception as e:
            print(str(e))
        time.sleep(0.1)


def run(port=None):
    """
    程序入口
    :return:
    """
    if port is None:
        if len(argv) != 2:
            print('Please enter the port number! eg: ptyhon3 rs485_tool.py 1')
            exit(-1)
        port = argv[1]

    serial_port = port_dict.get(str(port))
    if serial_port is None:
        print('port not in [1,2,3,4]')
        exit(-1)

    data_ser = serial.Serial(serial_port, 9600, timeout=5)
    data_ser.flushInput()
    _thread.start_new_thread(recv_data, (data_ser, port))
    send_data(data_ser)


def multi_run(port_list=''):
    pool = Pool(len(port_list))
    for port in port_list:
        pool.apply_async(run, args=(port,))
    pool.close()
    pool.join()


if __name__ == '__main__':
    freeze_support()
    multi_run([1, 2, 3, 4])
    # run()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。