ESP32控制SG90舵机:从懒人开关到微信小程序

提示:站在巨人肩膀上的小白,大家可以提出自己的看法。如有侵删;

原文参考链接:esp32单片机控制舵机 – 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/566948087

文章目录

目录

前言

一、准备步骤

二、使用步骤

1.ESP32和SG90舵机的连接

2.读入数据

3.外壳的打印

4.MQTT连接

若是纯小白,可以看一下这个

导入库和站看日志的方法,若找不到可以从官网上进行下载之后进行导入


前言

        随着智能化时代的到来,你是否想解放双手,实现家居智能化,这多酷啊!!懒人开关专属于你的定制。


有点模糊,但是实际功能实现啦!微信小程序端来自B站小林技术员的个人空间_哔哩哔哩_bilibili

大家可以私信一下;

 

一、准备步骤

  • 先准备一个SG90舵机;
  • 再来一个ESP32单片机;
  • 最后就是很多根杜邦线 ;
  • 安卓线来一条进行烧录的时候使用;
  • 二、使用步骤

    1.ESP32和SG90舵机的连接:

    1. 先来科普一下舵机的小知识:

            (1)舵机分三条线,分别是棕色:GND;红色:VCC (这里我们采用的是5V电压,力气更大一点个人理解哈);橘色线:脉冲输入(也就是信号线);

            (2)开始接线啦:棕色==GND 红色==自带的5V 橘色==GPIO13

     先上一个ESP32的引脚图,详细内容在图中都有标注,自行查看即可(图是从网上找到的,很详细!如有侵删)

            舵机转动角度与占空比的关系: 占 空 比 = ( 角 度 90 + 0.5 ) ∗ 1023 / 20 占空比=(\frac {角度}{90}+0.5)*1023/20占空比=( 90角度 +0.5)∗1023/20:

    舵机的购买和详细知识在这里不做过过多的解释了,自行从参考链接中查询。

    2.读入数据

    整体就是判断1,0开关,接收到后返回OK;本文采用的是MQTT进行通信,当然后期你也可以自行添加蓝牙的通信方式等等;

    代码如下:

    int freq = 50;      // 1/50秒,50Hz的频率,20ms的周期,这个变量用来存储时钟基准。
    int channel = 8;    // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。)
    int resolution = 8; // 分辨率设置为8,就是2的8次方,用256的数值来映射角度,看下方的占空比函数。
    const int led = 13;
    
    /*****将局部变量已改为全局变量(根据实际需求再自行调整)****/
    int degree;
    float deadZone = 0;
    String push_msg = "OK";
    //最好不要使用max、min...之类的词作为变量,容易被编译器识别成方法、类、函数...
    float maxs = 32;//对应2.5ms(2.5ms/(20ms/256))
    /*****************************/
    
    WiFiClient espClient;  // 定义WLAN实例
    PubSubClient client(espClient);  // 定义PubSubClient的实例
     
    /*****将int degree改为 int c,通过赋值修改degree的值******/
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
    int calculatePWM(int c) //定义函数用于输出PWM的占空比
    { //0-180度
      degree = c;
    /*****************************************************/
    
     //20ms周期内,高电平持续时长0.5-2.5ms,对应0-180度舵机角度,参考上面的180度对应图。
       deadZone = 6.4;//对应0.5ms(0.5ms/(20ms/256))
      
      if (degree < 0)
        degree = 0;
      if (degree > 200)
        degree = 180;
      return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值
    }

    定义两个主题用于发送和接受;

    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
    int leddev(char* topic, byte* payload, unsigned int length)
    /*************************************************************************/
    
    {
      String msg="";
      for (int i = 0; i < length; i++) {
        msg+= (char)payload[i];
      }
      Serial.println(msg);
      if (msg == "1")
      {
        degree = 0;
        ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。
        
        client.publish(Mqtt_pub_topic,push_msg.c_str());
        
        return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值
      }
      else
      {
        Serial.printf("ok");
         client.publish(Mqtt_pub_topic,push_msg.c_str());
         ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。
      }
    }

    来一个标志位;

    标志位:拿着钥匙进来返回OK 

    int flag = 0;
    void loop()
    {
      
      if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。
      {
        reconnect();
      }
      client.loop();
      if(flag==0){
        client.publish(Mqtt_pub_topic,push_msg.c_str());
        flag=1;
        Serial.println("发送ok!");
       }

    看一下端口 

    3.外壳的打印

    外壳的打印使用的是solidworks,其中有很多偏差就自行又添加了一些小组件,后期可能会发布一下完成版的外壳源码。

    4.MQTT连接

    1、先创建一下你的项目

    2、设置两个主题来进行接受和发送,便于自行检查;

    arduino部分的全部代码附上:

    代码汇中的注释部分已经过分详细了,请自行查看即可;

    #include <WiFi.h>
    #include <PubSubClient.h>//发布订阅库,也可以使用mqtt.h
    #include <Arduino.h>
    //连接mqtt
    const char* ssid = "  "; //WIFI的ID
    const char* password = "  "; //WIFI的PASSWORD
    const char* mqtt_server = "  "; // mqtt服务器的地址。
    const char* TOPIC = "set"; // 订阅信息主题
    const char* Mqtt_pub_topic = "get"; // 订阅信息主题
    const char* client_id = "esp32";//设备的客户端编号
    char* sh = new char[10]; //定义两个字符串数组,用来存放温湿度的浮点数转换过来的字符串。
    char* st = new char[10];
    long lastMsg = 0;     // 记录上一次发送信息的时间。
    
    int freq = 50;      // 1/50秒,50Hz的频率,20ms的周期,这个变量用来存储时钟基准。
    int channel = 8;    // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。)
    int resolution = 8; // 分辨率设置为8,就是2的8次方,用256的数值来映射角度,看下方的占空比函数。
    const int led = 13;
    
    /*****将局部变量已改为全局变量(根据实际需求再自行调整)****/
    int degree;
    float deadZone = 0;
    String push_msg = "OK";
    //最好不要使用max、min...之类的词作为变量,容易被编译器识别成方法、类、函数...
    float maxs = 32;//对应2.5ms(2.5ms/(20ms/256))
    /*****************************/
    
    WiFiClient espClient;  // 定义WLAN实例
    PubSubClient client(espClient);  // 定义PubSubClient的实例
     
    /*****将int degree改为 int c,通过赋值修改degree的值******/
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
    int calculatePWM(int c) //定义函数用于输出PWM的占空比
    { //0-180度
      degree = c;
    /*****************************************************/
    
     //20ms周期内,高电平持续时长0.5-2.5ms,对应0-180度舵机角度,参考上面的180度对应图。
       deadZone = 6.4;//对应0.5ms(0.5ms/(20ms/256))
      
      if (degree < 0)
        degree = 0;
      if (degree > 200)
        degree = 180;
      return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值
    }
    
    void setup()
    {
      Serial.begin(9600);
      ledcSetup(channel, freq, resolution); // 用于设置 LEDC 通道的频率和分辨率。
      ledcAttachPin(led, channel);          // 将通道与对应的引脚连接
      //
      WiFi.begin(ssid, password);
       while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
      }
      client.setServer(mqtt_server, 1883);//设定MQTT服务器与使用的端口
      client.setCallback(leddev); //设定回调程序,当ESP32收到订阅消息时会调用此方法
      
      delay(5000);
      
      client.publish(Mqtt_pub_topic,push_msg.c_str());
      Serial.println(push_msg);
    }
    
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
    int leddev(char* topic, byte* payload, unsigned int length)
    /*************************************************************************/
    
    {
      String msg="";
      for (int i = 0; i < length; i++) {
        msg+= (char)payload[i];
      }
      Serial.println(msg);
      if (msg == "1")
      {
        degree = 0;
        ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。
        
        client.publish(Mqtt_pub_topic,push_msg.c_str());
        
        return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值
      }
      else
      {
        Serial.printf("ok");
         client.publish(Mqtt_pub_topic,push_msg.c_str());
         ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。
      }
    }
    
    void reconnect() {
      while (!client.connected()) {
        if (client.connect(client_id))
        {
          client.subscribe(TOPIC);
        }
        else
        {
          delay(5000);
        }
      }
    }
    int flag = 0;
    void loop()
    {
      
      if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。
      {
        reconnect();
      }
      client.loop();
      if(flag==0){
        client.publish(Mqtt_pub_topic,push_msg.c_str());
        flag=1;
        Serial.println("发送ok!");
       }
    //  for (int d = 0; d <= 180; d += 10)
    //  {
    //    ledcWrite(channel, calculatePWM(d)); // 输出PWM,设置 LEDC 通道的占空比。
    //    Serial.printf("value=%d,calcu=%d\n", d, calculatePWM(d));
    //    delay(1000);
    //  }  
    }

       以上就是今天要讲的内容,本文仅仅简单介绍了MQTT通讯连接的使用和舵机旋转控制方式;


    若是纯小白,可以看一下这个哈

    导入库和站看日志的方法,若找不到可以从官网上进行下载之后进行导入;

    (1)导入ESP32的库这里是获取芯片的ID为例子:

     (2)打开串口监视器就可以看到,ESP32输出的日志;

     ​​​​​

    物联沃分享整理
    物联沃-IOTWORD物联网 » ESP32控制SG90舵机:从懒人开关到微信小程序

    发表评论