开发工具:thonny、pycharm

硬件设备:ESP32、MPU6050

mpu6050库文件(thonny)

import machineclass accel():def __init__(self, i2c, addr=0x68):self.iic = i2cself.addr = addrself.iic.start()self.iic.writeto(self.addr, bytearray([107, 0]))self.iic.stop()def get_raw_values(self):self.iic.start()a = self.iic.readfrom_mem(self.addr, 0x3B, 14)self.iic.stop()return adef get_ints(self):b = self.get_raw_values()c = []for i in b:c.append(i)return cdef bytes_toint(self, firstbyte, secondbyte):if not firstbyte & 0x80:return firstbyte << 8 | secondbytereturn - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)def get_values(self):raw_ints = self.get_raw_values()vals = {}vals["AcX"] = self.bytes_toint(raw_ints[0], raw_ints[1])vals["AcY"] = self.bytes_toint(raw_ints[2], raw_ints[3])vals["AcZ"] = self.bytes_toint(raw_ints[4], raw_ints[5])vals["Tmp"] = self.bytes_toint(raw_ints[6], raw_ints[7]) / 340.00 + 36.53vals["GyX"] = self.bytes_toint(raw_ints[8], raw_ints[9])vals["GyY"] = self.bytes_toint(raw_ints[10], raw_ints[11])vals["GyZ"] = self.bytes_toint(raw_ints[12], raw_ints[13])return vals  # returned in range of Int16# -32768 to 32767def val_test(self):  # ONLY FOR TESTING! Also, fast reading sometimes crashes IICfrom time import sleepwhile 1:print(self.get_values())sleep(0.05)

客户端(thonny)

#调用模块
import math
import network
import socket
import time
import mpu6050
from machine import Pin,I2Cport = 10000  #端口号
wlan = None  #wlan
listenSocket = None  #套接字i2c = I2C(scl=Pin(22), sda=Pin(21))   #初始化i2c对象
Mpu = mpu6050.accel(i2c)    #初始化MPU6050对象#创建WiFi
def createWifi():   global apap = network.WLAN(network.AP_IF)     #创建接入点界面ap.active(True)                      #激活界面ap.config(essid='ESP32',authmode=4,password='12345678')  #设置接入点的ESSID,和WiFi 通道while(ap.ifconfig()[0] == '0.0.0.0'):   #等待连接time.sleep(1)return True#求欧拉角
def IMUupdate(ax,ay,az,gx,gy,gz):global q0global q1global q2global q3global exIntglobal eyIntglobal ezInt# print(q0)#测量正常化norm = math.sqrt(ax*ax+ay*ay+az*az)#单元化ax = ax/normay = ay/normaz = az/norm#估计方向的重力vx = 2*(q1*q3 - q0*q2)vy = 2*(q0*q1 + q2*q3)vz = q0*q0 - q1*q1 - q2*q2 + q3*q3#错误的领域和方向传感器测量参考方向之间的交叉乘积的总和ex = (ay*vz - az*vy)ey = (az*vx - ax*vz)ez = (ax*vy - ay*vx)#积分误差比例积分增益exInt += ex*KieyInt += ey*KiezInt += ez*Ki#调整后的陀螺仪测量gx += Kp*ex + exIntgy += Kp*ey + eyIntgz += Kp*ez + ezInt#整合四元数q0 += (-q1*gx - q2*gy - q3*gz)*halfTq1 += (q0*gx + q2*gz - q3*gy)*halfTq2 += (q0*gy - q1*gz + q3*gx)*halfTq3 += (q0*gz + q1*gy - q2*gx)*halfT#正常化四元数norm = math.sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3)q0 /= normq1 /= normq2 /= normq3 /= norm#获取欧拉角 pitch、roll、yawpitch = math.asin(-2*q1*q3+2*q0*q2)*57.3roll = math.atan2(2*q2*q3+2*q0*q1,-2*q1*q1-2*q2*q2+1)*57.3yaw = math.atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3)*57.3return pitch,roll,yawtry:createWifi()ip = ap.ifconfig()[0]   #获取IP地址print(ip)listenSocket = socket.socket()   #创建套接字listenSocket.bind((ip, port))   #绑定地址和端口号listenSocket.listen(1)   #监听套接字listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)   #设置套接字print ('tcp waiting...')while True:print("accepting.....")conn, addr = listenSocket.accept()   #接收连接请求,返回收发数据的套接字对象和客户端地址#print(addr, "connec getd")while True:s = Mpu.get_values()#调用mpu6050方法,采集数据。ax=s.get('AcX')acx=ax/16384.0ay=s.get('AcY')acy=ay/16384.0az=s.get('AcZ')aacz=az/16384.0acz=aacz-1gx=s.get('GyX')gyx = gx/131.0gy=s.get('GyY')gyy = gy/131.0gz=s.get('GyZ')gyz = gz/131.0Kp = 100 #比例增益控制加速度计/磁强计的收敛速度Ki = 0.002 #积分增益控制陀螺偏差的收敛速度halfT = 0.001 #采样周期的一半#传感器框架相对于辅助框架的四元数(初始化四元数的值)q0 = 1q1 = 0q2 = 0 q3 = 0#由Ki缩放的积分误差项(初始化)exInt = 0eyInt = 0ezInt = 0#创建对象m,求欧拉角m = IMUupdate(ax,ay,az,gx,gy,gz)#从m元组中提取每个单独的数据pitch = m[0]roll = m[1]yaw = m[2]r = 'acx:'+str(acx)s = 'acy:'+str(acy)t = 'acz:'+str(acz)u = 'gyx:'+str(gyx)v = 'gyy:'+str(gyy)w = 'gyz:'+str(gyz)x = 'pitch:'+str(pitch)y = 'roll:'+str(roll)z = 'yaw:'+str(yaw)#换行处理,为接受数据做准备m = r+'\n'+s+'\n'+t+'\n'+u+'\n'+v+'\n'+w+'\n'+x+'\n'+y+'\n'+zconn.send(str(m))#发送,发送数据似乎只能支持str格式,还需要进一步查看手册time.sleep_ms(1000)#延时一定时间,避免发送过快except:if(listenSocket):   #判断套接字是否为空listenSocket.close()   #关闭套接字

服务端(thonny)

import network
import socket
import timeSSID = "ESP32"  #修改为你的WiFi名称
PASSWORD = "12345678"  #修改为你WiFi密码port = 10000  #端口号
wlan = None  #wlan
listenSocket = None  #套接字#连接WiFi
def connectWifi(ssid,passwd):   global wlanwlan = network.WLAN(network.STA_IF) #客户端,连接到上游WiFi接入点wlan.active(True)   #激活网络wlan.disconnect()   #断开WiFi连接wlan.connect(ssid, passwd)   #连接WiFiwhile(wlan.ifconfig()[0] == '0.0.0.0'):   #等待连接time.sleep(1)return Truetry:connectWifi(SSID,PASSWORD)sendSocket = socket.socket()#创建连接套接字addr=('192.168.4.1',10000)#设置目的IP与端口号sendSocket.connect(addr)#套接字连接print ('tcp connected')#连接成功except:if(listenSocket):   #判断套接字是否为空listenSocket.close()   #关闭套接字wlan.disconnect()   #断开WiFiwlan.active(False)   #冻结网络while True:data = sendSocket.recv(2048)#利用套接字进行数据接收,阻塞功能if(len(data)==0):#判定套接字是否为空print("close socket")sendSocket.close()   #关闭套接字else:d=data.decode('utf-8')   #去掉终端的b''print(d)#打印数据到终端

实时绘图监测肢体动作(pycharm)

import sys  #是一个从程序外部获取参数的桥梁
import time
import pyqtgraph as pg  #是一个纯python的图形和GUI库
import threading    #多线程模块
import serial   #串口通信模块
from PyQt5.QtCore import *  #包含了核心的非GUI功能。处理时间、文件和目录、各种数据类型、流、线程等
from PyQt5.QtGui import *   #包含了多种基本图形功能的类。窗口集、事件处理、2d图形、基本图像和界面以及字体文本。
from PyQt5.QtWidgets import *   #包含了一整套UI元素组件,用于建立符合系统风格的classic界面
import datetime #表示日期时间,年月日时分秒
from pyqtgraph import DateAxisItem  #?#版本
__version__ = '1.0'#创建一个主窗口的类
class MainWindow(QMainWindow):newdata = pyqtSignal(object)  # 创建信号#初始化、实例化对象def __init__(self, filename=None, parent=None):super(MainWindow, self).__init__(parent)self.setWindowTitle('健身动作监测')   #设置窗口标题self.setWindowIcon(QIcon(r"C:\Users\Administrator\Desktop\毕设\素材库\fitness"))   #设置窗体图标self.t = []self.acx = []self.acy = []self.acz =[]self.gyx = []self.gyy = []self.gyz = []self.pitch = []self.roll = []self.yaw = []self.history = 3600  # 历史保存数据的数量self.connected = Falseself.port = 'COM3'self.baud = 115200# 启动线程# QTimer.singleShot(0, self.startThread)self.btn = QPushButton('点击运行!')font = QFont()font.setPointSize(16)self.label = QLabel("实时获取健身动作数据")self.label.setFont(font)self.label.setAlignment(Qt.AlignCenter)self.data_label = QLabel("Data")# self.data_label.setAlignment(Qt.AlignCenter)self.pw = pg.PlotWidget()self.pw_angular = pg.PlotWidget()self.pw_angle = pg.PlotWidget()self.init_pg_accel()self.init_pg_angular()self.init_pg_angle()# 设置布局vb = QVBoxLayout()hb = QHBoxLayout()vb.addWidget(self.label)vb.addWidget(self.btn)#控制图表显示个数hb.addWidget(self.pw)hb.addWidget(self.pw_angular)hb.addWidget(self.pw_angle)vb.addLayout(hb)vb.addWidget(self.data_label)self.cwidget = QWidget()self.cwidget.setLayout(vb)self.setCentralWidget(self.cwidget)self.btn.clicked.connect(self.startThread)self.newdata.connect(self.updatePlot)#设置图表:加速度变化趋势def init_pg_accel(self):# 设置图表标题self.pw.setTitle("加速度变化趋势",color='008080',size='12pt')# 设置上下左右的labelself.pw.setLabel("left", "米/秒^2")self.pw.setLabel("bottom", "时间")# 设置Y轴 刻度 范围# self.pw.setYRange(min=10,max=50)  # 最大值# 显示表格线self.pw.showGrid(x=True, y=True)# 背景色改为白色self.pw.setBackground('w')# 居中显示 PlotWidget# self.setCentralWidget(self.pw)axis = DateAxisItem()  # 设置时间轴,主要此时x的数据为时间戳time.time()self.pw.setAxisItems({'bottom': axis})self.curve_acx = self.pw.getPlotItem().plot(pen=pg.mkPen('r', width=2))self.curve_acy = self.pw.getPlotItem().plot(pen=pg.mkPen('b', width=2))self.curve_acz = self.pw.getPlotItem().plot(pen=pg.mkPen('y', width=2))def init_pg_angular(self):# 设置图表标题self.pw_angular.setTitle("角速度变化趋势",color='008080',size='12pt')# 设置上下左右的labelself.pw_angular.setLabel("left", "弧度/秒")self.pw_angular.setLabel("bottom", "时间")# 设置Y轴 刻度 范围# self.pw.setYRange(min=10,max=50)  # 最大值# 显示表格线self.pw_angular.showGrid(x=True, y=True)# 背景色改为白色self.pw_angular.setBackground('w')# 居中显示 PlotWidget# self.setCentralWidget(self.pw)axis = DateAxisItem()  # 设置时间轴,主要此时x的数据为时间戳time.time()self.pw_angular.setAxisItems({'bottom': axis})self.curve_gyx = self.pw_angular.getPlotItem().plot(pen=pg.mkPen('r', width=2))self.curve_gyy = self.pw_angular.getPlotItem().plot(pen=pg.mkPen('b', width=2))self.curve_gyz = self.pw_angular.getPlotItem().plot(pen=pg.mkPen('y', width=2))def init_pg_angle(self):# 设置图表标题self.pw_angle.setTitle("角度变化趋势",color='008080',size='12pt')# 设置上下左右的labelself.pw_angle.setLabel("left", "度")self.pw_angle.setLabel("bottom", "时间")# 设置Y轴 刻度 范围# self.pw.setYRange(min=10,max=50)  # 最大值# 显示表格线self.pw_angle.showGrid(x=True, y=True)# 背景色改为白色self.pw_angle.setBackground('w')# 居中显示 PlotWidget# self.setCentralWidget(self.pw)axis = DateAxisItem()  # 设置时间轴,主要此时x的数据为时间戳time.time()self.pw_angle.setAxisItems({'bottom': axis})self.curve_pitch = self.pw_angle.getPlotItem().plot(pen=pg.mkPen('r', width=2))self.curve_roll = self.pw_angle.getPlotItem().plot(pen=pg.mkPen('b', width=2))self.curve_yaw = self.pw_angle.getPlotItem().plot(pen=pg.mkPen('y', width=2))def startThread(self):'''这里使用python的threading.Thread构造线程,并将线程设置为守护线程,这样主线程退出后守护线程也会跟着销毁'''self.btn.setEnabled(False)print('Start lisnening to the COM-port')# timeout参数很重要!可以结合波特率和传输的数据量计算出数据发送所需的时间serial_port = serial.Serial(self.port, self.baud, timeout=0.1)thread = threading.Thread(target=self.read_from_port, args=(serial_port,))#thread.setDaemon(True)  # 守护线程thread.start()  # 启动线程#更新绘图def updatePlot(self, signal):#self.curve_pitch.getViewBox().enableAutoRange()#self.curve_pitch.getViewBox().setAutoVisible()self.curve_acx.setData(signal[0], signal[1][0])self.curve_acy.setData(signal[0], signal[1][1])self.curve_acz.setData(signal[0], signal[1][2])self.curve_gyx.setData(signal[0], signal[1][3])self.curve_gyy.setData(signal[0], signal[1][4])self.curve_gyz.setData(signal[0], signal[1][5])self.curve_pitch.setData(signal[0], signal[1][6])self.curve_roll.setData(signal[0], signal[1][7])self.curve_yaw.setData(signal[0], signal[1][8])#处理数据def process_data(self, data: str):''''处理数据,注意原来通过串口发送的数据格式'''if len(self.t) >= self.history:  # 保证存储数量为设定的历史长度数量self.t.pop(0)self.acx.pop(0)self.acy.pop(0)self.acz.pop(0)self.gyx.pop(0)self.gyy.pop(0)self.gyz.pop(0)self.pitch.pop(0)self.roll.pop(0)self.yaw.pop(0)if data.startswith('acx'):try:# ['Temperature:28.00\r', 'Humidity:28.00']#strip()清除data = data.strip().replace(' ', '').replace('\r', '').replace('\r', '').replace('\r', '').replace('\r', '').replace('\r', '').replace('\r', '').replace('\r', '').replace('\r', '').split('\n')print(data)self.data_label.setText('Time:' + str(datetime.datetime.now()) + ', ' +data[0] + ', ' + data[1] +', '+data[2]+', '+data[3]+', '+data[4]+', '+data[5]+', '+data[6]+', '+data[7]+', '+data[8])self.t.append(time.time())self.acx.append(float(data[0].split(':')[1].strip()))self.acy.append(float(data[1].split(':')[1].strip()))self.acz.append(float(data[2].split(':')[1].strip()))self.gyx.append(float(data[3].split(':')[1].strip()))self.gyy.append(float(data[4].split(':')[1].strip()))self.gyz.append(float(data[5].split(':')[1].strip()))self.pitch.append(float(data[6].split(':')[1].strip()))self.roll.append(float(data[7].split(':')[1].strip()))self.yaw.append(float(data[8].split(':')[1].strip()))except:print('No valid data')signal = (self.t, (self.acx, self.acy,self.acz,self.gyx, self.gyy,self.gyz,self.pitch, self.roll,self.yaw))self.newdata.emit(signal)else:print('数据格式错误,接收到的数据为:', data)#?def read_all(self, port, chunk_size=200):"""Read all characters on the serial port and return them.参考:https://stackoverflow.com/questions/19161768/pyserial-inwaiting-returns-incorrect-number-of-bytes"""if not port.timeout:raise TypeError('Port needs to have a timeout set!')read_buffer = b''while True:# Read in chunks. Each chunk will wait as long as specified by# timeout. Increase chunk_size to fail quickerbyte_chunk = port.read(size=chunk_size)read_buffer += byte_chunkif not len(byte_chunk) == chunk_size:breakreturn read_buffer#从串口读取数据def read_from_port(self, ser):while True:bytedata = self.read_all(ser)if bytedata:self.process_data(bytedata.decode())  # 处理数据#停止线程def stopThread(self):print('Stop the thread...')#?def closeEvent(self, event):if self.okToContinue():event.accept()self.stopThread()else:event.ignore()#?def okToContinue(self):return True#?
if __name__ == '__main__':app = QApplication(sys.argv)win = MainWindow()win.show()app.exec_()

肢体动作监测(WiFi通信)相关推荐

  1. 基于Android和WI-FI通信的智能家居系统

    针对传统智能家居系统存在的操作复杂.可移动性差.升级维护成本高等缺点,本文提出了一种基于Android的智能家居系统的设计和实现方案.采用了具有Android操作系统的智能手机或平板电脑作为家居控制终 ...

  2. 对WIFI通信的一些理解(经常更新修改)

    1.WIFI模块配置的指令形式是什么? 指令形式是字符串,上位机或MCU通过串口连接WIFI芯片,发送指令协议中对应的字符串,实质就是发送这些字符串对应的ASCII码值.WIFI 芯片接受到这些字符串 ...

  3. Android通过广播监测Wi-Fi和便携式热点开关状态

    前言 Android端通过广播的形式动态监测Wi-Fi状态以及便携式热点开关状态,其中获取Wi-Fi状态很简单,网上很多示例,但是通过广播获取热点开关状态相关的资料少之又少,不过好在一个国外网站找到了 ...

  4. 树莓派与安卓手机app的WIFI通信(局域网通信)

    参考:树莓派与安卓手机app的WIFI通信(局域网通信) 作者:图触靓 发布时间: 2020-07-29 10:18:12 网址:https://blog.csdn.net/bhbhhyg/artic ...

  5. 基于51单片机的电子密码指纹锁无线WiFi通信原理图PCB

    功能介绍: 0.本系统采用STC12C5A60S2-35I作为单片机,因本系统需要使用WiFi模块和指纹模块,两者均是串口串口通信,89C52只有一路串口,因此无法满足需求,STC12C5A60S2- ...

  6. c语言实现wifi通信,stm32实现简单wifi通信

    最近需要做wifi通信实验,实验中的坑比较多,本文章用于记录实验中遇到的问题. ----------更新:本文章只实现了简单的wifi连接功能,最近封装了较完整的wifi协议,能够实现wifi连接.服 ...

  7. MicroPython玩转物联网之WIFI通信开发板

    互联网+.全民IoT等热词的兴起让物联网逐渐成为新一代信息技术的重要组成部分.思科首席未来学家.首席技术学家戴夫-埃万斯(DaveEvans)称,在未来十年内,物联网.云服务和虚拟人类等十大技术发展趋 ...

  8. CV5200无线WiFi通信模组,公里级数据传输应用,远距离无线交互方案

    无线Mesh网络根据设备自身的特点,支持点对多点.点对点.MESH自组网. 可广泛应用于森林防火.江河湖泊监控.无人机.机器人.电厂.电力.车辆.舰船等各种固定点和移动点的无线传输通信. WiFi就是 ...

  9. 基于WiFi模块的Android WiFi通信

    通过一段时间的学习和应用,理解了Android通信,通过这篇文章记录一下学习过程. 基于ESP8266的Android WiFi通信广泛应用于物联网领域,常用是通过局域网实现Android端和下位机的 ...

  10. 基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据

    基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据 注:只有文字描述的功能,其它功能无法实现,也不会制作 ID:6939642638150328Uun丶

最新文章

  1. 软件体系结构风格(第5-8课时)
  2. 修改tomcat6.0.25日志默认路径
  3. EASYPHP安装完Apache工作正常后,配置MYSQL的问题
  4. SQL Server 审核(Audit)-- 审核组件
  5. SPCAMLEditor–灵活实用的CAML编辑工具(上)
  6. Java(CallableStatement)调用Oracle存储过程返回结果集(ResultSet)
  7. 马云养的蚂蚁赚钱如印钞:每小时盈利500万,程序员平均年薪竟没到百万
  8. [鸟哥的Linux私房菜] X Window 与 纯文本模式的切换
  9. 29 个你必须知道的 Linux 命令
  10. 过滤输入字符串中的危险字符
  11. 设计模式实战-策略模式(Strategy Pattern)
  12. Elasticsearch安装(Linux)
  13. 2016秋季阅读计划
  14. 使用RxJava从多个数据源获取数据
  15. P6620 [省选联考 2020 A 卷] 组合数问题(斯特林数、下降幂)
  16. python回到首行_python读取文件首行和最后一行
  17. 无线网卡连接internet,有线网卡向另一台电脑分享网络(笔记本当有线路由器)...
  18. win10家庭中文版自动更新解决办法
  19. UI设计师福利之手把手打造SVG动画应用的微场景
  20. 弘辽科技:信息层面售假排查逻辑

热门文章

  1. 将运动相机作为电脑摄像头 - 以Windows+SJCAM C100+为例
  2. js 正则验证数字(整数,货币型,浮点型)
  3. 关于ie8以上浏览器下—兼容性视图设置
  4. 【DL】第 2 章 :变分自动编码器(VAE)
  5. pe系统怎么删除服务器密码,win10系统怎么用pe删除系统开机密码
  6. 雪鹰领主服务器维护,37雪鹰领主8月16日维护更新公告
  7. SpringBoot+Vue项目校园台球厅人员与设备管理系统
  8. 身为程序员你必须掌握的职场黑话!
  9. D3D渲染--D3DRender.h
  10. Python xlwt,xlrd对Excel表求笛卡尔积