基于巴法云的esp8266实现温湿度、LED、sg90舵机和HC-RS04实现的小程序远程控制

2023-11-15

基于巴法云的esp8266实现温湿度、LED、sg90舵机和HC-RS04实现的小程序远程控制


本项目想法已经在我脑海想了很久了,都没有时间去实现它,这次刚刚考完试就用了两天把它做了出来,希望对大家有帮助,有什么需要的可以在下面留言喔。

  • 其实这两天遇到的坑还是比较多的,就比如在数据传输的没能想到用cmd9进行获取返回值
  • 还有一个便是舵机消抖问题

具体代码.

#include <ESP8266WiFi.h>
#include <SimpleDHT.h>
#include <U8g2lib.h>
#include <Servo.h>

///*********************************************///

//巴法云的定义
#define TCP_SERVER_ADDR "bemfa.com"
#define TCP_SERVER_PORT "8344"
#define DEFAULT_STASSID  "123456"
#define DEFAULT_STAPSW "1234567890"
String UID = "xxxxx";
String TOPIC = "temp"; //用于传输温湿度的主题
//主题名字,可在控制台新建
String TOPIC2  = "Light002";  //用于led控制的主题
String TOPIC3  = "distance";  //用于HC-RS04控制的主题
String TOPIC4  = "servo";  //用于电机控制的主题

///*********************************************///

//DHT11引脚值
int pinDHT11 = D4;  //连接dht11的引脚
//单片机LED引脚值
int LED_Pin = D2;  //假设连接led的引脚
int pin1= D5;  //连接HC-RS04的 trig引脚
int pin2= D6;  //连接HC-RS04的echo引脚
int servopin = D7;   //电机引脚
volatile float item;       //物体距离

///*********************************************///
//led 控制函数
void turnOnLed();
void turnOffLed();

//电机控制函数
void turnleft();
void turnright();

//led状态状态
String my_led_status = "off";
//电机状态状态
String my_servo_status = "left";
float cm;

//电机状态之后的 防止状态没变 导致一直运行 防抖
bool my_servo_left =true;
bool my_servo_right =true;

///*********************************************///
//下面的2代表上传间隔是2秒
#define upDataTime 2*1000

SimpleDHT11 dht11(pinDHT11);
Servo myservo;  


//最大字节数
#define MAX_PACKETSIZE 512


//tcp客户端相关初始化,默认即可
WiFiClient TCPclient;
String TcpClient_Buff = "";
unsigned int TcpClient_BuffIndex = 0;
unsigned long TcpClient_preTick = 0;
unsigned long preHeartTick = 0;
unsigned long preTCPStartTick = 0;
bool preTCPConnected = false;

///*********************************************///
//相关函数初始化
//连接WIFI
void doWiFiTick();
void startSTA();

//TCP初始化连接
void doTCPClientTick();
void startTCPClient();
void sendtoTCPServer(String p);


///*********************************************///
/*
  *发送数据到TCP服务器
 */
void sendtoTCPServer(String p){
  
  if (!TCPclient.connected()) 
  {
    Serial.println("Client is not readly");
    return;
  }
  TCPclient.print(p);   //将数据发送到巴法云中
  Serial.println("刚刚发送到云端的数据为:");
  Serial.println(p);
}
///*********************************************///
/*
  *初始化和服务器建立连接
*/
void startTCPClient(){
  if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT))){
    Serial.print("\nConnected to server:");
    Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
    String tcpTemp="";
    tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC2+"&msg="+my_led_status+"\r\n";         //这里可以随便写一个主题,主要是测试与服务器的连接状态
    sendtoTCPServer(tcpTemp);
    preTCPConnected = true;
    preHeartTick = millis();
    TCPclient.setNoDelay(true);
  }
  else{
    Serial.print("Failed connected to server:");
    Serial.println(TCP_SERVER_ADDR);
    TCPclient.stop();
    preTCPConnected = false;
  }
  preTCPStartTick = millis();
}
///*********************************************///
/*
  *检查数据,发送数据
*/
void doTCPClientTick(){
 //检查是否断开,断开后重连
   if(WiFi.status() != WL_CONNECTED) return;

  if (!TCPclient.connected()) {//断开重连

  if(preTCPConnected == true){

    preTCPConnected = false;
    preTCPStartTick = millis();
    Serial.println();
    Serial.println("TCP Client disconnected.");
    TCPclient.stop();
  }
  else if(millis() - preTCPStartTick > 1*1000)//重新连接
    startTCPClient();
  }
  else
  {
    if (TCPclient.available()) {//收数据
      char c =TCPclient.read();
      TcpClient_Buff +=c;
      TcpClient_BuffIndex++;
      TcpClient_preTick = millis();
      if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){
        TcpClient_BuffIndex = MAX_PACKETSIZE-2;
        TcpClient_preTick = TcpClient_preTick - 200;
      }
      preHeartTick = millis();   
    }   
    if(millis() - preHeartTick >= upDataTime){//上传数据
      preHeartTick = millis();

      /*****************获取DHT11 温湿度*****************/
      // read without samples.
      byte temperature = 0;
      byte humidity = 0;
      int err = SimpleDHTErrSuccess;
      if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
        Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
        return;
      }      
      /*********************数据上传*******************/
      /*
        数据用#号包裹,以便app分割出来数据,&msg=#23#80#on#\r\n,即#温度#湿度#按钮状态#,app端会根据#号分割字符串进行取值,以便显示
        如果上传的数据不止温湿度,可在#号后面继续添加&msg=#23#80#data1#data2#data3#data4#\r\n,app字符串分割的时候,要根据上传的数据进行分割
      */
      String upstr = "";
      String upstr1 = "";
      String upstr2 = "";
      String upstr3 = "";

      //发送数据   温湿度及距离用cmd2 发送无需返回值    而需要返回值的  这种情况需要是服务器端操控单片机的话 使用cmd9
      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg=#"+temperature+"#"+humidity+"#\r\n";
      upstr1 = "cmd=9&uid="+UID+"&topic="+TOPIC2+"\r\n";
      upstr2 = "cmd=2&uid="+UID+"&topic="+TOPIC3+"&msg="+item+"\r\n";
      upstr3 = "cmd=9&uid="+UID+"&topic="+TOPIC4+"\r\n"; 
        
      sendtoTCPServer(upstr);
      sendtoTCPServer(upstr1);
      sendtoTCPServer(upstr2);
      sendtoTCPServer(upstr3); 
      upstr = "";
      upstr1 = "";
      upstr2 = "";
      upstr3 = "";
    }
  }
  if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
  {//data ready
    TCPclient.flush();
    Serial.println("Buff");
    Serial.println(TcpClient_Buff);
    //TcpClient_Buff.indexOf判断返回值中是否有这些字符   本人建议最好加上主题
    if((TcpClient_Buff.indexOf("servo&msg=right") > 0)) {
     String my_servo1_status = "right";
      turnright();
    }else if((TcpClient_Buff.indexOf("servo&msg=left") > 0)) {
      String my_servo1_status = "left";
      turnleft();
    } 
    if((TcpClient_Buff.indexOf("Light002&msg=on") > 0)) {
      String my_led1_status = "off";
      turnOffLed();
    }else if((TcpClient_Buff.indexOf("Light002&msg=off") > 0)) {
      String my_led1_status = "on";
     turnOnLed();
   } 
   TcpClient_Buff="";
   TcpClient_BuffIndex = 0;
  }
  item = checkdistance_2_3();
  }
//打开灯泡
void turnOnLed(){
  Serial.println("Turn on");
  digitalWrite(LED_Pin,LOW);
  my_led_status = "on";
}
//关闭灯泡
void turnOffLed(){
  Serial.println("Turn off");
  digitalWrite(LED_Pin,HIGH);
  my_led_status = "off";
 
}
//打开电机
void turnleft(){
  Serial.println("Turn left");
   my_servo_status ="left";
   if(my_servo_left==true){          //解决待机问题的消抖
    servopulse(180);   //引用脉冲函数
    delay(1000);
    my_servo_left=false;
   }else{
      my_servo_right=true;
    }
  }
void turnright(){
  Serial.println("Turn right");
  my_servo_status ="right";
 if(my_servo_right==true){     //解决待机问题的消抖
    servopulse(0);   //引用脉冲函数
    delay(1000);
    my_servo_right=false;
 }else{
  my_servo_left=true;
  }
}

void startSTA(){
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(DEFAULT_STASSID, DEFAULT_STAPSW);
}

//*********************************************************************
void doWiFiTick(){
  static bool startSTAFlag = false;
  static bool taskStarted = false;
  static uint32_t lastWiFiCheckTick = 0;
  if (!startSTAFlag) {
    startSTAFlag = true;
    startSTA();
    Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());
  }
  //未连接1s重连
  if ( WiFi.status() != WL_CONNECTED ) {
    if (millis() - lastWiFiCheckTick > 1000) {
      lastWiFiCheckTick = millis();
    }
  }
  //连接成功建立
  else {
    if (taskStarted == false) {
      taskStarted = true;
      Serial.print("\r\nGet IP Address: ");
      Serial.println(WiFi.localIP());
      startTCPClient();
    }
  }
}

//*********************************************************************
float checkdistance_2_3() {         //获取物体距离函数
  digitalWrite(pin1, LOW);
  delayMicroseconds(pin1);
  digitalWrite(pin1, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin1, LOW);
  float distance = pulseIn(pin2, HIGH) / 58.00;
  delay(10);
  return distance;
}
float iif(bool expression, float truePart, float falsePart)
{
  return expression ? truePart : falsePart;
}


//*********************************************************************
//消抖
void servopulse(int angle)//定义一个脉冲函数
{
  //发送50个脉冲
  for (int i = 0; i < 50; i++) {
    int pulsewidth = (angle * 11) + 500; //将角度转化为500-2480的脉宽值
    digitalWrite(servopin, HIGH);   //将舵机接口电平至高
    delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数
    digitalWrite(servopin, LOW);    //将舵机接口电平至低
    delayMicroseconds(20000 - pulsewidth);
  }
  //  delay(20);
}
// 初始化,相当于main 函数
void setup() {
 myservo.attach(servopin); 
   pinMode(pin1, OUTPUT);
  pinMode(pin2, INPUT);
  Serial.begin(115200);
  //初始化引脚为输出
	pinMode(LED_Pin,OUTPUT);
}
//循环
void loop() {
  doWiFiTick();
 doTCPClientTick();
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于巴法云的esp8266实现温湿度、LED、sg90舵机和HC-RS04实现的小程序远程控制 的相关文章

  • PMP常用英文术语缩写总结(文字版+表格版+图片版)

    PMP常用英文术语缩写总结 文字版 表格版 图片版 文字版 PMBOK Project Management Body of Knowledge 项目管理知识体系 PMI Project Management Institute 项目管理协
  • 数据结构--图的应用--最短路径

    最短路径 两种常见的最短路径问题 一 单源最短路径 用Dijistra迪杰斯特拉 算法 二 所有顶点间的最短路径 用Floyd 弗洛伊德 算法 Dijistra算法 1 初始化 先找出从源点v0到各终点Vk的的直达路径 V0 Vk 即通过一
  • 【element-plus】icon在菜单的使用(二)

    前言 之前觉得升级的icon不好使用是以为不能动态的设置图标 现在发现我错了 升级后的icon同样能满足之前的需求 本篇主要说明一下配置菜单时如何使用icon 一 下载依赖包 因为动态引入的icon随时都会调整 所以之前引入所有的icon最
  • 【满分】【华为OD机试真题2023B卷 JAVA&JS】VLAN资源池

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 VLAN资源池 知识点数组字符串 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 VLAN是一种对局域网设备进行逻辑划分的技术 为了标识不同的VLAN 引入VLAN I

随机推荐

  • C++字符串 处理函数合集

    本博客的内容源自 数据结构 用面向对象方法与C 描述 第二版 的内容 章节4 4 在阅读原文的情况下整理得出的读书笔记 均写在代码的注释中 供大家参考 include
  • HDF5 windows编译 release版本、Debug版本

    由于最近急需的一个项目 需要hdf5库 误打误撞 编译成功 特此记录 1 下载源代码 官网下载地址 https portal hdfgroup org display support HDF5 1 12 2 files 找到如下地址 本人电
  • 设计模式 -- Adapter 适配器模式

    转自 http blog csdn net joyney article details 4000818 以下内容是我和小组的兄弟学习设计模式我做的课件 我整理出来和大家分享 有不妥之处敬请指出 上次做的桥接模式 Bridge 这次是适配器
  • 小程序wxs使用教程

    1 什么是wxs wxs是小程序的一种脚本语言 它类似JavaScript 但是与JavaScript有所不同 wxs是一种数据绑定和逻辑处理的语言 它可以在wxml中使用 并且可以在wxml中直接调用 使用wxs可以实现更高效 更灵活的数
  • Games101,Lecture 13(光线与物体求交,引入包围盒)

    光线追踪 光线追踪更多的用于离线应用 因为一帧一般需要一万个CPU小时 原理 由摄像机发出感应光线 判断与物体相交的点是否可以与 光源连线 无遮挡物 如何判断光线与物体有交点 是管线追踪中较难的部分 光线与物体求交 1 与隐式表示的曲面求交
  • RabbitMQ 端口详解

    4369 epmd 25672 Erlang distribution Epmd 是 Erlang Port Mapper Daemon 的缩写 在 Erlang 集群中相当于 dns 的作用 绑定在4369端口上 5672 5671 AM
  • c++ 定时器_「STM32」定时器中断实验

    在上一篇文章中 STM32 定时器概述 中 定时器可以被人为分为4个大部分 时钟发生器 实际模块 输入捕获 输出比较 而定时器中断实验 我们更多的在操作时钟发射器这个模块 这个应用也是定时器最基本的应用了 时钟选择 内部时钟选择 时钟计算方
  • SpringBoot使用@JsonDeserialize和@JsonSerialize注解的功能简介说明

    转自 SpringBoot使用 JsonDeserialize和 JsonSerialize注解的功能简介说明 下文笔者讲述 JsonDeserialize和 JsonSerialize注解的功能简介说明 SpringMVC 在Spring
  • 【SQL基础】【关键字大写】条件查询:比较、不等于、IN、为空、BETWEEN

    概述 1 内容介绍 条件查询 比较 不等于 IN 为空 BETWEEN 2 建表语句 drop table if exists user profile CREATE TABLE user profile id int NOT NULL d
  • 使用 vite 代替 webpack 搭建 react 前端开发环境

    说明 在大型前端项目中 我们一般会使用 webpack Rollup 等工具进行模块整合 但是庞大的代码量会使得我们在开发阶段花费更多的时间在 代码改动 gt 页面渲染 这个阶段 即使使用 HMR 这个问题也没有完全的解决 项目代码量达到一
  • plsql链接服务器无响应,sqlplus 连接数据库无响应

    一批三台安装服务器 先后出现了sqlplus 连接数据库无响应问题 1 因为几乎同一时间出现问题 起初怀疑是网络组对网络有整体调整 后经过确认网络组有调整 但不影响我们的服务器 2 telnet server 1521端口正常响应 3 从终
  • 深度解析,抖音对口型唱歌类短视频内容制作流程,步骤技巧分享

    就像之前分享的信息差案例一样 任何时候都有信息差 但是还有一种叫认知差 就是认知高的人赚认知低的人的钱 不是有句话很火吗 你永远也赚不到认知以外的钱 更多精彩干货请关注共众号 萤火宠 你的认知很高 可以高客单价赚高认知人群的钱 但是也有些人
  • 图形学-改进的Bresenham算法

    图形学 改进的Bresenham算法 原理 代码 原理 虽然中点Bresenham算法是一种效率很高的算法 但也还有改进的余地 当然 其基本原理仍是每次在最大位移方向上走一步 而另一个方向上走还是不走取决于误差项的判断 根据中点Bresen
  • JSP和JavaBean

    8 JSP 8 1 什么是JSP Java Servlet Pages java服务器端页面 也和Servlet一样 用于实现动态Web技术 最大特点 写JSP就像是写HTML 区别 HTML只给用户提供静态的数据 JSP页面中可以嵌入Ja
  • 智慧政务行业发展报告

    转自微信公众号 智慧城市圈子邱文斌 一 智慧政务行业发展状况 从上个世纪90年代开始 政府信息化的建设就开始围绕 通 进行 而现今正逐渐过渡到 云 的建设 从网络的连通 数据的整合 到云的出现与整合 政府信息化的建设是一个漫长而又快速发展的
  • element-ui 实现多日期选择

    一 前端代码
  • Spring 多线程异步上传图片、处理水印、缩略图

    使用环境 SpringBoot FastDfs thumbnailator fdfs环境自己搞吧 thumbnailator maven依赖
  • C++中引用的用法以及将引用作为函数的形参

    在C 中引用就相当于是给变量起了一个别名 有点类似于指针 但是与指针又不同 引用的初始化 int i i 10 变量i的引用 引用必须在创建的时候就要初始化 而指针可以在任意的时候初始化 引用就相当于是给变量起了一个别名 int i r i
  • HTML基本结构

    HTML一般是在vscod中进行书写 后缀为html 其完整的基本结构如下 h1 一级标题 h1 每一个尖括号 lt gt 代表着标签或者说是元素 不同的标签代表有着不同的作用 标签一般成对出现后一个标签为前一个标签加一个 例如 但也有单个
  • 基于巴法云的esp8266实现温湿度、LED、sg90舵机和HC-RS04实现的小程序远程控制

    基于巴法云的esp8266实现温湿度 LED sg90舵机和HC RS04实现的小程序远程控制 具体代码 本项目想法已经在我脑海想了很久了 都没有时间去实现它 这次刚刚考完试就用了两天把它做了出来 希望对大家有帮助 有什么需要的可以在下面留