ShareIdeas

本博客不再更新,欢迎访问我的github,https://github.com/sunke-github/

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

兴趣之余,利用晚上的时间,做一些个人兴趣方面的开发. 之前没接触过 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

posted on 2016-04-10 22:06  ShareIdeas  阅读(15976)  评论(0编辑  收藏  举报