安装的时候要输入 pip install pyserial 进行安装
serial是python做串口通讯的库,在这里介绍了NX与Windows串口通讯 NX串口通讯windows_Suyuoa的博客-CSDN博客
1 使用demo
1.1 发送字符串
import serial
ser = serial.Serial('/dev/ttyTHS0', 9600)
if ser.isOpen == False:
ser.open()
ser.flushInput()
ser.write(('hello').encode("utf-8"))
- /dev/ttyTHS0是串口名称,9600是波特率
如果要发送中文需要将encode的参数改为GB2312
import serial
ser = serial.Serial('/dev/ttyTHS0', 9600)
if ser.isOpen == False:
ser.open()
ser.flushInput()
ser.write(('hello').encode("GB2312"))
1.2 接收
import serial
ser = serial.Serial('/dev/ttyTHS0', 9600)
if ser.isOpen == False:
ser.open()
ser.flushInput()
accept = ''
while accept == '':
accept = ser.readline()
accept = accept.decode("utf-8")
print(accept)
- 这里如果要接收中文要把decode()的参数改为GB2312
1.3 发送ASCII
import serial
ser = serial.Serial('/dev/ttyTHS0', 9600)
if ser.isOpen == False:
ser.open()
ser.flushInput()
ser.write(bytes.fromhex('4E 2D 61 00 00 00 FF 21'))
1.4 发送json
发json本质上和发字符串一样,我之前用过的一个机械手是要求是发送json
经测试发下面这串代码可以成功操作上面的机械臂
import serial
ser = serial.Serial('/dev/ttyUSB0', 115200)
if ser.isOpen == False:
ser.open()
ser.flushInput()
ser.write('{"T":106,"cmd":3.14,"spd":0,"acc":0}'.encode() + b'\n')
2 串口名称
2.1 windows
windows可以在 设备管理器的端口 中进行找到
是COM几在这里写多少进行了
2.2 Linux
2.2.1 USB型
USB型的命名大概率是 /dev/ttyUSB0,如果有多个串口就是/dev/ttyUSB1,/dev/ttyUSB2这种
可以输入ls -l [串口名称] 查看该端口是否可用
如果返回的是这种信息说明该端口可用
上面是我插上通讯设备时的情况,下面是我拔掉通讯设备的情况
如果返回的是上面这种信息说明该端口不可用
你也可以用 ls -l /dev/ttyUSB* 或 ls -l /dev/ttyS* 来获取所有相关的端口,之后再通过插拔得知你插拔的是哪个端口
2.2.2 非USB型
非USB型就要使用到固定的引脚,一般来讲你找到你使用板子的引脚图就可以找到引脚叫什么名字,比如NX
我们可以看到8引脚和10引脚依次是TX与RX,它们的串口名称为/dev/ttyTHS0
3 测发送内容的工具cutecom
linux可以sudo apt-get install cutecom直接装
在这里可以找到想要的串口(如果太多了就一个一个接)
选择好之后点open
如果出现了权限不够就用sudo开
打开之后你可以在input中发送命令,在input下面得到响应内容
如果要发hex,那么需要将这里搞成HEX,然后聚焦input按回车发出去
如果有响应那就说明通了
那么如果你知道你的响应是一个hex,那么你应该把这里勾上,那么这个hex你看起来就更方便
4 读协议的方法
有时我们接到的协议并不是简单的那种,比如发"hello"这个字符串,那么机器就会讲一声你好。
那么我们下面举几个例子
4.1 VISCA协议
visca是控制摄像头云台的协议,能控制摄像头的上下左右聚焦这些
目前很多摄像头都可以使用VISCA协议控制
协议内容就是下面这些
- X:摄像头的号,如果你就一个摄像头就写1
- ZZ:预制点的号 比如00 01 02 03 ... 0A 0B 一直到3F,一共有64个(16×4)
- VV:水平速度 01最慢 18最快
- WW 垂直速度 01最慢 14最快
这样的协议本质上就是发hex
import serial
ser = serial.Serial(
# 端口
port='/dev/ttyTHS0',
# 波特率
baudrate=9600,
# 数据位8位(数据帧由起始位、数据位、校验位、停止位构成。他这个通信协议就这么规定的,包括下面的校验位、停止位也是一样,他要定16位就16位,跟下面的81 01 06 01 18 17 03 01 FF没有关系)
bytesize=serial.EIGHTBITS,
# 无校验位
parity=serial.PARITY_NONE,
# 停止位1位
stopbits=serial.STOPBITS_ONE,
timeout=1
)
if ser.isOpen == False:
ser.open()
ser.flushInput()
#下面这个命令可以让摄像头云台向上移动
ser.write(bytes.fromhex('81 01 06 01 18 17 03 01 FF'))
在实例化serial.Serial()的时候,bytesize、parity、stopbits都可以不屑,因为默认的参数就是这三个
4.2 MODBUS-RTU
这个是直流电机的控制协议,从外观上看是这个东西
下面是它的具体协议内容
看上去很复杂,但本质上还是发hex
我们下面分析一下
4.2.1 地址码
就是几号设备。如果只有一个设备就是01
4.2.2 功能码
Modbus的功能码如下。这个就是人家定的,没有为什么这一说
我们可以看到我们设备支持的三个功能码
- 03 读保持寄存器(获取信息)
- 06 写单个保持寄存器(改变单个保持寄存器的值,换言之就是发送单条信息)
- 10 写多个保持寄存器(改变多个保持寄存器的值,换言之就是发送多条信息)