ESP8266使用记录(三)

news2025/1/10 23:44:27

在这里插入图片描述

通过udp把mpu6050数据发送到PC端

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : ESP8266WiFiUdp_12
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : 小凯
日期/Date(YYYYMMDD)     : 20200319
程序目的/Purpose          : 
用于演示ESP8266WiFiUdp库中print函数
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
#include <Wire.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define ssid      "TaichiMaker_WIFI" //这里改成你的设备当前环境下WIFI名字
#define password  "xxxxxxx"          //这里改成你的设备当前环境下WIFI密码
 
#define BTN_1 D4       // 开关按钮
bool btn1_state = false;

WiFiUDP Udp;//实例化WiFiUDP对象
unsigned int localUdpPort = 16651;  // 自定义本地监听端口
unsigned int remoteUdpPort = 16650;  // 自定义远程监听端口
char incomingPacket[255];  // 保存Udp工具发过来的消息
char replyPacket[2048];  //发送的消息,仅支持英文
 
const int MPU6050_addr = 0x68;
int16_t AccX, AccY, AccZ, Temp, GyroX, GyroY, GyroZ;

void setup()
{
  Wire.begin();
  Wire.beginTransmission(MPU6050_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial.begin(9600);//打开串口
  Serial.println();
 
  Serial.printf("正在连接 %s ", ssid);
  WiFi.begin(ssid, password);//连接到wifi
  while (WiFi.status() != WL_CONNECTED)//等待连接
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("连接成功");
 
 //启动Udp监听服务
  if(Udp.begin(localUdpPort))
  {
    Serial.println("监听成功");
      
    //打印本地的ip地址,在UDP工具中会使用到
    //WiFi.localIP().toString().c_str()用于将获取的本地IP地址转化为字符串   
    Serial.printf("现在收听IP:%s, UDP端口:%d\n", WiFi.localIP().toString().c_str(), localUdpPort);
  }
  else
  {
    Serial.println("监听失败");
  }
  pinMode(BTN_1, INPUT_PULLUP);//开关按钮为输入开启上拉电阻
}
 
void loop()
{
  Wire.beginTransmission(MPU6050_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_addr, 14, true);
  AccX = Wire.read() << 8 | Wire.read();
  AccY = Wire.read() << 8 | Wire.read();
  AccZ = Wire.read() << 8 | Wire.read();
  Temp = Wire.read() << 8 | Wire.read();
  GyroX = Wire.read() << 8 | Wire.read();
  GyroY = Wire.read() << 8 | Wire.read();
  GyroZ = Wire.read() << 8 | Wire.read();
 
  DynamicJsonDocument doc(2048);
  // 创建json根节点对象
  JsonObject obj  = doc.to<JsonObject>();
  obj ["AccX"] = AccX;
  obj ["AccY"] = AccY;
  obj ["AccZ"] = AccZ;
  obj ["Temp"] = Temp;
  obj ["GyroX"] = GyroX;
  obj ["GyroY"] = GyroY;
  obj ["GyroZ"] = GyroZ;  
  //向udp工具发送消息
  Udp.beginPacket(Udp.remoteIP(), remoteUdpPort);//配置远端ip地址和端口 
  if (digitalRead(BTN_1) == 0)
  {
      obj ["Shoot"] = 1; 
  }
  else
  {
      obj ["Shoot"] = 0; 
  }
  String output;
  serializeJson(doc, replyPacket);    
  Udp.print(replyPacket);//把数据写入发送缓冲区
  Udp.endPacket();//发送数据 
  delay(16);//延时33毫秒
}

PC端Unity工程代码

using System;
using UnityEngine;

public class MPU6050 : MonoBehaviour
{
    private UdpServer server;

    public Transform trans;
    private bool fire = false;
    public float fireRate = 0.5f;
    private float nextFire = 0.0f;
    public GameObject sphere;

    float AccX;
    float accAngleX;
    float AccY;
    float accAngleY;
    float AccZ;

    float GyroX;
    float GyroY;
    float GyroZ;

    float gyroAngleX;
    float gyroAngleY;

    float roll;
    float pitch;
    float yaw;

    float elapsedTime, currentTime, previousTime;

    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
        Loom.Initialize();

        EventCenter.AddListener<string>("Receive", OnMessage);
        EventCenter.AddListener<string>("Error", OnError);

        server = new UdpServer();
        server.Start(16650, "192.168.0.56", 16651);

        server.Send("192.168.0.105");
    }

    // Update is called once per frame
    void Update()
    {
    	//射个球
        if (fire && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            GameObject go = Instantiate(sphere, trans.position, trans.rotation);
            go.SetActive(true);
            go.GetComponent<Rigidbody>().AddForce(trans.forward * 800);
        }
    }

    private void OnApplicationQuit()
    {
        server.Dispose();
        server = null;
    }

    int count = 0;
    float AccErrorX;
    float AccErrorY;
    float GyroErrorX;
    float GyroErrorY;
    float GyroErrorZ;

    void OnMessage(string msg)
    {
        Loom.QueueOnMainThread(() =>
        {
            //previousTime = currentTime;        // Previous time is stored before the actual time read
            //currentTime = DateTime.Now.Millisecond;            // Current time actual time read
            //elapsedTime = (currentTime - previousTime) / 1000;
            elapsedTime = 0.016f;
            //Debug.Log("elapsedTime:" + elapsedTime);
            //ifReceive.text += msg+ "\r\n";
            MPUMSG mpumsg = new MPUMSG();
            try
            {
                JsonUtility.FromJsonOverwrite(msg, mpumsg);
            }
            catch (Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
            //射个球
            if (mpumsg.Shoot == 1)
            {
                fire = true;
            }
            else
            {
                fire = false;
            }

            AccX = mpumsg.AccX / 16384.0f;
            AccY = mpumsg.AccY / 16384.0f;
            AccZ = mpumsg.AccZ / 16384.0f;

            accAngleX = (MathF.Atan(AccY / MathF.Sqrt(MathF.Pow(AccX, 2) + MathF.Pow(AccZ, 2))) * 180 / MathF.PI) - 0.58f;
            accAngleY = (MathF.Atan(-1 * AccX / MathF.Sqrt(MathF.Pow(AccY, 2) + MathF.Pow(AccZ, 2))) * 180 / MathF.PI) + 1.58f;

            accAngleX += 3.845675f;
            accAngleY += 1.984601f;

            GyroX = mpumsg.GyroX / 131.0f;
            GyroY = mpumsg.GyroY / 131.0f;
            GyroZ = mpumsg.GyroZ / 131.0f;

            GyroX += 1.553333f;
            GyroY += 3.210216f;
            GyroZ += 0.1432245f;

            if (count < 200)
            {
                count++;
                AccErrorX += accAngleX;
                AccErrorY += accAngleY;

                GyroErrorX += GyroX;
                GyroErrorY += GyroY;
                GyroErrorZ += GyroZ;
            }
            if (count == 200)
            {
                AccErrorX = AccErrorX / 200;
                AccErrorY = AccErrorY / 200;

                GyroErrorX = GyroErrorX / 200;
                GyroErrorY = GyroErrorY / 200;
                GyroErrorZ = GyroErrorZ / 200;

                Debug.LogWarning("AccErrorX:" + AccErrorX
                    + " AccErrorY:" + AccErrorY
                    + " GyroErrorX:" + GyroErrorX
                    + " GyroErrorY:" + GyroErrorY
                    + " GyroErrorZ:" + GyroErrorZ);
                //温度
                Debug.LogWarning("Temp:" + (mpumsg.Temp / 340.00 + 36.53));
                count = 0;
            }

            // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
            gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
            gyroAngleY = gyroAngleY + GyroY * elapsedTime;
            yaw = yaw + GyroZ * elapsedTime;
            // Complementary filter - combine acceleromter and gyro angle values
            roll = 0.96f * gyroAngleX + 0.04f * accAngleX;
            pitch = 0.96f * gyroAngleY + 0.04f * accAngleY;
            //Debug.Log("yaw:" + yaw + " roll:" + roll + " pitch:" + pitch);
            trans.eulerAngles = new Vector3(-roll, pitch, yaw);
        });
    }

    void OnError(string error)
    {
        Loom.QueueOnMainThread(() =>
        {
            Debug.LogError(error);
            if (error.Equals("serverSocket == null"))
            {
                fire = false;
            }
        });
    }
}

[Serializable]
public class MPUMSG
{
    public float AccX;
    public float AccY;
    public float AccZ;
    public float Temp;
    public float GyroX;
    public float GyroY;
    public float GyroZ;
    public int Shoot;
}

ESP8266&MPU6050&Unity

相关链接
https://howtomechatronics.com/tutorials/arduino/arduino-and-mpu6050-accelerometer-and-gyroscope-tutorial/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1037635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【视频处理】通过调用图像来重建新影片及计算颜色通道的平均灰度值,并检测帧与前一帧之间的差异(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网易云信4K 8K RTC助力远程医疗的技术实践

// 编者按&#xff1a;随着近年来国家关于缓解医疗资源分配不均的一系列政策出台&#xff0c;远程医疗作为平衡医疗资源分配的有力手段&#xff0c;目前正处于强劲发展阶段。网易云信运用超高清RTC视频技术助力医疗行业实现了远程高清视频病理分析和手术示教等能力。LiveVide…

Beyond Compare 4对比工具注册

Beyond Compare是一款文件及文件夹&#xff08;目录&#xff09;的对比工具。 Beyond Compare不仅可以快速比较出两个目录的不同&#xff0c;还可以比较每个文件的内容&#xff0c;而且可以任意显示比较结果。 Beyond Compare程序内建了文件浏览器&#xff0c;方便您对文件、…

NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061

今天发现,有两个处理器,启动以后,数据流不过去,后来,锁定问题在,queue队列上面,因为别的队列都可以通过,右键,empty queue清空,就是 这个队列不行,这个队列无法被删除,至于为什么导致这样的, 猜测是因为之前,流程设计好以后,队列没有设置背压,也没有设置队列中的内容大小和fl…

基于人脸5个关键点的人脸对齐(人脸纠正)

摘要&#xff1a;人脸检测模型输出人脸目标框坐标和5个人脸关键点&#xff0c;在进行人脸比对前&#xff0c;需要对检测得到的人脸框进行对齐&#xff08;纠正&#xff09;&#xff0c;本文将通过5个人脸关键点信息对人脸就行对齐&#xff08;纠正&#xff09;。 一、输入图像…

nginx实现反向代理实例

1 前言 1.1 演示内容 在服务器上访问nginx端口然后跳转到tomcat服务器 1.2 前提条件 前提条件&#xff1a;利用docker安装好nginx、tomcat、jdk8&#xff08;tomcat运行需要jdk环境&#xff09; 只演示docker安装tomcat&#xff1a; 默认拉取最新版tomcat docker pull t…

学习 OpenStack 的新指南和教程的六个建议

云基础设施是一个非常需要的技能。如果你正在为你的云基础架构需求寻找开源解决方案&#xff0c;那么 OpenStack 就是其中之一。OpenStack 是一个巨大的项目集合&#xff0c;为云服务的几乎每一个部分都提供了解决方案和集成。虽然这个巨大范围使得它成为一个强大的工具&#x…

若依前后端分离版搭建记录

一、如果是mysql8&#xff0c;得修改一下参数allowPublicKeyRetrieval为true&#xff0c;不然会报Public Key Retrieval is not allowed错误&#xff1a; 二、导入第二张表的数据库的时候&#xff0c;需要增加“--default-character-setutf8”参数才不会报错&#xff1a;

爱心助力口腔健康——三金西瓜霜全国“爱牙公益行”活动启动

在第35个“全国爱牙日”来临之际&#xff0c;三金西瓜霜牙膏联合中国善网公益平台共同发起的第四届三金西瓜霜“爱牙公益行”活动于近日启动。 今年“爱牙日”主题是“口腔健康 全身健康”&#xff0c;副主题是“关爱老年口腔乐享健康生活”。口腔健康是人体健康的重要组成部分…

两种常见矩形框旋转方法推导及其C++实现

在已知矩形中心点、长宽和旋转角度&#xff08;定义为矩形最长边与X轴正方向的夹角&#xff09;&#xff0c;如何确定矩形四个顶点的坐标&#xff0c;通常有以下两种处理方法。 法一&#xff1a;直接对顶点进行旋转 比如下图虚线框矩形是实线框矩形绕矩形中心点旋转后得到。在…

贴片电容耐压值选取和特性(包含实际电路和PCB)

一、一般电容的特性 ①容值大的电容&#xff0c;一般通低频率&#xff1b;  ②容值小的电容&#xff0c;一般通高频率。   注&#xff1a;详细请看这位博主的篇文章&#xff1a; 大电容为什么虑低频小电容为什么又虑高频?(个人整理) 二、贴片电容的耐压选取 ①贴片电容有2…

“构建完善的用户认证与数据交互系统“

目录 引言1.ElementUI完成登录注册1. 登录页面设计与实现2. 注册页面设计与实现 2.axios之get请求3.axios之post请求4.跨域问题的解决方案5.总结 引言 在现代Web应用程序开发中&#xff0c;用户认证和数据交互是至关重要的功能。本文将介绍如何使用ElementUI、axios和解决跨域…

PyTorch 模型性能分析与优化--第1部分

一、说明 这篇文章的重点将是GPU上的PyTorch培训。更具体地说&#xff0c;我们将专注于 PyTorch 的内置性能分析器 PyTorch Profiler&#xff0c;以及查看其结果的方法之一&#xff0c;即 PyTorch Profiler TensorBoard 插件。 二、深度框架 训练深度学习模型&#xff0c;尤其是…

Understanding Host Network Stack Overheads论文阅读笔记

RFS (Receive Flow Steering) RFS&#xff08;Receive flow steering&#xff09;和 RPS 配合使用。RPS 试图在 CPU 之间平衡收包&#xff0c;但是没考虑 数据的本地性问题&#xff0c;如何最大化 CPU 缓存的命中率。RFS 将属于相同 flow 的包送到相同的 CPU 进行处理&#xf…

通用深度模型UniverSeg:分割医疗图像

医学图像分割是医学分析的中心问题。它很昂贵&#xff0c;需要大量数据&#xff0c;而且是特定于任务的。如果我们可以拥有一个可以应用于任何分割任务的模型怎么办&#xff1f; 医学图像分割&#xff1a;为什么我们需要以及为什么它很困难&#xff1f; 分割的例子。一般来说&…

2808. 使循环数组所有元素相等的最少秒数;1015. 可被 K 整除的最小整数;1001. 网格照明

2808. 使循环数组所有元素相等的最少秒数 核心思想&#xff1a;枚举每个元素作为相等元素最多需要多少秒&#xff0c;然后维护它的最小值。最多需要多少秒是怎么计算的&#xff0c;我们可以把相等值的下标拿出来&#xff0c;然后你会发现两个相邻下标&#xff08;相邻下标只的…

three.js——宝马汽车产品展示

宝马汽车产品展示 前言效果图1、创建基本设置(场景和背景等&#xff09;2、加载模型和展厅灯光3、添加点击事件 前言 宝马汽车产品展示和原理讲解 演示网址&#xff1a;http://f-h-y.gitee.io/bmw-car-display-project/#/ 效果图 1、创建基本设置(场景和背景等&#xff09; …

ChatGPT详细搭建教程+支持AI绘画

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&#x…

The 2023 ICPC Asia Regionals Online Contest (1) E. Magical Pair(数论 欧拉函数)

题目 T(T<10)组样例&#xff0c;每次给出一个n(2<n<1e18)&#xff0c; 询问多少对&#xff0c;满足 答案对998244353取模&#xff0c;保证n-1不是998244353倍数 思路来源 OEIS、SSerxhs、官方题解 2023 ICPC 网络赛 第一场简要题解 - 知乎 题解 官方题解还没有…

【Springboot】整合Xxl-job

目录 一&#xff0c;下载1.1 官方文档地址1.2 源码仓库地址 二&#xff0c; 配置部署 "调度中心"2.1 初始化 "调度数据库"2.2 修改配置文件2.3 启动调度中心 三&#xff0c;springboot项目整合3.1 添加依赖3.2 修改配置文件3.3 执行器组件配置4.4 编写测试…