Cool_Breeze 发表于 2021-11-4 18:05

串口通信不太完美! Python 跨平台真的太棒了!

基于 pyserial 开发!

这个程序很简单,自动连接串口,发送一条指令后退出!

这个程序需要在Windows,和Ubuntu上面跑。

唯一改动的就是文件格式,需要转换为 unix 格式vim 命令 set ff=unix

厉害的是 pyinstaller 居然可以在两个平台上无改动编译成功!太棒了!

配置文件 是json格式。一个字典内套一个字典!

statusLight.py:
    实现串口通信
    bpsList = 这个是波特率的集合,我们这个项目只用到这两种

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import serial
import serial.tools.list_ports
import os
import sys

class StatusLight(object):
    ''' 连接串口,实现通信类 '''
   
    # 兼容频率
    bpsList =
    # 端口
    ports = serial.tools.list_ports.comports()
   
   
    def __init__(self, sendStr, receive, timeout=0.2):
      ''' args:
            sendStr 发送数据
            reverse 接送数据
            timeout 超时
            # portn 端口
            # bps 波特率
      '''
      self.portn = ""
      self.bps = ""
      self.sendStr = sendStr
      self.receive = receive
      self.timeout = timeout
      self.serial = None # type pyserial.Serial
   
    def _connect(self):
      ''' 连接串口 '''
      result = True
      try:
            self.serial = serial.Serial(self.portn, self.bps, timeout=self.timeout)
            self.checkDevice()
      except Exception as e:
            result = False
      return result
      
    def setInfo(self, portn, bps, timeout=0.2):
      self.portn = portn
      self.bps = bps
      self.timeout = timeout
      if not self._connect():
            self.automaticAddressing()
   
    def close(self):
      ''' 关闭串口通信 '''
      self.serial.close()

    def automaticAddressing(self):
      '''
            自动寻找设备
            实现方法 发送 sendStr 接受返回 数据 与 receive 匹配
      '''
      breakFlag = False
      for n in StatusLight.ports:
            self.portn = n.device
            for b in StatusLight.bpsList:
                self.bps = b
                if self._connect():
                  breakFlag = True
                  break
            if breakFlag:
                break
      if breakFlag:
            print('-' * 20)
            print(f'Device   = {self.portn}')
            print(f'Baudrate = {self.bps}')
            print('-' * 20)
      else:
            print("Failed to connect to serial device!")
            sys.exit(1)
   
    def checkDevice(self):
      ''' 验证设备 '''
      self.write(self.sendStr)
      serial.time.sleep(0.1)
      byteDate = self.serial.read(1)
      if byteDate != self.receive.encode('gbk'):
            raise ValueError(f"check Device Failed: {send} not equal to {receive}")
            
    def write(self, string):
      ''' 发送数据 '''
      self.serial.reset_input_buffer() # 清空输入缓冲器(清空返回值)
      self.serial.write(string.encode('gbk'))
      
    def read(self, count=1):
      ''' 读取数据 count = 字节数'''
      return self.serial.read(count)

if __name__ == "__main__":
    ser = StatusLight('COM4', 38400)
    ser.automaticAddressing()
    print(ser.serial.write("b".encode('gbk')))
    serial.time.sleep(0.5)
    ser.serial.write("d".encode('gbk'))
    ser.close()

RGBLight.py:
    实现命令行、配置文件的解析
    很丑,因为没有其它参数。。
   #!/usr/bin/env python3# -*- coding: utf-8 -*-

import json
import sys
import re
import os
from statusLight import StatusLight



# 命令行参数
configF = "statusLight"
sendStr = ""
version = 0.1

   

def errorPrint(string):
    print("eg: exe -send=a")
    print(string)
    print(sys.argv)
    sys.exit(1)

def parseCommandLine():
    ''' 解析命令行参数 '''
    global sendStr, version
    argv = sys.argv
    # configFRex = re.compile("-configF=(.+)")
    sendStrRex = re.compile("-send=(.+)")
    if len(argv) <= 1:
      print("eg: exe -send=a")
      print(f"version: {version}")
      print("Parse CommandLine Error !")
      input("Type any key to exit!")
      sys.exit(1)
      
      
    for n in argv:   
      stripN = n.strip()
      # res = configFRex.match(stripN)
      # if res:
            # configF = res.group(1)
      res = sendStrRex.match(stripN)
      if res:
            sendStr = res.group(1)
      
   
    if sendStr == "":
      errorPrint("Parse CommandLine Error !")
   
parseCommandLine()

# 加载本地配置文件
if not os.path.exists(configF):
    errorPrint(f"file does not exit: {configF}")
   
config = None
with open(configF, encoding='utf-8') as f:
    config = json.load(f)

s = config['check'].get('s', None)
e = config['check'].get('e', None)
if s is None or e is None:
    errorPrint("parse file fail!")
   
rgb = StatusLight(s, e)
rgb.automaticAddressing()
rgb.write(sendStr)
rgb.close()
sys.exit(0)

阳光肥肥 发表于 2021-11-4 18:42

你确定能在ubuntu上跑?我记得linux系统下那个端口名字用COM4是不行的。。。

Cool_Breeze 发表于 2021-11-4 20:13

阳光肥肥 发表于 2021-11-4 18:42
你确定能在ubuntu上跑?我记得linux系统下那个端口名字用COM4是不行的。。。

能跑啊。com4 只是表面。

ynboyinkm 发表于 2021-11-4 19:34

python真是利割{:1_921:}

zlf2020999 发表于 2021-11-4 19:52

谢谢分享!认真学习!

wqs0987 发表于 2021-11-4 21:00

感谢大佬的无私分享

bennyt 发表于 2021-11-5 00:45

大神来学习了。

jiguang523 发表于 2021-11-5 07:49

向前辈们致敬

rxxcy 发表于 2021-11-5 09:17

串口通信?还是怎么回事

Cool_Breeze 发表于 2021-11-5 15:36

rxxcy 发表于 2021-11-5 09:17
串口通信?还是怎么回事

串口通信! 需要 Ubuntu glibc 2.25以上版本!
页: [1] 2
查看完整版本: 串口通信不太完美! Python 跨平台真的太棒了!