├── README.md ├── wifi.py ├── LICENSE ├── mpu6050.py ├── PC端.py └── ESP32duan.py /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MicroPython——ESP32驱动mpu6050 4 | MicroPython固件使用的是Lobo的micropython固件而非官网固件, 5 | 此程序仅对加速度X轴数据进行了平滑滤波和上传, 6 | 7 | [mpu6050采集] -- IIC --> (ESP32) -->[平滑滤波] --mqtt--> (PC) --> [matplotlib动态展示] 8 | 9 | 10 | 11 | ## 引脚 12 | 13 | |ESP32|MPU6050| 14 | |---|---| 15 | |P32|SCL| 16 | |P33|SDA| 17 | 18 | INT和AD0不使用 19 | ## 注意 20 | mqtt服务器是在阿里云上自己搭建的,所以ip地址被隐去了,需要自己设定 21 | 22 | mqtt上传每200ms一次以内时间大概几分钟后会断线,即便设置了自动重连也连接不上 23 | 后续可以多次采集,一次上传 24 | -------------------------------------------------------------------------------- /wifi.py: -------------------------------------------------------------------------------- 1 | 2 | ip_addr = '127.0.0.1' 3 | 4 | def do_connect(host, password): 5 | global ip_addr 6 | import network 7 | sta_if = network.WLAN(network.STA_IF) 8 | ap_if = network.WLAN(network.AP_IF) 9 | if ap_if.active(): 10 | ap_if.active(False) 11 | 12 | if not sta_if.isconnected(): 13 | 14 | print('connecting to network...') 15 | sta_if.active(True) 16 | sta_if.connect(host, password) 17 | while not sta_if.isconnected(): 18 | pass 19 | print('network config:', sta_if.ifconfig()) 20 | ip_addr = sta_if.ifconfig()[0] 21 | return ip_addr -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 cnbright 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /mpu6050.py: -------------------------------------------------------------------------------- 1 | import machine 2 | 3 | class accel(): 4 | 5 | def __init__(self, i2c, addr=0x68): 6 | 7 | self.iic = i2c 8 | 9 | self.addr = addr 10 | 11 | self.iic.begin(0) 12 | 13 | self.iic.writeto(self.addr, bytearray([107, 0])) 14 | 15 | self.iic.stop() 16 | 17 | 18 | 19 | def get_raw_values(self): 20 | 21 | self.iic.start() 22 | 23 | a = self.iic.readfrom_mem(self.addr, 0x3B, 14) 24 | 25 | self.iic.stop() 26 | 27 | return a 28 | 29 | 30 | 31 | def get_ints(self): 32 | 33 | b = self.get_raw_values() 34 | 35 | c = [] 36 | 37 | for i in b: 38 | 39 | c.append(i) 40 | 41 | return c 42 | 43 | 44 | 45 | def bytes_toint(self, firstbyte, secondbyte): 46 | 47 | if not firstbyte & 0x80: 48 | 49 | return firstbyte << 8 | secondbyte 50 | 51 | return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1) 52 | 53 | 54 | 55 | def get_values(self): 56 | 57 | raw_ints = self.get_raw_values() 58 | 59 | vals = {} 60 | 61 | vals["AcX"] = self.bytes_toint(raw_ints[0], raw_ints[1]) 62 | 63 | vals["AcY"] = self.bytes_toint(raw_ints[2], raw_ints[3]) 64 | 65 | vals["AcZ"] = self.bytes_toint(raw_ints[4], raw_ints[5]) 66 | 67 | vals["Tmp"] = self.bytes_toint(raw_ints[6], raw_ints[7]) / 340.00 + 36.53 68 | 69 | vals["GyX"] = self.bytes_toint(raw_ints[8], raw_ints[9]) 70 | 71 | vals["GyY"] = self.bytes_toint(raw_ints[10], raw_ints[11]) 72 | 73 | vals["GyZ"] = self.bytes_toint(raw_ints[12], raw_ints[13]) 74 | 75 | return vals # returned in range of Int16 76 | 77 | # -32768 to 32767 78 | 79 | 80 | 81 | def val_test(self): # ONLY FOR TESTING! Also, fast reading sometimes crashes IIC 82 | 83 | from time import sleep 84 | 85 | while 1: 86 | 87 | print(self.get_values()) 88 | 89 | sleep(0.05) 90 | -------------------------------------------------------------------------------- /PC端.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | #coding=utf-8 3 | import threading 4 | from time import sleep 5 | import random 6 | from matplotlib import pyplot as plt 7 | from matplotlib import animation 8 | import numpy as np 9 | import seaborn as sns 10 | 11 | 12 | gesture_i = [0] * 2200 13 | # 创建画布 14 | fig = plt.figure(figsize=(15, 10)) 15 | ax1 = fig.add_subplot(1, 1, 1) 16 | ax1.set_facecolor('none')#设置该子图背景透明,其他子图同理 17 | # 绘制初始图形 18 | x = np.arange(0, 2200, 1) # x轴 19 | #ax1.set_ylim(-1, 1)#设置y轴范围为-1到1 20 | line1, = ax1.plot(x, gesture_i,color='coral') 21 | 22 | 23 | #初始化函数 24 | def init(): 25 | gesture_i 26 | line1.set_ydata(gesture_i) 27 | ax1.set_xlabel("I") 28 | return line1 29 | 30 | #更新图像的函数 31 | def animate(i): 32 | global gesture_i 33 | line1.set_ydata(gesture_i) 34 | return line1 35 | 36 | 37 | def draw_view(): 38 | ani = animation.FuncAnimation(fig=fig, 39 | func=animate, 40 | frames=100, 41 | init_func=init, 42 | interval=100, 43 | blit=False) 44 | plt.show() 45 | 46 | 47 | #接收数据线程 48 | import paho.mqtt.client as mqtt 49 | 50 | def on_message(client, userdata, msg): 51 | '''处理message回调''' 52 | global gesture_i 53 | #print('topic: {}'.format(msg.topic)) 54 | #print('message: {}'.format(str(msg.payload))) 55 | new_val = float(str(msg.payload)[2:-1]) 56 | gesture_i.pop(0) 57 | gesture_i.append(new_val) 58 | 59 | 60 | 61 | def Rec_Data(): 62 | client = mqtt.Client() 63 | client.on_message = on_message 64 | HOST_IP = '这里需要改为你的matt服务器地址' # Server的IP地址 65 | HOST_PORT = 1883 # mosquitto 默认打开端口 66 | TOPIC_ID = 'acc_data'# TOPIC的ID 67 | client.connect(HOST_IP, HOST_PORT, 60) 68 | client.subscribe(TOPIC_ID) 69 | client.loop_forever() 70 | 71 | 72 | t1 = threading.Thread(target=Rec_Data) 73 | 74 | if __name__ == '__main__': 75 | t1.setDaemon(True) 76 | t1.start() 77 | 78 | #t.join() 79 | draw_view() 80 | print("接收结束") -------------------------------------------------------------------------------- /ESP32duan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import mpu6050 3 | import network 4 | from machine import Pin,I2C 5 | import machine 6 | import time 7 | from wifi import do_connect 8 | 9 | i2c = I2C(scl=Pin(33), sda=Pin(32)) 10 | accelerometer = mpu6050.accel(i2c) 11 | ints = accelerometer.get_ints() 12 | #初始化传感器 13 | sum_val = 0 14 | for i in range(400): 15 | acc_data = accelerometer.get_values() 16 | sum_val+=acc_data['AcX']/16384 17 | 18 | error_x = sum_val/400 19 | 20 | #平滑滤波器 21 | 22 | class avg_fiter(): 23 | def __init__(self, data_list): 24 | self.data_sum=sum(data_list) 25 | self.data_list=data_list 26 | 27 | def fit(self, data, len): 28 | #data是传入的数据,len是平滑的长度 29 | self.data_sum = self.data_sum - self.data_list[0] + data 30 | self.data_list.pop(0) 31 | self.data_list.append(data) 32 | data = self.data_sum/len 33 | return data 34 | 35 | data_list=[0,0,0,0,0] 36 | ''' 37 | for i in range(5): 38 | acc_data = accelerometer.get_values() 39 | data_list.append(acc_data['AcX']/16384) 40 | ''' 41 | avgfiter = avg_fiter(data_list) 42 | ip_addr = do_connect(host='42',password='15863335982') 43 | 44 | def conncb(task): 45 | print("[{}] Connected".format(task)) 46 | 47 | def disconncb(task): 48 | print("[{}] Disconnected".format(task)) 49 | 50 | 51 | def subscb(task): 52 | #print("[{}] Subscribed".format(task)) 53 | pass 54 | 55 | def pubcb(pub): 56 | print("[{}] Published: {}".format(pub[0], pub[1])) 57 | 58 | def datacb(msg): 59 | #print("[{}] Data arrived from topic: {}, Message:\n".format(msg[0], msg[1]), msg[2]) 60 | pass 61 | 62 | 63 | TOPIC = b'acc_data' 64 | mqtt = network.mqtt('acc_0', "mqtt://这里需要改为你的matt服务器地址", port=1883, 65 | lwt_topic=TOPIC,autoreconnect=True, 66 | cleansession=True, 67 | connected_cb=conncb, 68 | disconnected_cb=disconncb, subscribed_cb=subscb, 69 | published_cb=pubcb, data_cb=datacb) 70 | mqtt.start() 71 | while not mqtt.subscribe(TOPIC): 72 | pass 73 | 74 | def tcb(timer): 75 | acc_data = accelerometer.get_values() 76 | try: 77 | mqtt.publish(TOPIC, str(acc_data['AcX']/16384-error_x)) 78 | except: 79 | print("MQTT HAND BROKEN!!!!!") 80 | 81 | #t1 = machine.Timer(2) 82 | #t1.init(period=50, mode=t1.PERIODIC, callback=tcb) 83 | while True: 84 | #这个速度不能太快 85 | time.sleep_ms(1000) 86 | acc_data = accelerometer.get_values() 87 | try: 88 | #print(mqtt.status()) 89 | temp = avgfiter.fit(acc_data['AcX']/16384-error_x,5) 90 | mqtt.publish(TOPIC, str(temp)) 91 | 92 | except: 93 | print('===========END============') 94 | break 95 | #mqtt.publish(TOPIC, 'Hi from Micropython') 96 | #接收到消息时会进入中断,不用像umqtt那样写个循环 97 | #mqtt.stop() 98 | 99 | --------------------------------------------------------------------------------