arduino串口绘图_arduino 串口实时绘图(以mpu9250为例)

本文介绍了如何使用Arduino和Python结合MPU9250传感器进行串口实时绘图。通过C++在Arduino端收集传感器数据并以特定格式发送,然后用Python的matplotlib库解析数据并绘制图表。虽然发现Python读取串口数据效率不高可能导致卡顿,但提供了SerialChart工具作为替代方案,并预告了将探讨Processing在数据可视化中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

兴趣之余,利用晚上的时间,做一些个人兴趣方面的开发. 之前没接触过 arduino, 无意之中买了个开发板做一些小开发, 这里利用python 读取 mpu9250 数据实时绘图.

下位机代码 C++

void Serial_SendDataPython( int16_t *sendData, uint8_t lens )

{

uint8_t tmpData[32] = {0}; //tmpData lens >= 2 * lens + 4

uint8_t *ptrData =tmpData;

uint8_t dataBytes= lens << 1;

uint8_t dataLens= dataBytes + 4;

uint8_t count= 0;

uint16_t tmpSum= 0;

tmpData[0] = 'S';while(count > 1]);//tmpData[count+2] = Byte8L(sendData[count >> 1]);

tmpData[count+1] = (sendData[count >> 1])>>8;

tmpData[count+2] = (sendData[count >> 1])&0x00ff; ;

count= count + 2;

}for(uint8_t i = 0; i < dataBytes; i++)

tmpSum+= tmpData[i+1];

tmpData[dataLens- 3] = (uint8_t)(tmpSum & 0x00FF);

tmpData[dataLens- 2] = '\r';

tmpData[dataLens- 1] = '\n';do{//Serial_SendByte(*ptrData++);

Serial.write(*ptrData++);

}while(--dataLens);

}

....................................

IMU_Buf[0] = testLostRate++;

MU_Buf[1] = ax/2;

IMU_Buf[2] = ay/2;

IMU_Buf[3] = az/2;

IMU_Buf[4] = gx/2;

IMU_Buf[5] = gy/2;

IMU_Buf[6] = gz/2;

IMU_Buf[7] = mx/2;

IMU_Buf[8] = my/2;

IMU_Buf[9] = mz/2;

Serial_SendDataMATLAB(IMU_Buf,10);

.................................................

这里简要说明一下, 发送数据以'S'开头,传感器数据分低8位和高8位数据分别发送,最后以换行符结尾.

1 """2 ldr.py3 http://electronut.in/plotting-real-time-data-from-arduino-using-python/

4 Display analog data from Arduino usingPython (matplotlib)5

6 Author: Mahesh Venkitachalam7 Website: electronut.in

8 """9 import ctypes10 import sys, serial, argparse11 import numpy asnp12 fromtime import sleep13 fromcollections import deque14

15 import matplotlib.pyplot asplt16 import matplotlib.animation asanimation17

18

19 # plot class

20 classAnalogPlot:21 # constr22 def __init__(self, strPort, maxLen):23 # open serial port24 self.ser = serial.Serial(strPort, 38400)25

26 self.ax = deque([0.0]*maxLen)27 self.ay = deque([0.0]*maxLen)28 self.az = deque([0.0]*maxLen)29 self.gx = deque([0.0]*maxLen)30 self.gy = deque([0.0]*maxLen)31 self.gz = deque([0.0]*maxLen)32 self.mx = deque([0.0]*maxLen)33 self.my = deque([0.0]*maxLen)34 self.mz = deque([0.0]*maxLen)35 self.maxLen =maxLen36

37 # add to buffer38 def addToBuf(self, buf, val):39 if len(buf) <40 buf.append else:42 buf.pop buf.appendleft>

45 # add data46 def add(self, data):47 assert(len(data) == 9)48 self.addToBuf(self.ax, data[0])49 self.addToBuf(self.ay, data[1])50 self.addToBuf(self.az, data[2])51 self.addToBuf(self.gx, data[3])52 self.addToBuf(self.gy, data[4])53 self.addToBuf(self.gz, data[5])54 self.addToBuf(self.mx, data[6])55 self.addToBuf(self.my, data[7])56 self.addToBuf(self.mz, data[8])57 # update plot58 def update(self,frameNum,a0,a1,a2,a3,a4,a5,a6,a7,a8):59 try:60 data =self.ser.readline()61 length =len(data)62 if length == 24 and ord(data[0])== 83:63 count = (ord(data[1])<<8)+ord(data[2])64 value = (ord(data[3])<<8)+ord(data[4])65 ax =ctypes.c_int16(value).value66 value = (ord(data[5])<<8)+ord(data[6])67 ay =ctypes.c_int16(value).value68 value = (ord(data[7])<<8)+ord(data[8])69 az =ctypes.c_int16(value).value70 value = (ord(data[9])<<8)+ord(data[10])71 gx =ctypes.c_int16(value).value72 value = (ord(data[11])<<8)+ord(data[12])73 gy =ctypes.c_int16(value).value74 value = (ord(data[13])<<8)+ord(data[14])75 gz =ctypes.c_int16(value).value76 value = (ord(data[15])<<8)+ord(data[16])77 mx =ctypes.c_int16(value).value78 value = (ord(data[17])<<8)+ord(data[18])79 my =ctypes.c_int16(value).value80 value = (ord(data[19])<<8)+ord(data[20])81 mz =ctypes.c_int16(value).value82

83 array =[ax,ay,az,gx,gy,gz,mx,my,mz]84 print array85 self.add(array)86 a0.set_data(range(self.maxLen), self.ax)87 a1.set_data(range(self.maxLen), self.ay)88 a2.set_data(range(self.maxLen), self.az)89 a3.set_data(range(self.maxLen), self.gx)90 a4.set_data(range(self.maxLen), self.gy)91 a5.set_data(range(self.maxLen), self.gz)92 a6.set_data(range(self.maxLen), self.mx)93 a7.set_data(range(self.maxLen), self.my)94 a8.set_data(range(self.maxLen), self.mz)95 except KeyboardInterrupt:96 print('exiting')97

98 returna0,99

100 # clean up101 def close(self):102 # close serial103 self.ser.flush()104 self.ser.close()105

106 # main() function107 def main():108 # create parser109 #parser = argparse.ArgumentParser(description="LDR serial")110 # add expected arguments111 #parser.add_argument('--port', dest='port', required=True)112

113 # parse args114 #args =parser.parse_args()115

116 strPort = 'COM3'

117 #strPort =args.port118

119 print('reading from serial port %s...' %strPort)120

121 # plot parameters122 analogPlot = AnalogPlot(strPort, 100)123

124 print('plotting data...')125

126 # setup animation127 fig =plt.figure()128 ax = plt.axes(xlim=(0, 100), ylim=(-20000, 20000))129 a0, =ax.plot([], [])130 a1, =ax.plot([], [])131 a2, =ax.plot([], [])132 a3, =ax.plot([], [])133 a4, =ax.plot([], [])134 a5, =ax.plot([], [])135 a6, =ax.plot([], [])136 a7, =ax.plot([], [])137 a8, =ax.plot([], [])138 anim =animation.FuncAnimation(fig, analogPlot.update,139 fargs=(a0,a1,a2,a3,a4,a5,a6,a7,a8),140 interval=50)141

142 # show plot143 plt.show()144

145 # clean up146 analogPlot.close()147

148 print('exiting.')149

150

151 # call main152 if __name__ == '__main__':153 main()

运行结果如下图:

从互联网搜索了一下,可以串口绘图的工具很多,试了一下 SerialChart工具,感觉还不错,界面如下:

下位机数据格式较简单:

interval(两次数据获取时间间隔,可设置为0),ax,ay,az 为int 类型,

Serial.print(interval); //microseconds since last sample, please note that printing more data will increase interval

Serial.print(",");

Serial.print(ax); //Inclination X axis (as measured by accelerometer)

Serial.print(",");

Serial.print(ay); //Inclination X axis (estimated / filtered)

Serial.print(",");

Serial.print(az); //Inclination X axis (estimated / filtered)

Serial.println("");

具体使用方法请参见官方网站: https://en.wikiversity.org/wiki/SerialChart_Tutorial  ,这里有详细说明和配置方法.

总结: 利用 python 读取seria 数据似乎效率不怎么高, 和之前matlab 测试遇到的情况情况类似,容易出现卡顿的情况. 下篇博客我将会介绍数据可视化工具 Processing在这方便的用途和代码.

参考,引用:

http://electronut.in/plotting-real-time-data-from-arduino-using-python/

https://en.wikiversity.org/wiki/SerialChart_Tutorial

40>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值