说明:本次是在windows 系统操作实现的。

serial

使用场景,获取得力扫码枪的扫码数据,该扫码枪支持三种通讯接口设置,如下图

即插即用的是 USB-KBW功能,插上去即可获取扫码数据,第二种是通过USB虚拟串口功能实现的,即通过com 口,

使用前可以通过扫码这三种方式中的其中一种进行设置通讯方式。

首先介绍第二种方式

第二种方式打开后,本机打开记事本,扫码是获取不到扫码数据的,询问客服,客服说该扫码枪不支持该功能。

但是通过程序监控com口是可以实现获取数据的。具体是通过serial模块进行操作的,具体介绍如下:

安装 pyserial模块

  1. pip install pyserial
  1. # 介绍一下serial的相关方法
  2.  
  3. open() #打开端口
  4. close() #立即关闭端口
  5. setBaudrate(波特率) #在打开的端口上更改波特率
  6. inWaiting() #返回接收缓冲区中的字符数
  7. readsize = 1 #读取“size”字符
  8. writes #将字符串s写入端口
  9. flushInput() #刷新输入缓冲区,丢弃所有的内容
  10. flushOutput() #刷新输出缓冲区,中止输出
  11. sendBreak() #发送中断条件
  12. setRTSlevel = 1 #设置RTS线路为指定的逻辑电平
  13. setDTRlevel = 1 #设置DTR行为指定的逻辑级别
  14. getCTS() #返回CTS行的状态
  15. getDSR() #返回DSR行的状态
  16. getRI() #返回RI行的状态
  17. getCD() #返回CD行的状态

实例介绍

检查是否有使用端口欧

  1. # FileName : demo.py
  2. # Author : Adil
  3. # DateTime : 2019/9/1 7:03
  4. # SoftWare : PyCharm
  5.  
  6. import serial
  7. # 这里使用的是windwos
  8. from serial.tools.list_ports_windows import *
  9.  
  10. plist = list(comports())
  11.  
  12. if len(plist) <= 0:
  13. print ("The Serial port can't find!")
  14. else:
  15. plist_0 =list(plist[0])
  16. serialName = plist_0[0]
  17. serialFd = serial.Serial(serialName,9600,timeout = 60)
  18. print ("check which port was really used >",serialFd.name)

实际读取端口数据

  1. # FileName : test.py
  2. # Author : Adil
  3. # DateTime : 2019/9/1 7:25
  4. # SoftWare : PyCharm
  5.  
  6. import serial
  7.  
  8. ser = serial.Serial('COM6', 9600,timeout=0.5)
  9. # ser = serial.Serial('COM6', 9600)
  10.  
  11. print(ser.name)
  12.  
  13. print(ser.port)
  14.  
  15. if not ser.isOpen():
  16. ser.open()
  17. print('com3 is open', ser.isOpen())
  18.  
  19. # 获取一行信息
  20. def recv(serial):
  21. print('')
  22. data = ''
  23. while serial.inWaiting() > 0:
  24. print(serial.inWaiting())
  25. print('')
  26. # data += str(serial.read(15)) # ok 要配合timeout 使用, 否则要传入已知 的 size
  27. # data += str(serial.readline()) # ok 要配合timeout 使用
  28. # data += str(serial.readlines()) # ok 要配合timeout 使用
  29. # data += str(serial.readall()) # ok 要配合timeout 使用
  30. data += str(serial.read_all()) # ok 要配合timeout 使用
  31.  
  32. print("************************************")
  33. #print(serial.read(13))
  34. print('准备打印data')
  35. # data = str(serial.read(19))
  36. print(data)
  37. print('data:%s'%data)
  38. print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
  39.  
  40. return data
  41.  
  42. # cursor.execute("DROP TABLE IF EXISTS productinfo")
  43.  
  44. '''
  45. sql="""CREATE TABLE productinfo(
  46. code CHAR(18),
  47. price double(9,2),
  48. info CHAR(25))"""
  49. cursor.execute(sql)
  50. '''
  51.  
  52. sum = 0.0
  53. while True:
  54. print('')
  55. data = recv(ser)
  56. print('')
  57. if data != '':
  58. print('')
  59. print(data)
  60. break
  61.  
  62. ser.close()
  1. print ser.name#打印设备名称
  2.  
  3. print ser.port#打印设备名
  4.  
  5. ser.open() #打开端口
  6.  
  7. s = ser.read(10)#从端口读10个字节
  8.  
  9. ser.write("hello")#向端口些数据
  10.  
  11. ser.close()#关闭端口
  12.  
  13. data = ser.read(20)#是读20个字符
  14.  
  15. data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
  16.  
  17. data = ser.readlines()和ser.xreadlines()#都需要设置超时时间
  18.  
  19. ser.baudrate = 9600 #设置波特率
  20.  
  21. ser.isOpen() #看看这个串口是否已经被打开

获得串行口状态、属性

串行口的属性:

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()

设置串行口状态

需要用的常量

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#字符间隔超时

Read

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

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

其中,read(value)方法的参数value为需要读取的字符长度。 如果想要全部读取,提供两个方法:

inWaiting:监测接收字符。

inWaitting返回接收字符串的长度值,然后把这个值赋给read做参数。

data =readall()::读取全部字符。

data = ser.read()可以读一个字符

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

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

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

  1. import serial
  2. import serial.tools.list_ports
  3.  
  4. #测试调试输出开关,正式发布需调整为False
  5. mytest = True
  6. #mytest = False
  7.  
  8. def getPort():
  9. port_serial=[]#返回串口列表
  10. port_list = list(serial.tools.list_ports.comports())
  11.  
  12. if len(port_list) <= 0:
  13. print("The Serial port can't find!")
  14. else:
  15. #if(mytest):print("port_list: ",port_list)
  16. for port in port_list:
  17. #if(mytest):print("port: ",port)
  18. port_serial.append(str(port).split(' ')[0])
  19. # if(mytest):print("port_serial: ",port_serial)
  20.  
  21. return(port_serial)
  22.  
  23. '''
  24. ** Descriptions: 发送串口数据
  25. ** Parameters:
  26. ** Returned value:
  27. ** Created By: yanerfree
  28. ** Created on: 2018年10月16日
  29. ** Remarks:以二进制读取
  30. '''
  31. def send_data(serial_port="COM6", baudrate=115200, bytesize=8,
  32. parity=serial.PARITY_NONE,stopbit=1,
  33. timeout=5, filename="F:\test.txt"):
  34. serial_port_1 = serial_port
  35. baudrate_1 = int(baudrate)
  36. bytesize_1 = int(bytesize)
  37. parity_1 = parity[:1]
  38. stopbit_1 = int(stopbit)
  39. timeout_1 = timeout
  40. filename_1 = filename
  41. print(serial_port_1,baudrate_1,bytesize_1,parity_1,stopbit_1,timeout_1,filename_1)
  42. try:
  43. print("初始化串口")
  44. # ser_port = serial.Serial("COM6",115200,timeout=1.5,parity=serial.PARITY_NONE,
  45. # stopbits=serial.STOPBITS_ONE,
  46. # bytesize=serial.EIGHTBITS)
  47. ser_port = serial.Serial(serial_port_1, baudrate_1,bytesize_1,parity_1,stopbit_1, timeout_1)
  48. print("串口是否打开:",ser_port.isOpen())
  49. if not ser_port.isOpen():
  50. ser_port.open()
  51. print("串口是否打开:",ser_port.isOpen())
  52.  
  53. f = open(filename_1,'rb')#打开或者新建一个文件
  54. i=0
  55. while 1:
  56. i = i + 1
  57. print("读取文 件第 %d 行"%i)
  58. #fileData=f.readline().strip('\n').encode(encoding='utf_8')#编码转换成字节发送
  59. fileData=f.readline().strip(b'\n')
  60. fileData=fileData.strip(b'\r')
  61. if fileData==b'':
  62. break
  63. #fileData_1=(fileData+'SDSA\r\n'.encode(encoding='utf_8'))
  64. fileData_1=(fileData+b'SDSA\r\n')
  65. print("发送数据为:",fileData_1)
  66. ser_port.write(fileData_1)
  67. #print("fileData[-11:]",fileData[-11:])
  68. if fileData[-11:]==b'***[END]***':
  69. #if fileData[-11:]=='***[END]***':
  70. print("检测到文件结束符,退出")
  71. break;
  72. print("等待2s")
  73. time.sleep(2)
  74. except Exception:
  75. print("发送脚本失败")
  76. finally:
  77. f.close()
  78. ser_port.close()
  79.  
  80. '''
  81. ** Descriptions: 获取串口数据
  82. ** Parameters:
  83. ** Returned value:
  84. ** Created By: yanerfree
  85. ** Created on: 2018年10月17日
  86. ** Remarks:二进制保存
  87. '''
  88. def receive_data(serial_port="COM6", baudrate=115200, bytesize=8,
  89. parity=serial.PARITY_NONE,stopbit=1,
  90. timeout=5,filename="F:\test.txt"):
  91. serial_port_1 = serial_port
  92. baudrate_1 = int(baudrate)
  93. bytesize_1 = int(bytesize)
  94. parity_1 = parity[:1]
  95. stopbit_1 = int(stopbit)
  96. timeout_1 = timeout
  97. filename_1 = filename
  98. print(serial_port_1,baudrate_1,bytesize_1,parity_1,stopbit_1,timeout_1,filename_1)
  99. try:
  100. print("初始化串口")
  101. #ser_port = serial.Serial(serial_port, baudrate,bytesize,parity,stopbit, timeout)
  102. ser_port = serial.Serial(serial_port_1, baudrate_1,bytesize_1,parity_1,stopbit_1, timeout_1)
  103. print("串口是否打开:",ser_port.isOpen())
  104. if not ser_port.isOpen():
  105. ser_port.open()
  106. print("串口是否打开:",ser_port.isOpen())
  107.  
  108. #f = open(filename_1,'w',encoding='utf-8')#打开或者新建一个文件
  109. f = open(filename_1,'wb')#以二进制打开或创建一个文件
  110.  
  111. while True:
  112. fileData=ser_port.readline()
  113. if(len(fileData)==0 or fileData[-6:]!=b'SDSA\r\n'):
  114. continue;
  115. print("接收到的数据:",fileData)
  116. fileData1=fileData.split(b'SDSA\r\n')[0]
  117. fileData2=fileData1+b'\n'#'0X0D'
  118. filedata_str=fileData1.decode(encoding='utf_8')
  119. content = filedata_str + '\n'
  120. print("保存的数据为:",fileData2)
  121. #saveFile(filename_1,fileData1)
  122. f.write(fileData2)
  123. if filedata_str[-11:]=='***[END]***':
  124. break;
  125. sleep(1)
  126. except Exception:
  127. print("获取脚本失败")
  128. finally:
  129. f.close()
  130. ser_port.close()
  131. if mytest: print("串口是否打开:",ser_port.isOpen())

pyusb

安装模块

  1. pip install pyusb

在设备列表中找到要使用的USB,如下图所示:

请注意上述的VID_0A12以及PID_0001;这个在使用USB接口时要用到VID以及PID;

  1. # FileName : usbdemo.py
  2. # Author : Adil
  3. # DateTime : 2019/9/1 10:26
  4. # SoftWare : PyCharm
  5.  
  6. import usb
  7.  
  8. all_devs = usb.core.find(find_all=True)
  9.  
  10. print(all_devs)
  11. for d in all_devs:
  12. if (d.idVendor == 'VID_04F2') & (d.idProduct == 'PID_B541'):
  13. print(d)

遇到报错:“usb.core.NoBackendError No backend available”

如果执行时遇到上面的错误,解决办法

最近一个案子是要用到USB信息交互,获取电脑连接的USB设备,主要是用到pyusb的库,按照网上的教程和代码,但是遇到了报错:usb.core.NoBackendError No backend available ,网上关于这个错误的解决方案也有不少,但是大部分都是英文,而且有些试了下并没有效果,不过好在最后还是完美解决,这里记录下。

我是根据他的解决方案来解决的,我的操作系统是Windows10_64位。

首先,打开链接,网页会自动下载libusb-1.0.20的压缩包

打开压缩包,选择MS64\dll\libusb-1.0.dll,复制到C:\Windows\System32

然后选择同目录下的libusb-1.0.lib到Python环境,我用的环境是conda的Python,所以就复制到D:\Anaconda3\Lib下

然后执行程序即可打印usb信息。

python 之serial、pyusb 使用开发的更多相关文章

  1. [Python] 利用Django进行Web开发系列(二)

    1 编写第一个静态页面——Hello world页面 在上一篇博客<[Python] 利用Django进行Web开发系列(一)>中,我们创建了自己的目录mysite. Step1:创建视图 ...

  2. 程序员带你十天快速入门Python,玩转电脑软件开发(四)

    本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...

  3. 程序员带你十天快速入门Python,玩转电脑软件开发(三)

    声明:本次教程主要适用于已经习得一门编程语言的程序员.想要学习第二门语言.有梦想,立志做全栈攻城狮的你 . 如果是小白,也可以学习本教程.不过可能有些困难.如有问题在文章下方进行讨论.或者添加QQ群5 ...

  4. 程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  5. 程序员带你十天快速入门Python,玩转电脑软件开发(一)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  6. Nginx+Python+uwsgi+Django的web开发环境安装及配置

    Nginx+Python+uwsgi+Django的web开发环境安装及配置 nginx安装 nginx的安装这里就略过了... python安装 通常系统已经自带了,这里也略过 uwsgi安装 官网 ...

  7. Python十分适合用来开发网页爬虫

    Python十分适合用来开发网页爬虫,理由如下:1.抓取网页自身的接口比较与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简练:比较其他动态脚本语言,如perl,shel ...

  8. 在windows下使用多版本Python安装相应的虚拟开发环境

    在windows下面使用多版本Python安装相应的虚拟开发环境   在搭建一个项目的时候,希望使用最新版的Python3.7版本,但是Python3.6的版本也要留下,那么问题来了,如何解决这个问题 ...

  9. Python windows serial

    Python windows serial 一.参考文章: Serial port programming http://www.cnblogs.com/2zhyi/p/3405339.html py ...

  10. python 3 serial module install

    /************************************************************************* * python 3 serial module ...

随机推荐

  1. Linux 内存文件系统-ramfs and tmpfs

    Linux内存文件系统:可满足高IO的要求 ramdisk: 基于虚拟在内存中的其他文件系统(ex2fs). 挂载方式:mount /dev/ram /mnt/ramdisk ramfs: 物理内存文 ...

  2. nginx配置中root和alias的区别

    例:访问http://127.0.0.1/download/*这个目录时候让他去/opt/app/code这个目录找. 方法一(使用root关键字): location / { root /usr/s ...

  3. Java中Class和单例类的作用与类成员的理解

    Java中Class类的作用与深入理解 在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每个对象所属的类.JVM利用运行时信息选择相应的方法执行.而保存 ...

  4. Node.js Koa2开发微信小程序服务端

    1.promise.async.await const Koa = require('koa') const app = new Koa() // 应用程序对象 有很多中间件 // 发送HTTP KO ...

  5. [C1] Andrew Ng - AI For Everyone

    About this Course AI is not only for engineers. If you want your organization to become better at us ...

  6. CSP-S 2019图论总结

    CSP-S 2019图论总结 一.最短路问题 模板 Floyd算法 void floyd() { memset(map,0x3f,sizeof(map)); for(int i=1;i<=n;i ...

  7. mysql里的insert

    insert不跟where 比如 insert into table (name) value('******')where id =1 肯定不行的 insert 语句 是插入语句,不跟条件的. 如果 ...

  8. 高性能MySQL count(1)与count(*)的差别

    -------------------------------------------------------------------------------------------------第一篇 ...

  9. ulimit 用法和系统优化

    ulimit :用于shell启动进程所占用的资源 -a:显示目前资源限制的设定: -c <core文件上限>:设定core文件的最大值,单位为区块: -d <数据节区大小>: ...

  10. C++ TCP客户端网络消息发送接收同步实现

    废话不多说, 直入主题, 我们在写客户单的时候希望在哪里发消息出去,然后在哪里返回消息(同步), 然后继续往下运行-, 而不是在这里发送了一个消息给服务端, 在另一个地方接受消息(异步) , 也不知道 ...