兴趣之余,利用晚上的时间,做一些个人兴趣方面的开发. 之前没接触过 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 < dataBytes) { // tmpData[count+1] = Byte8H(sendData[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.py 3 http://electronut.in/plotting-real-time-data-from-arduino-using-python/ 4 Display analog data from Arduino using Python (matplotlib) 5 6 Author: Mahesh Venkitachalam 7 Website: electronut.in 8 """ 9 import ctypes 10 import sys, serial, argparse 11 import numpy as np 12 from time import sleep 13 from collections import deque 14 15 import matplotlib.pyplot as plt 16 import matplotlib.animation as animation 17 18 19 # plot class 20 class AnalogPlot: 21 # constr 22 def __init__(self, strPort, maxLen): 23 # open serial port 24 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 = maxLen 36 37 # add to buffer 38 def addToBuf(self, buf, val): 39 if len(buf) < self.maxLen: 40 buf.append(val) 41 else: 42 buf.pop() 43 buf.appendleft(val) 44 45 # add data 46 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 plot 58 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).value 66 value = (ord(data[5])<<8)+ord(data[6]) 67 ay = ctypes.c_int16(value).value 68 value = (ord(data[7])<<8)+ord(data[8]) 69 az = ctypes.c_int16(value).value 70 value = (ord(data[9])<<8)+ord(data[10]) 71 gx = ctypes.c_int16(value).value 72 value = (ord(data[11])<<8)+ord(data[12]) 73 gy = ctypes.c_int16(value).value 74 value = (ord(data[13])<<8)+ord(data[14]) 75 gz = ctypes.c_int16(value).value 76 value = (ord(data[15])<<8)+ord(data[16]) 77 mx = ctypes.c_int16(value).value 78 value = (ord(data[17])<<8)+ord(data[18]) 79 my = ctypes.c_int16(value).value 80 value = (ord(data[19])<<8)+ord(data[20]) 81 mz = ctypes.c_int16(value).value 82 83 array = [ax,ay,az,gx,gy,gz,mx,my,mz] 84 print array 85 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 return a0, 99 100 # clean up 101 def close(self): 102 # close serial 103 self.ser.flush() 104 self.ser.close() 105 106 # main() function 107 def main(): 108 # create parser 109 #parser = argparse.ArgumentParser(description="LDR serial") 110 # add expected arguments 111 #parser.add_argument('--port', dest='port', required=True) 112 113 # parse args 114 #args = parser.parse_args() 115 116 strPort = 'COM3' 117 #strPort = args.port 118 119 print('reading from serial port %s...' % strPort) 120 121 # plot parameters 122 analogPlot = AnalogPlot(strPort, 100) 123 124 print('plotting data...') 125 126 # set up animation 127 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 plot 143 plt.show() 144 145 # clean up 146 analogPlot.close() 147 148 print('exiting.') 149 150 151 # call main 152 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