serial_serializable - CSDN
精华内容
参与话题
  • Python-serial 模块使用方法

    千次阅读 2020-08-28 14:39:58
    serial 模块使用方法 一、概述 pyserial模块封装了对串口的访问。 二、特性 在支持的平台上有统一的接口。 通过python属性访问串口设置。 支持不同的字节大小、停止位、校验位和流控设置。 可以有或者没有接收超时...
    def get_com_list(self):
        com_dev_list = tuple(serial.tools.list_ports.comports())
        if not com_dev_list:
            log.info('there\'s no com')
            self.__com_list = []
        else:
            self.__com_list = ['/dev/' + i.name for i in com_dev_list]
            # log.debug('com_name_list:{}'.format(self.__com_list))
        return self.__com_list

     

    serial 模块使用方法

    一、概述
        pyserial模块封装了对串口的访问。
    二、特性
        在支持的平台上有统一的接口。
        通过python属性访问串口设置。
        支持不同的字节大小、停止位、校验位和流控设置。
        可以有或者没有接收超时。 
        类似文件的API,例如read和write,也支持readline等。
        支持二进制传输,没有null消除,没有cr-lf转换。
    三、版本要求
        python 2.3及以上版本,包括py3k。

    四、使用方法和实例

    1、导入pyserial模块

    import  serial


    2、打开串行口


    // 打开串口0, 9600,8N1,连接超时0.5秒
    import serial
    ①选择设备
    ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5) #使用USB连接串行口
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) #使用树莓派的GPIO口连接串行口
    ser=serial.Serial(1,9600,timeout=0.5)                       #winsows系统使用com1口连接串行口
    ser=serial.Serial("com1",9600,timeout=0.5)              #winsows系统使用com1口连接串行口
    ser=serial.Serial("/dev/ttyS1",9600,timeout=0.5)       #Linux系统使用com1口连接串行口
    print ser.name        #打印设备名称
    print ser.port           #打印设备名
    ser.open()               #打开端口
    s = ser.read(10)      #从端口读10个字节
    ser.write("hello")     #向端口写数据
    ser.close()               #关闭端口
    data = ser.read(20) #读20个字符


    data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。

    data = ser.readlines()  和  ser.xreadlines()     #都需要设置超时时间

    ser.baudrate = 9600      #设置波特率

    ser.isOpen()                   #看看这个串口是否已经被打开

    3、获得串行口状态
    串行口的属性:
    name:设备名字
    portstr:已废弃,用name代替
    port:读或者写端口
    baudrate:波特率
    bytesize:字节大小
    parity:校验位
    stopbits:停止位
    timeout:读超时设置
    writeTimeout:写超时
    xonxoff:软件流控
    rtscts:硬件流控
    dsrdtr:硬件流控
    interCharTimeout:字符间隔超时
            
    ①属性

    属性的使用方法:
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5)
    ser.open()

    print ser.name
    print ser.port
    print ser.baudrate#波特率
    print ser.bytesize#字节大小
    print ser.parity#校验位N-无校验,E-偶校验,O-奇校验
    print ser.stopbits#停止位
    print ser.timeout#读超时设置
    print ser.writeTimeout#写超时
    print ser.xonxoff#软件流控
    print ser.rtscts#硬件流控
    print ser.dsrdtr#硬件流控
    print ser.interCharTimeout#字符间隔超时
    ser.close()
    4、设置串行口状态
    需要用的常量


    bytesize:FIVE BITS、SIXBITS、SEVENBITS、EIGHTBITS
    parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
    stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
    异常:
    ValueError:参数错误
    SerialException:找不到设备或不能配置
    ser.baudrate=9600#设置波特率

    ser.bytesize=8#字节大小
    ser.bytesize=serial.EiGHTBITS#8位数据位

    ser.parity=serial.PARITY_EVEN#偶校验
    ser.parity=serial.PARITY_NONE#无校验
    ser.parity=serial.PARITY_ODD#奇校验

    ser.stopbits=1               #停止位
    ser.timeout=0.5             #读超时设置
    ser.writeTimeout=0.5    #写超时
    ser.xonxoff#软件流控
    ser.rtscts#硬件流控
    ser.dsrdtr#硬件流控
    ser.interCharTimeout#字符间隔超时

    5、Readline方法的使用

            是读一行,以/n结束,要是没有/n就一直读,阻塞。


           使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。如果没有超时,readline会报异常。
    6、serial.Serial类——原生端口
    class serial.Serial 
    {
        __init__(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)
    }
        #其中:
        # bytesize:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS
        # parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
        # stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
        #异常:
        #ValueError:参数错误
        #SerialException:找不到设备或不能配置

        open():打开串口

        close():立即关闭串口

        __del__():析构函数

        read(size=1):从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。

        write(data):发送data,并返回发送字节数。如果bytes和bytearray可用(python 2.6以上),则接受其作为参数;否则接受str作为参数。
        #异常:SerialTimeoutException——配置了写超时并发生超时时发生此异常。

        inWaiting():返回接收缓存中的字节数

        flush():等待所有数据写出。

        flushInput():丢弃接收缓存中的所有数据

        flushOutput():终止当前写操作,并丢弃发送缓存中的数据。

        sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE

        setBreak(level=True):根据level设置break条件。

        setRTS(level=True)

        setDTR(level=True)

        getCTS()

        getDSR()

        getRI()

        getCD()

        #只读属性:
        name:设备名字
        portstr:已废弃,用name代替
        port:读或者写端口
        baudrate:波特率
        bytesize:字节大小
        parity:校验位
        stopbits:停止位
        timeout:读超时设置
        writeTimeout:写超时
        xonxoff:软件流控
        rtscts:硬件流控
        dsrdtr:硬件流控
        interCharTimeout:字符间隔超时

        #端口设置可以被读入字典,也可从字典加载设置:
        getSettingDict():返回当前串口设置的字典
        applySettingDict(d):应用字典到串口设置

        #对提供io库的系统(python 2.6或以上),Serial从io.RawIOBase派生。对其它系统,从FileLike派生。

        #异常:
        exception serial.SerialException
        exception serial.SerialTimeoutException

        #常量:
        serial.VERSION:pyserial版本

        #模块函数和属性:
        serial.device(number)

        serial.serial_for_url(url, *args, **kwargs)

        serial.protocol_handler_packages()

        serial.to_bytes(sequence):接收一个字符串或整数列表sequence,返回bytes实例
    }

     

    展开全文
  • Python 之 Serial串口通信

    万次阅读 多人点赞 2019-08-05 09:57:11
    确定串口名称 WINDOWS #!/usr/bin/env python #-*- coding: utf-8 -* import serial ...import serial.tools.list_ports ...plist = list(serial.tools.list_ports.comports()) ... print ("The Serial...

    0 Serial方法

    1、导入pyserial模块

    import serial

    2、打开串行口

    // 打开串口0, 9600,8N1,连接超时0.5秒
    import serial
    ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5) #使用USB连接串行口
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) #使用树莓派的GPIO口连接串行口
    ser=serial.Serial(1,9600,timeout=0.5)#winsows系统使用com1口连接串行口
    ser=serial.Serial(“com1”,9600,timeout=0.5)#winsows系统使用com1口连接串行口
    ser=serial.Serial("/dev/ttyS1",9600,timeout=0.5)#Linux系统使用com1口连接串行口
    print ser.name#打印设备名称
    print ser.port#打印设备名
    ser.open() #打开端口
    s = ser.read(10)#从端口读10个字节
    ser.write(“hello”)#向端口些数据
    ser.close()#关闭端口
    data = ser.read(20) #是读20个字符
    data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
    data = ser.readlines()和ser.xreadlines()#都需要设置超时时间
    ser.baudrate = 9600 #设置波特率
    ser.isOpen() #看看这个串口是否已经被打开

    3、获得串行口状态

    串行口的属性:
    name:设备名字
    portstr:已废弃,用name代替
    port:读或者写端口
    baudrate:波特率
    bytesize:字节大小
    parity:校验位
    stopbits:停止位
    timeout:读超时设置
    writeTimeout:写超时
    xonxoff:软件流控
    rtscts:硬件流控
    dsrdtr:硬件流控
    interCharTimeout:字符间隔超时

    属性的使用方法:
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5)
    ser.open()

    print ser.name
    print ser.port
    print ser.baudrate#波特率
    print ser.bytesize#字节大小
    print ser.parity#校验位N-无校验,E-偶校验,O-奇校验
    print ser.stopbits#停止位
    print ser.timeout#读超时设置
    print ser.writeTimeout#写超时
    print ser.xonxoff#软件流控
    print ser.rtscts#硬件流控
    print ser.dsrdtr#硬件流控
    print ser.interCharTimeout#字符间隔超时

    ser.close()

    4、设置串行口状态

    需要用的常量

    bytesize:FIVE BITS、SIXBITS、SEVENBITS、EIGHTBITS
    parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
    stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
    异常:
    ValueError:参数错误
    SerialException:找不到设备或不能配置

    ser.baudrate=9600#设置波特率

    ser.bytesize=8#字节大小
    ser.bytesize=serial.EiGHTBITS#8位数据位

    ser.parity=serial.PARITY_EVEN#偶校验
    ser.parity=serial.PARITY_NONE#无校验
    ser.parity=serial.PARITY_ODD#奇校验

    ser.stopbits=1#停止位
    ser.timeout=0.5#读超时设置
    ser.writeTimeout=0.5#写超时
    ser.xonxoff#软件流控
    ser.rtscts#硬件流控
    ser.dsrdtr#硬件流控
    ser.interCharTimeout#字符间隔超时

    5、Readline方法的使用

    是读一行,以/n结束,要是没有/n就一直读,阻塞。

    使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。如果没有超时,readline会报异常。

    6、serial.Serial类——原生端口

    class serial.Serial
    {
    init(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)

    #其中:
    # bytesize:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS
    # parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
    # stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
    #异常:
    #ValueError:参数错误
    #SerialException:找不到设备或不能配置

    open():打开串口

    close():立即关闭串口

    del():析构函数

    read(size=1):从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。

    write(data):发送data,并返回发送字节数。如果bytes和bytearray可用(python 2.6以上),则接受其作为参数;否则接受str作为参数。
    #异常:SerialTimeoutException——配置了写超时并发生超时时发生此异常。

    inWaiting():返回接收缓存中的字节数

    flush():等待所有数据写出。

    flushInput():丢弃接收缓存中的所有数据

    flushOutput():终止当前写操作,并丢弃发送缓存中的数据。

    sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE

    setBreak(level=True):根据level设置break条件。

    setRTS(level=True)

    setDTR(level=True)

    getCTS()

    getDSR()

    getRI()

    getCD()

    #只读属性:
    name:设备名字
    portstr:已废弃,用name代替
    port:读或者写端口
    baudrate:波特率
    bytesize:字节大小
    parity:校验位
    stopbits:停止位
    timeout:读超时设置
    writeTimeout:写超时
    xonxoff:软件流控
    rtscts:硬件流控
    dsrdtr:硬件流控
    interCharTimeout:字符间隔超时

    #端口设置可以被读入字典,也可从字典加载设置:
    getSettingDict():返回当前串口设置的字典
    applySettingDict(d):应用字典到串口设置

    #对提供io库的系统(python 2.6或以上),Serial从io.RawIOBase派生。对其它系统,从FileLike派生。

    #异常:
    exception serial.SerialException
    exception serial.SerialTimeoutException

    #常量:
    serial.VERSION:pyserial版本

    #模块函数和属性:
    serial.device(number)

    serial.serial_for_url(url, *args, **kwargs)

    serial.protocol_handler_packages()

    serial.to_bytes(sequence):接收一个字符串或整数列表sequence,返回bytes实例

    1 确定串口名称

    1.1 WINDOWS

    获取可用串口列表

    #!/usr/bin/env python
    #-*- coding: utf-8 -*
    import serial
    import serial.tools.list_ports
    
    plist = list(serial.tools.list_ports.comports())
    
    if len(plist) <= 0:
        print ("The Serial port can't find!")
    else:
        plist_0 =list(plist[0])
        serialName = plist_0[0]
        serialFd = serial.Serial(serialName,9600,timeout = 60)
        print ("check which port was really used >",serialFd.name)
    
    

    在这里插入图片描述

    import serial #导入模块
    
    import serial.tools.list_ports
    port_list = list(serial.tools.list_ports.comports())
    print(port_list)
    if len(port_list) == 0:
       print('无可用串口')
    else:
        for i in range(0,len(port_list)):
            print(port_list[i])
    
    1.2 LINUX

    查询从系统启动到现在串口插拔的信息,显示串口Ubuntu连接的端口号:

    在终端输入:

    dmesg | grep ttyS*

    在这里插入图片描述
    在这里插入图片描述

    在Ubuntu下装了CuteCom,但当打开 /dev/ttyUSB0 时,总提示错误,打开失败时:

    用 Minicom 可以正常读取 ttyUSB0。

    sudo chmod 666 /dev/ttyUSB0

    这样修改后, CuteCom 就可以正常打开 USB 串口了

    1,pycharm程序端代码。

    
    #usr/bin/python3
    # -*- coding: utf-8 -*-
    import serial
    from time import sleep
     
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5)
     
     
    def recv(serial):
            global data
            while True:
                    data = serial.read(30)
                    if data == '':
                            continue
                    else:
                            break
                    sleep(0.02)
            return data
     
     
    while True:
            data = recv(ser)
            ser.write(data)
     
    

    在pycharm上的程序:

    在这里插入图片描述

    程序效果为: 运行后,在CuteCom发生的代码, 程序这边会原文返回发给CuteCom。

    1.3 Python(Linux下)获取串口的idv和idp以及serial序列号

    串口端口的获取脚本

    # coding=utf-8
    #
    
    __author__ = 'Haleydu'
    __editTime__ = '2018.12.7'
    
    import serial.tools.list_ports
    import serial
    import os
    import re
    
    class AutoMatchSerialPort:
        #一.获取串口 or 判断是否存在该串口
        def getSerial(self,needdev=''):
            needSerial=''
            port_list = list(serial.tools.list_ports.comports())
            if len(port_list) <= 0:
                print ("The Serial port can't find!")
            else:
            #1.过滤,获取需要的串口
                for i in list(port_list):
                    if i.name==needdev:
                        needSerial=i.name
                    print(i.name,end=',')
                print('\n')
            #2.返回获取的目的串口为了绑定
            return needSerial
    
       # 二.根据端口号返回ID号和硬件号
        def getSerialIDAndSer(self,dev):
            cmd = "udevadm info --attribute-walk --name=" + dev
            result = self.execCmd(cmd)
            pat1 = "ATTRS{idVendor}==.?(\d\d\d\d).?"
            pat2 = "ATTRS{idProduct}==.?(\d\d\d\d).?"
            pat3 = 'ATTRS{serial}==.([A-Za-z0-9]+).'
            ret1 = re.search(pat1,result)
            ret2 = re.search(pat2,result)
            ret3 = re.search(pat3,result)
            idv = ret1.group(1)
            idp = ret2.group(1)
            ser = ret3.group(1)
            return idv,idp,ser
    
        # 三.根据ID号或者序列号返回串口的端口号,也可以用别名直接调用该串口(运行后需要拔插目的串口后生效)
        def getSerialPort(self,idv='',idp='',ser='',alias='ttyUSB_test'):
            if idv==''or idp=='':
                contentID = 'ATTRS{serial}=="'+ser+', MODE:="0777", SYMLINK+="'+ alias +'" \n'
            elif ser=='':
                contentID = '", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n'
            else:
                contentID = 'ATTRS{serial}=="'+ser+'", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n'
    
            path='/etc/udev/rules.d/getSerialPort_'+alias+'.rules'
            if os.path.exists(path):
                #print('存在文件')
                f = open(path,"w")
                f.write(contentID)
                f.flush()
                f.close()
                #print('创建成功')
                #print('重新拔插串口后生效')
            else:
                #print('不存在文件,开始创建getSerialPort_'+alias+'.rules的udev规则文件')
                f = open(path,"w")
                f.write(contentID)
                f.flush()
                f.close()
                #print('创建成功')
                #print('重新拔插串口后生效')
            #重启udev规则
            #sudo /etc/init.d/udev restart
            #根据ID获得端口号
            cmd = "udevadm info --attribute-walk --name=" + alias
            result = self.execCmd(cmd)
            pat = '(ttyUSB.)'
            ret = re.search(pat,result)
            dev=''
            try:
                dev = ret.group(1)
            except AttributeError:
                if dev=='':
                    print('重新拔插串口后生效')
            return dev
    
    
        #调用终端,获取终端输出
        def execCmd(self,cmd):  
            r = os.popen(cmd)  
            result = r.read()  
            r.close()  
            return result  
    
    if __name__ == '__main__':
        am=AutoMatchSerialPort()
        am.getSerial()
        print('ttyUSB0:' + str(am.getSerialIDAndSer("ttyUSB0")))
        print('ttyUSB1:' + str(am.getSerialIDAndSer("ttyUSB1")))
        print('0403:6002,FT2NPXY4,ttyUSB_1:' + am.getSerialPort('0403','6002','FT2NPXY4','ttyUSB_1'))
        print('0403:6001,FTSYWCXZ,ttyUSB_2:' + am.getSerialPort('0403','6001','FTSYWCXZ','ttyUSB_2'))
        
    
    
    

    2 SERIAL 串口操作

    参考文档:
    https://blog.csdn.net/qq_14997473/article/details/80875722:Python学习笔记——串口配置以及发送数据

    https://blog.csdn.net/ubuntu14/article/details/75335106:python实现串口自动触发工作

    (1) 安装pyserial库

    pip install pyserial
    

    serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
    serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux

    (2) pyserial库常用函数介绍
    serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
    
    serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux
    
    print serial .portstr 能看到第一个串口的标识
    
    serial .write(“hello”) 往串口里面写数据
    
    serial .close() 关闭serial 表示的串口
    
    serial .open() 打开串口
    
    data = serial .read(num) 读num个字符
    
    data = serial .readline() 读一行数据,以/n结束,要是没有/n就一直读,阻塞。
    
    serial .baudrate = 9600 设置波特率
    
    print serial 可查看当前串口的状态信息
    
    serial .isOpen() 当前串口是否已经打开
    
    serial.inWaiting() 判断当前接收的数据
    
    serial.flushInput() 清除输入缓冲区数据
    
    serial.flushOutput() 中止当前输出并清除输出缓冲区数据
    
    (3) 实例: 获取从其他串口发送来的数据并回显
    #!/usr/bin/python 
    # coding=UTF-8 
    import serial 
    ################################################### 
    # 
    # 功 能: 将接收到的数据已hex显示 
    # 参 数: 串口接受到的数据 
    # 返 回: 转换后的数据 
    # 
    ################################################### 
    def hexshow(data): 
      hex_data = '' hLen = len(data) 
    
      for i in xrange(hLen): 
        hvol = ord(data[i]) 
        hhex = '%02x' % hvol 
        hex_data += hhex+' '
    
      print 'hexshow:', hex_data 
    ################################################### 
    # 
    # 功 能: 将需要发送的字符串以hex形式发送 
    # 参 数: 待发送的数据 
    # 返 回: 转换后的数据 
    # 
    ################################################### 
    def hexsend(string_data=''): 
      hex_data = string_data.decode("hex") 
      return hex_data 
    
    if __name__ == '__main__': 
      serial = serial.Serial('/dev/ttyS0', 115200) 
      print serial 
    
      if serial.isOpen(): 
        print("open success") 
      else: 
        print("open failed") 
    
    
      try: 
    
        while True: 
          count = serial.inWaiting() 
          if count > 0: 
            data = serial.read(count) 
            if data != b'': 
              print("receive:", data) 
              serial.write(data) 
            else: 
              serial.write(hexsend(data)) 
    
      except KeyboardInterrupt: 
        if serial != None: 
          serial.close()
    
    16进制处理
    import serial #导入模块
    try:
      portx="COM3"
      bps=115200
      #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
      timex=None
      ser=serial.Serial(portx,bps,timeout=timex)
      print("串口详情参数:", ser)
    
      #十六进制的发送
      result=ser.write(chr(0x06).encode("utf-8"))#写数据
      print("写总字节数:",result)
    
      #十六进制的读取
      print(ser.read().hex())#读一个字节
    
      print("---------------")
      ser.close()#关闭串口
    
    except Exception as e:
        print("---异常---:",e)
    
    其他
    import serial #导入模块
    try:
    
      #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
      portx="COM3"
      #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
      bps=115200
      #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
      timex=5
      # 打开串口,并得到串口对象
      ser=serial.Serial(portx,bps,timeout=timex)
      print("串口详情参数:", ser)
    
    
    
      print(ser.port)#获取到当前打开的串口名
      print(ser.baudrate)#获取波特率
    
      result=ser.write("我是东小东".encode("gbk"))#写数据
      print("写总字节数:",result)
    
    
      #print(ser.read())#读一个字节
      # print(ser.read(10).decode("gbk"))#读十个字节
      #print(ser.readline().decode("gbk"))#读一行
      #print(ser.readlines())#读取多行,返回列表,必须匹配超时(timeout)使用
      #print(ser.in_waiting)#获取输入缓冲区的剩余字节数
      #print(ser.out_waiting)#获取输出缓冲区的字节数
    
      #循环接收数据,此为死循环,可用线程实现
      while True:
             if ser.in_waiting:
                 str=ser.read(ser.in_waiting ).decode("gbk")
                 if(str=="exit"):#退出标志
                     break
                 else:
                   print("收到数据:",str)
    
      print("---------------")
      ser.close()#关闭串口
    
    
    except Exception as e:
        print("---异常---:",e)
    
    

    3 解决 ImportError: No module named ‘serial’ 问题

    在pycharm里编写Python串口程序的时候,编译时提示 ImportError: No module named ‘serial’

    解决办法:

    安装 serial module
    这里区分python2和 python3:

    首先需要在终端输入:

    sudo apt install python-pip //python2
    sudo apt install python3-pip    //python3
    

    在这里插入图片描述
    安装python3的 pip3的时候,如果时国内的软件源可能安装不上,(当时用中国科学技术大学的软件源,python3-pip下载有问题),换成ubuntu官网成功下载。

    如果系统已经安装过了pip,就不需要这一步了。
    然后通过:

    pip install pyserial    //python2
    pip3 install pyserial   //python3
    

    在这里插入图片描述

    可以从pyserial下载这里去获取源码进行熟悉和学习。

    4 PYCHARM 里面的no module name serial错误

    在这里插入图片描述
    错误原因在于:==interpreter的选择==
    在这里插入图片描述

    安装目录下的python,其模块只有一个setuptools,所以找不到serial
    在这里插入图片描述
    ANACONDA下的python.exe里面包含了多个模块,所以应该将interpreter改为该目录下的python.exe

    5 TypeError: ‘bool’ object is not callable

    因为 isOpen是属性所以有如下做法

     def isOpen(self):
            return True
    
      def is_active(self):
            return True
    
      def is_anonymous(self):
            return False
    

    不是方法,将sOpen()括号去掉,完美解决!

    展开全文
  • Arduino串口通信(Serial)

    万次阅读 2019-06-03 11:24:38
    Arduino串口的硬件结构 知道单片机运行原理的撸友们都清楚,单片机是基于微控制器(下称MCU)搭建的电子系统。单片机的所有功能其实都是由板载的MCU提供的,Arduino开发板当然也不例外。Arduino(这里单指Uno)的板...

    Arduino串口的硬件结构


    知道单片机运行原理的撸友们都清楚,单片机是基于微控制器(下称MCU)搭建的电子系统。单片机的所有功能其实都是由板载的MCU提供的,Arduino开发板当然也不例外。Arduino(这里单指Uno)的板载MCU为ATmega328P。

     

    在ATmega328P内部,实现串口的部件为USART。

    是Universal Synchronous and Asynchronous serial Receiver andTransmitter头字母的缩写,

    中文翻译为:通用同步/异步串行收发器。

    看到这儿,是不是有点头晕,这到底与串口有什么关系呀?!

    串口其实就是一种通讯方式的称呼,背后隐藏的实质是一种数据传输协议。数据一位一位地发送出去和接收进来。

    就像做糖葫芦时,一个一个地串进去;吃糖葫芦时,一个一个地撸进嘴里去。名字起得还是很贴合实际的。

    串口协议一方面定义了硬件方面的电气连接,另一方面又定义了要实现的协议。而USART就是实现协议的家伙,只是这个家伙是电子硬件系统,而不是我们传统理解的软件了。

    而且硬件实现比软件实现的速度和稳定性都要高得多!

    这样是不是清晰多了!

    USART内部结构是十分复杂的,简而言之主要由三部分组成:波特率发生器、接收单元、发送单元。

    每个单元的功能全部由硬件实现,同时以寄存器的形式对用户开放了配置接口(控制寄存器),又以寄存器的形式对用户开放了过程监控(状态寄存器)。

    上图为波特率发生单元的内部结构示意图。

     

    波特率发生器为串口的收发单元提供统一的时序,

    保证了收发逻辑的准确性和稳定性。

     

    这里要重点说说UBRRn(波特率设置寄存器)。

    初始情况下,预分频计数器(Prescaling Down-Counter)自动装载用户写入的UBRRn值,并持续向下计数,计数到0时,重新装置UBRRn值,同时产生一个波特率时钟,由此便实现了波特率的产生。

    UBRRn寄存器值与波特率的对应关系见下表所示。

     

    除此之外,其它寄存器主要用于工作模式的配置。

    因为正如名称所言,USART有同步和异步两种工作模式:

    异步即收发双方各用各的时钟,

    波特率产生关键部件见上图红色线框,

    基于内部时钟、UBRRn和预分频计数器实现,直接供给本机的收发单元使用。

    同步即收发双方共用一个波特率,由同步主机统一提供。主机通过内部时钟产生波特率,一方面供本机的收发单元使用,另一方面通过左下角的XCKn  Pin输出给从机使用;从机则从左下角的XCKn  Pin接收波特率,供从机内部的收发单元使用。

     

    下图为发送单元结构示意图。

    发送前,将待发送数据写入UDRn(数据发送寄存器),这一步是发送过程中用户唯一可参与的环节。

    此后,硬件会在检测到移位寄存器(TRANSMIT SHIFT REGISTER)空时,

    自动将待发送数据移入,并根据设置好的波特率,通过TXDn引脚将数据发送出去。

     

    注意,虽然在发送过程中,用户是不可能介入的,

    但USART设置了状态寄存器以供用户随时读取,以掌握发送的实时进度。

    最常用的就是TXC(发送完成)标识和UDRE(发送寄存器空)标识。

    TXC会在移位寄存器内数据全部被移出,且发送缓存内也没有数据时被置1,常用于判断数据是否全部发送。UDRE则会在发送数据缓存器为空时置1,以告诉用户可以写入新数据了!

    下图为接收单元结构示意图。

    工作中,时刻采集来自RxDn的输入信号,

    一旦检测到有效的开始位,则在每个波特率周期向接收移位寄存器(RECEIVESHIFT REGISTER)内移入一位数据位,直到接收到第一个停止位。

    上面的过程全由硬件自动实现,用户无法参与。直到接收的数据被转移到接收缓存,用户才可以通过UDRn寄存器读取它了。

     

    同样的,虽然在接收过程中,用户是不可能介入的,但USART设置了状态寄存器以供用户随时读取,以掌握接收的实时进度。

    最常用的就是RXC(接收完成)标识,只要接收缓存中有未被读取的数据,该位就会被置1,用户也就知道此时可以读数据了。Arduino串口的软件实现


    Arduino实现了硬串口和软串口两种形式的串口通信,并且都以类的形式进行管理。

    • 硬串口的操作类为HardwareSerial,定义于HardwareSerial.h源文件中,并对用户公开声明了Serial对象,用户在Arduino程序中直接调用Serial,就可实现串口通讯。
    • 软串口的操作类为SoftwareSerial,定义于SoftwareSerial.h源文件中,但不像硬串口那样,源文件中并没有事先声明软串口对象,Arduino程序中需要手动创建软串口对象。

    下面重点聊聊硬串口的实现机理。

    Arduino以数组的形式管理着接收和发送缓存:

    unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
    
    unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];

    对Uno而言,两个数组的大小都是64字节。

     

    为实现动态存储管理,又分别对接收缓存和发送缓存设计了头指针和尾指针:

    volatile rx_buffer_index_t _rx_buffer_head;
    
    volatile rx_buffer_index_t_rx_buffer_tail;
    
    volatile tx_buffer_index_t_tx_buffer_head;
    
    volatile tx_buffer_index_t _tx_buffer_tail;

    初始时,这些指针都设置为0(指向数组的头部)。

    接收过程的动态存储管理描述如下:

    当接收到数据时,头指针+1;被接收的数据读取时,尾指针+1;当尾指针赶上头指针时,就表明接收缓存里没有数据可读取了。

    接收到新数据时:

    从缓存中读取数据时:

    发送过程与此类似,不再展开。

    上述机制,从软件上彻底屏蔽了USART硬件上的缓存概念。对用户而言,操作的缓存仅仅指的是接收和发送数组,而不是真正的USART的UDR寄存器。寄存器操作全部由Arduino封装了!

    注意:由于缓存数组是队列式的,并不是首尾相连的环式,因此,操作过程中为防止指针超出数组边界,指针在操作时均设计了取模操作(%)。

     

    重点函数讲解


    Begin()-串口工作前的配置,包括波特率和数据格式。

    Arduino共定义了两种形式的begin函数:

    1)void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }

    2)void begin(unsigned long baud, byte config)

    第1种形式只有一个参数波特率,其实内部调用了第2种形式,只是固化了数据格式。

    第2种形式除了可以配置波特率外,还可以配置数据格式(数据位、校验位及停止位)。

    设置过程中,为简化寄存器操作,

    Arduino把常用的数据格式都以宏定义的形式封装好了。

    其中,8N1即“8个数据位,无校验位,1个停止位”。

     

    Available()-返回当前接收缓存(接收数组)内尚未读取的字节数。实现机制是取接收缓存头指针与尾指针的差值。实际使用中,具体的数值没有多大意义,主要用于判断接收缓存里是否还有未被读取的数据,以方便下一步的读取。

     

    Read()-从接收缓存中读取一个字节的数据。

    内部实现中,会首先判断是否还有数据可读(头指针是否赶上了尾指针),如不可读,则返回-1;如可读,则返回一个字节的数据,并更新尾指针。

    Write()-向发送缓存里写入新字节。内部实现中,为提供发送效率。首先判断发送缓存数组以及底层的发送寄存器,如果都为空,则直接操作发送寄存器。如果不都为空,则将头指针+1,并将新字节加入到发送缓存中,具体什么时候再发送呢?

    UDRE时刻:USART的接收缓存寄存器为空的时候。

    实现方法包括两种:轮询或中断。

    见下图红色线框内的部分。

     

    基础例程解析


    该例程从计算机中接收字符串,并打印到串口监视器上。

    void setup(){
    
          Serial.begin(9600);
    
    }
    
    String inputString="";
    
    void loop(){
    
          while(Serial.available()){
    
               inputString=inputString+char(Serial.read());
    
               delay(2);
    
          }
    
          if(inputString.length()>0){
    
              Serial.println(inputString);
    
              inputString="";
    
         }
    
    }

    正常情况下的输出为:

    上述例程在处理接收的字符串时,

    用while(Serial.available()){…}形式,

    同时为实现字符串的判断,使用delay(2)进行了适当的延时,

    如果不延时,你会发现打印效果并不是自己想要的结果?!

    为什么会这样呢?

    因为不加延时时,USART内部的发送速度远大于接收速度,

    从而导致每到一个新字节,进入一次available()发送出去后,就没有新的数据发送了,从而立即执行下面的打印命令!

     

    展开全文
  • python serial 模块使用方法

    万次阅读 多人点赞 2018-01-22 11:34:43
    一、概述  pyserial模块封装了对串口的访问。 二、特性  在支持的平台上有统一的接口。  通过python属性访问串口设置。  支持不同的字节大小、停止位、校验位和流控设置。... 支持二进制传输,
    一、概述
        pyserial模块封装了对串口的访问。
    二、特性
        在支持的平台上有统一的接口。
        通过python属性访问串口设置。
        支持不同的字节大小、停止位、校验位和流控设置。
        可以有或者没有接收超时。 
        类似文件的API,例如read和write,也支持readline等。
        支持二进制传输,没有null消除,没有cr-lf转换。
    三、系统要求
        python 2.3及以上版本,包括py3k。

    四、使用方法和实例

    1、导入pyserial模块

    import serial

    2、打开串行口

    // 打开串口0, 9600,8N1,连接超时0.5秒
    import serial
    ①选择设备
    ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5#使用USB连接串行口
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5#使用树莓派的GPIO口连接串行口
    ser=serial.Serial(1,9600,timeout=0.5)#winsows系统使用com1口连接串行口
    ser=serial.Serial("com1",9600,timeout=0.5)#winsows系统使用com1口连接串行口
    ser=serial.Serial("/dev/ttyS1",9600,timeout=0.5)#Linux系统使用com1口连接串行口
    print ser.name#打印设备名称
    print ser.port#打印设备名
    ser.open() #打开端口
    s = ser.read(10)#从端口读10个字节
    ser.write("hello")#向端口写数据
    ser.close()#关闭端口

    data = ser.read(20) #是读20个字符

    data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。

    data = ser.readlines()和ser.xreadlines()#都需要设置超时时间

    ser.baudrate = 9600 #设置波特率

    ser.isOpen() #看看这个串口是否已经被打开

    3、获得串行口状态
    串行口的属性:
    name:设备名字
    portstr:已废弃,用name代替
    port:读或者写端口
    baudrate:波特率
    bytesize:字节大小
    parity:校验位
    stopbits:停止位
    timeout:读超时设置
    writeTimeout:写超时
    xonxoff:软件流控
    rtscts:硬件流控
    dsrdtr:硬件流控
    interCharTimeout:字符间隔超时
           

    ①属性

    属性的使用方法:
    ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5)

    ser.open()

    print ser.name
    print ser.port
    print ser.baudrate#波特率
    print ser.bytesize#字节大小
    print ser.parity#校验位N-无校验,E-偶校验,O-奇校验
    print ser.stopbits#停止位
    print ser.timeout#读超时设置
    print ser.writeTimeout#写超时
    print ser.xonxoff#软件流控
    print ser.rtscts#硬件流控
    print ser.dsrdtr#硬件流控
    print ser.interCharTimeout#字符间隔超时
    ser.close()
    4、设置串行口状态

    需要用的常量

    bytesize:FIVE BITS、SIXBITS、SEVENBITS、EIGHTBITS
    parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
    stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
    异常:
    ValueError:参数错误
    SerialException:找不到设备或不能配置
    ser.baudrate=9600#设置波特率

    ser.bytesize=8#字节大小
    ser.bytesize=serial.EiGHTBITS#8位数据位

    ser.parity=serial.PARITY_EVEN#偶校验
    ser.parity=serial.PARITY_NONE#无校验
    ser.parity=serial.PARITY_ODD#奇校验

    ser.stopbits=1#停止位
    ser.timeout=0.5#读超时设置
    ser.writeTimeout=0.5#写超时
    ser.xonxoff#软件流控
    ser.rtscts#硬件流控
    ser.dsrdtr#硬件流控
    ser.interCharTimeout#字符间隔超时

    5、Readline方法的使用

            是读一行,以/n结束,要是没有/n就一直读,阻塞。

           使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。如果没有超时,readline会报异常。
    6、serial.Serial类——原生端口
    class serial.Serial 
    {
        __init__(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)
    }
        #其中:
        # bytesize:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS
        # parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
        # stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
        #异常:
        #ValueError:参数错误
        #SerialException:找不到设备或不能配置

        open():打开串口

        close():立即关闭串口

        __del__():析构函数

        read(size=1):从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。

        write(data):发送data,并返回发送字节数。如果bytes和bytearray可用(python 2.6以上),则接受其作为参数;否则接受str作为参数。
        #异常:SerialTimeoutException——配置了写超时并发生超时时发生此异常。

        inWaiting():返回接收缓存中的字节数

        flush():等待所有数据写出。

        flushInput():丢弃接收缓存中的所有数据

        flushOutput():终止当前写操作,并丢弃发送缓存中的数据。

        sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE

        setBreak(level=True):根据level设置break条件。

        setRTS(level=True)

        setDTR(level=True)

        getCTS()

        getDSR()

        getRI()

        getCD()

        #只读属性:
        name:设备名字
        portstr:已废弃,用name代替
        port:读或者写端口
        baudrate:波特率
        bytesize:字节大小
        parity:校验位
        stopbits:停止位
        timeout:读超时设置
        writeTimeout:写超时
        xonxoff:软件流控
        rtscts:硬件流控
        dsrdtr:硬件流控
        interCharTimeout:字符间隔超时

        #端口设置可以被读入字典,也可从字典加载设置:
        getSettingDict():返回当前串口设置的字典
        applySettingDict(d):应用字典到串口设置

        #对提供io库的系统(python 2.6或以上),Serial从io.RawIOBase派生。对其它系统,从FileLike派生。

        #异常:
        exception serial.SerialException
        exception serial.SerialTimeoutException

        #常量:
        serial.VERSION:pyserial版本

        #模块函数和属性:
        serial.device(number)

        serial.serial_for_url(url, *args, **kwargs)

        serial.protocol_handler_packages()

        serial.to_bytes(sequence):接收一个字符串或整数列表sequence,返回bytes实例
    }






    展开全文
  • 树莓派: 串口serial用法

    千次阅读 2019-07-20 23:00:42
    先安装sudo apt-get install python3-serial 一、打开串口 import serial ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5) #使用USB连接串行口 ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) #使用...
  • python serial模块

    千次下载 热门讨论 2020-07-30 23:30:42
    开发python串口的模块,简洁方便。在开发前,请确保安装此模块。
  • python安装serial 2019版

    千次阅读 2019-09-25 11:59:20
    python安装serial
  • 路由器的串口(serial)和以太口的区别

    万次阅读 2018-03-25 22:02:01
    1、串口,serial 口:最早的路由器对接需要通过Serial端口连接来实现, 用专门的串口线。  现在的企业级路由器还有串口,不过其实是CONSOLE口,用于对交换机进行配置,却用一根配置线插在上面,在电脑上打开超级终端...
  • python中pyserial模块使用方法

    万次阅读 2015-09-25 16:44:46
    一、概述  pyserial模块封装了对串口的访问。 二、特性  在支持的平台上有统一的接口。  通过python属性访问串口设置。  支持不同的字节大小、停止位、校验位和... 支持二进制传输,没有null消除,没
  • jvm发展至今已有很长一段时间,最开始
  • serial口和以太网口

    千次阅读 2014-10-09 11:16:34
    串行口是点到点链路,一方发送,对方肯定可以收到,不需要ARP解析出mac地址 而以太口是广播式多路访问链路,必须解析出对方的mac地址才能够封装数据包并发出 串口专为广域网设计,它可以做ISDN,PPP,帧中继等...
  • Arduino编程之Serial.println()和Serial.print()

    万次阅读 多人点赞 2018-04-22 20:03:11
    Arduino编程之Serial.println()和Serial.print()Arduino 的输出基本就用两个函数 print 和 println,区别在于后者比前者多了回车换行Serial.println(data)从串行端口输出数据,跟随一个回车(ASCII 13, 或 'r')和一...
  • 在pycharm里编写Python串口程序的时候,编译时提示 ImportError: No module named 'serial' 解决办法: 安装 serial module 这里区分python2和 python3: 首先需要在终端输入: sudo apt ...
  • python 安装serial模块

    万次阅读 2018-05-14 09:57:01
    运行时提示错误,说是没有安装serial模块,于是乎安装 pip install serial。下载了一会安装好了,再运行,还是提示同样的错误。上网查了一下,应该安装 pip install pyserial。这个问题之前遇到过两次了,但是总是记...
  • Arduino - 串口操作函数与示例代码大全

    万次阅读 多人点赞 2016-06-10 00:09:27
    本文总结了Arduino常用串口操作函数的说明、语法、参数、返回值。根据函数定义编写了示例代码,并通过实验解释了每个函数的具体用法。是对Arduino串口操作函数的较全面总结,可作为工具贴查找使用。
  • pycharm 中已经安装了serial,在调用 port_list = list(serial.tools.list_ports.comports()) 的时候报错: ModuleNotFoundError: No module named 'serial.tools' 这时我们不能直接pip install serial.tools,...
  • Arduino 的Serial.print()函数与Serial.write()函数的区别 1. 在发送数值类型数据时的区别 首先你需要理解这两句话: Serial.print() 发送的是字符, Serial.write() 发送的字节. 例 1.发送十进制的数据 int i=97;...
  • python serial 获取所有的串口名称

    万次阅读 2015-03-25 11:35:29
    #!/usr/bin/env python # -*- coding: utf-8 -* ...import serial import serial.tools.list_ports port_list = list(serial.tools.list_ports.comports()) if len(port_list) print "The Ser
  • 遇到该问题正常有两种情况:(1)你的文件名serial.py和引入的第三方库名字重复了,解决方法:重命名文件名(2)你没有安装第三方库文件,解决方法,pip install serial 之后 pip install pyserial (3)可能由于...
  • 在新的笔记本(没有和python有关的任何软件)上安装好python,在cmd窗口中使用pip install pyserial命令安装完成pyserial的包,打开python自带的IDLE,运行一下代码:import serial # 导入pyserial ...
1 2 3 4 5 ... 20
收藏数 243,862
精华内容 97,544
关键字:

serial