興趣之餘,利用晚上的時間,作一些我的興趣方面的開發. 以前沒接觸過 arduino, 無心之中買了個開發板作一些小開發, 這裏利用python 讀取 mpu9250 數據實時繪圖.python
下位機代碼 C++app
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位數據分別發送,最後以換行符結尾.electron
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 類型,ui
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("");spa
具體使用方法請參見官方網站: https://en.wikiversity.org/wiki/SerialChart_Tutorial ,這裏有詳細說明和配置方法.code
總結: 利用 python 讀取seria 數據彷佛效率不怎麼高, 和以前matlab 測試遇到的狀況狀況相似,容易出現卡頓的狀況. 下篇博客我將會介紹數據可視化工具 Processing在這方便的用途和代碼.blog
參考,引用:
http://electronut.in/plotting-real-time-data-from-arduino-using-python/
https://en.wikiversity.org/wiki/SerialChart_Tutorial