树莓派通讯数据plot

来源:互联网 发布:数据库点赞表 编辑:程序博客网 时间:2024/06/06 09:41

以下两种方法其实都是不行的,第三种方法没有尝试,有兴趣的可以尝试一下

方法一:通过tcp传送数据并用python的matplotlib库来画(帧数跟不上,严重延迟)

在硬件开发的时候很容易就会遇到要把数据plot一下,在树莓派里面暂时有两种方法,一种是蓝牙传输,一种是tcp的方式。比较熟悉tcp的方法,就是用了tcp的方法。

python的tcp连接方法简单,而且有丰富的库,那么就找了python的matplotlib类库来做。python的话要注意粘包的问题,原因。为了解决粘包问题,就先发送一个包的大小过来,接收之后,再设置python接收的包的大小,这样就能解决粘包的问题,不然数据很容易就乱了。在c里面发送int和double,float也是一个坑。如下:

char data[1024];
int j;j = sprintf(data, "%lf\t", nP);j += sprintf(data + j, "%lf\t", nD);j += sprintf(data + j, "%d\t", nSpeed);j += sprintf(data + j, "%d\t", g_nLeftMotorOut);j += sprintf(data + j, "%lf\t", rotation_y);j += sprintf(data + j, "%lf\t", gyro_scaled_y);j += sprintf(data + j, "%lf\t", gyro_y_delta);j += sprintf(data + j, "%lf\t", nDelta);j += sprintf(data + j, "%lf\t", last_y);

要通过sprintf来转换,放到一个char数组里面去,j是返回的长度,这个是方便传输。

在c传输过去之后,python接收到的话,是不能直接转成int的(python不熟,临时用的,或者有其他方法是可以的)需要做如下处理:

data = tcpCliSock.recv(BUFSIZE) # 接受数据
data = data.decode('utf-8')data = data.rstrip('\x00')

这个在调试的时候其实可以看到的,tcp传输的应该是char类型的,那么data接收到的应该是char拼成的string,那么在数字的后面就会有一个\x00的,这个如果不去掉的话,是不能转成int的,不转成int,你就不能当成一个长度来接收下一个发过来的包。这样就解决不了粘包的问题了。接收到了之后,对数据处理并画出来,发现有很大的延迟性,一分钟只有40多帧,这个是无法接收的,因为实时性达不到。

方法二:强大的matlab中有一个simulink,simulink中有树莓派的硬件包。

c语言真的不熟,再在c上折磨怎么发送int和double这些还是很实在,毕竟c好像就是要转成char来发送的,而simulink的设置一看就知道是直接读取流的数据,并通过设置数据类型的长度来解析数据的,因为simulink能运行到树莓派上面,其实就是因为simulink能把画出来的图转成c语言,这样就能运行在树莓派上了。那么c发送的char,但simulink是接收int、double这样的数据,那怎么办。其实真有点绝望,如果你按照char发过去的话,接收的数据会变得很古怪,但其实是能解释的,例如你要发送的数据是1,那么在simulink上显示的是49,这是为什么呢,其实根据我上面所说的就能理解了,c发送的1的char值,那么1的ascii值就是49,simulink是没有做转换的,直接读取到这么多字符,里面是什么数字就显示什么数字了,所以就出现了这样的情况(本人对于tcp的传输,c语言,python都不太熟悉,但表现的确是这样,所以有什么错误的,请留言纠正。)既然我都在1里面都做了,c发送给python了,不如就发给python,再用python发送给simulink,这样用python发送int应该会容易很多,但python其实不也是发送char的么经过研究之后,在这个绝望的时候,又发现了一个struct的东西,python和c语言沟通的方法,简直就是神器,大家可以去搜索一下python的struct和c的struct对应的。如下代码:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(address)values = (20)print (type(values))struct1 = struct.Struct('!I')packed_data = struct1.pack(values)print(packed_data)while True:    data  = input('>>> ')    print(type(data))    if not data:        break    # 数据收发和UDP基本一致    a = struct1.pack(int(data))    print(a)    s.send(a)s.close()

用了这种方法之后,在simulink里面就能读取出正确的数字出来了。事到这里的时候都已经12点多了,带着愉快回去睡觉了。故事还在第二天。

第二天回到公司,想用这种方法来画图的时候发现,还是画图有很明显的延迟,也只能有40多帧,我发送的频率是60多,完全跟不上。事到如此都经过2天的研究了,项目不能就这样拖下去了。

方法三:matlab是能够直接用tcp去接收数据并且绘制的,但没有试过,我想应该也会受到带宽的限制