ubuntu下python读取六维力传感器数据,做个代码记录
整体下来感觉难点有3处:
1.找不到usb对应的接口。ubuntu系统接口和windows不太一样,不是com口,而是ttyUSB或者ttyACM,这个可以通过在终端输入”cd /dev"然后输入“ll tty*”去查看到底对应的是那个接口。简单一点的可以下个cutcom软件,也就是linux系统下的串口调试助手,然后直接去看。
2.发送数据收不到返回。找到对应的接口,然后也发送了对应的数据,但是就是没有回复或者说是打不开该串口,这是因为ubuntu系统会串口使用需要给权限,需要执行“sudo chmod 666 ttyUSB*",把权限给完之后就可以正常收发数据了。使用cutcom下遇到这种情况会直接告诉你权限拒绝,那就是说明没有给权限。另外这种情况每次插拔之后都需要执行一遍,要想每次插上就可以用的,需要去在udev.rule上面添加该usb的端口信息,具体怎么操作的,可以看下面。
a.终端直接输入"lsusb",通过插拔usb端口确定该端口的信息,我确定为如下信息:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a0c8392a7515414a866e1eb8941c12fa.png
b.从文件夹进入“/etc/udev/rules.d"文件夹下,然后终端输入”sudo gedit ***.rules",任意一个.rules都可以。这里用sudo gedit的原因是因为这里的文件打开保存需要权限,如果没有gedit的可以自己找资料下一个
c.打开文件后,直接将下面复制进去。然后将之前lsusb里面ID后面的2341:8037拆开放进idProduct和idVendor里面,然后再把SYMLINK里面改个自己想要的名字就可以了。然后保存退出。
KERNEL=="ttyACM*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8037", MODE:="0777", SYMLINK+="pressure"
d.这时候可以插拔端口试一下是否还需要权限,正常到这已经可以了。如果还是不行的话可以再加入下面两个指令试一下
sudo service udev reload
sudo service udev restart
3.接收到的数据不会转化。有的是4字节的hex码,有的是2字节的hex码,有的需要大端排序,有的需要小端排序,还有高低字节。这一块呢建议可以直接找厂家要一份协议使用说明,有的厂家如果直接带上位机可以要一份源码的转化说明。我程序中的就是4字节的hex码转化,供大家参考。
def hex_to_float(i,response):
binary_data = response[i:i+4]
binary_data = binary_data[2:4]+binary_data[0:2]
# 使用struct模块将二进制数据反序列化为浮点数
float_value = struct.unpack('>f', binary_data)[0]
float_value = round(float_value,3)
return float_value
总体代码如下
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import serial
import time
import binascii
import struct
def hex_to_float(i,response):
binary_data = response[i:i+4]
binary_data = binary_data[2:4]+binary_data[0:2]
# 使用struct模块将二进制数据反序列化为浮点数
float_value = struct.unpack('>f', binary_data)[0]
float_value = round(float_value,3)
return float_value
# print((i+1)/4,"is ",round(float_value,3)) # 输出: 3.141592653589793
def get_forceandtorque():
force_torque = [0,0,0,0,0,0]
try:
ser = serial.Serial(port="/dev/ttyUSB0",
baudrate=921600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=0.5,
xonxoff = False,
rtscts = False)
if ser.isOpen(): # 判断串口是否成功打开
print("打开串口成功。")
# 发送数据
bytes_str = 'DD 04 00 0C 00 0C 23 50'
bytes_str = bytes.fromhex(bytes_str)
ser.write(bytes_str)
try:
# 接收返回数据
response = ser.readline(1024) # 根据实际情况调整读取的字节
if response:
# 打印返回数据
# print("response is",response)
response_str = response.hex()
# print(len(response))
if len(response)==29:
fx=hex_to_float(3,response)
fy=hex_to_float(7,response)
fz=hex_to_float(11,response)
mx=hex_to_float(15,response)
my=hex_to_float(19,response)
mz=hex_to_float(23,response)
print("fx is ",fx)
print("fy is ",fy)
print("fz is ",fz)
print("mx is ",mx)
print("my is ",my)
print("mz is ",mz)
force_torque = [fx,fy,fz,mx,my,mz]
# print(force_torque)
except:
print("未接收到返回数据!")
else:
print("打开串口失败。")
except:
print("没有找到该串口。")
return force_torque
get_forceandtorque()