• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

懒人开关 ESP32控制舵机旋转ESP32+SG90舵机+微信小程序

武飞扬头像
小杰爱吃西瓜
帮助2

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


前言

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


学新通

有点模糊,但是实际功能实现啦!微信小程序端来自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进行通信,当然后期你也可以自行添加蓝牙的通信方式等等;

代码如下:

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

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

  1.  
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
  2.  
    int leddev(char* topic, byte* payload, unsigned int length)
  3.  
    /*************************************************************************/
  4.  
     
  5.  
    {
  6.  
    String msg="";
  7.  
    for (int i = 0; i < length; i ) {
  8.  
    msg = (char)payload[i];
  9.  
    }
  10.  
    Serial.println(msg);
  11.  
    if (msg == "1")
  12.  
    {
  13.  
    degree = 0;
  14.  
    ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。
  15.  
     
  16.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  17.  
     
  18.  
    return (int)(((maxs - deadZone) / 180) * degree deadZone); //返回度数对应的高电平的数值
  19.  
    }
  20.  
    else
  21.  
    {
  22.  
    Serial.printf("ok");
  23.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  24.  
    ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。
  25.  
    }
  26.  
    }
学新通

来一个标志位;

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

  1.  
    int flag = 0;
  2.  
    void loop()
  3.  
    {
  4.  
     
  5.  
    if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。
  6.  
    {
  7.  
    reconnect();
  8.  
    }
  9.  
    client.loop();
  10.  
    if(flag==0){
  11.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  12.  
    flag=1;
  13.  
    Serial.println("发送ok!");
  14.  
    }

看一下端口 

学新通

3.外壳的打印

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

4.MQTT连接

1、先创建一下你的项目

学新通

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

arduino部分的全部代码附上:

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

  1.  
    #include <WiFi.h>
  2.  
    #include <PubSubClient.h>//发布订阅库,也可以使用mqtt.h
  3.  
    #include <Arduino.h>
  4.  
    //连接mqtt
  5.  
    const char* ssid = " "; //WIFI的ID
  6.  
    const char* password = " "; //WIFI的PASSWORD
  7.  
    const char* mqtt_server = " "; // mqtt服务器的地址。
  8.  
    const char* TOPIC = "set"; // 订阅信息主题
  9.  
    const char* Mqtt_pub_topic = "get"; // 订阅信息主题
  10.  
    const char* client_id = "esp32";//设备的客户端编号
  11.  
    char* sh = new char[10]; //定义两个字符串数组,用来存放温湿度的浮点数转换过来的字符串。
  12.  
    char* st = new char[10];
  13.  
    long lastMsg = 0; // 记录上一次发送信息的时间。
  14.  
     
  15.  
    int freq = 50; // 1/50秒,50Hz的频率,20ms的周期,这个变量用来存储时钟基准。
  16.  
    int channel = 8; // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。)
  17.  
    int resolution = 8; // 分辨率设置为8,就是2的8次方,用256的数值来映射角度,看下方的占空比函数。
  18.  
    const int led = 13;
  19.  
     
  20.  
    /*****将局部变量已改为全局变量(根据实际需求再自行调整)****/
  21.  
    int degree;
  22.  
    float deadZone = 0;
  23.  
    String push_msg = "OK";
  24.  
    //最好不要使用max、min...之类的词作为变量,容易被编译器识别成方法、类、函数...
  25.  
    float maxs = 32;//对应2.5ms(2.5ms/(20ms/256))
  26.  
    /*****************************/
  27.  
     
  28.  
    WiFiClient espClient; // 定义WLAN实例
  29.  
    PubSubClient client(espClient); // 定义PubSubClient的实例
  30.  
     
  31.  
    /*****将int degree改为 int c,通过赋值修改degree的值******/
  32.  
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
  33.  
    int calculatePWM(int c) //定义函数用于输出PWM的占空比
  34.  
    { //0-180度
  35.  
    degree = c;
  36.  
    /*****************************************************/
  37.  
     
  38.  
    //20ms周期内,高电平持续时长0.5-2.5ms,对应0-180度舵机角度,参考上面的180度对应图。
  39.  
    deadZone = 6.4;//对应0.5ms(0.5ms/(20ms/256))
  40.  
     
  41.  
    if (degree < 0)
  42.  
    degree = 0;
  43.  
    if (degree > 200)
  44.  
    degree = 180;
  45.  
    return (int)(((maxs - deadZone) / 180) * degree deadZone); //返回度数对应的高电平的数值
  46.  
    }
  47.  
     
  48.  
    void setup()
  49.  
    {
  50.  
    Serial.begin(9600);
  51.  
    ledcSetup(channel, freq, resolution); // 用于设置 LEDC 通道的频率和分辨率。
  52.  
    ledcAttachPin(led, channel); // 将通道与对应的引脚连接
  53.  
    //
  54.  
    WiFi.begin(ssid, password);
  55.  
    while (WiFi.status() != WL_CONNECTED)
  56.  
    {
  57.  
    delay(500);
  58.  
    }
  59.  
    client.setServer(mqtt_server, 1883);//设定MQTT服务器与使用的端口
  60.  
    client.setCallback(leddev); //设定回调程序,当ESP32收到订阅消息时会调用此方法
  61.  
     
  62.  
    delay(5000);
  63.  
     
  64.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  65.  
    Serial.println(push_msg);
  66.  
    }
  67.  
     
  68.  
    /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/
  69.  
    int leddev(char* topic, byte* payload, unsigned int length)
  70.  
    /*************************************************************************/
  71.  
     
  72.  
    {
  73.  
    String msg="";
  74.  
    for (int i = 0; i < length; i ) {
  75.  
    msg = (char)payload[i];
  76.  
    }
  77.  
    Serial.println(msg);
  78.  
    if (msg == "1")
  79.  
    {
  80.  
    degree = 0;
  81.  
    ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。
  82.  
     
  83.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  84.  
     
  85.  
    return (int)(((maxs - deadZone) / 180) * degree deadZone); //返回度数对应的高电平的数值
  86.  
    }
  87.  
    else
  88.  
    {
  89.  
    Serial.printf("ok");
  90.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  91.  
    ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。
  92.  
    }
  93.  
    }
  94.  
     
  95.  
    void reconnect() {
  96.  
    while (!client.connected()) {
  97.  
    if (client.connect(client_id))
  98.  
    {
  99.  
    client.subscribe(TOPIC);
  100.  
    }
  101.  
    else
  102.  
    {
  103.  
    delay(5000);
  104.  
    }
  105.  
    }
  106.  
    }
  107.  
    int flag = 0;
  108.  
    void loop()
  109.  
    {
  110.  
     
  111.  
    if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。
  112.  
    {
  113.  
    reconnect();
  114.  
    }
  115.  
    client.loop();
  116.  
    if(flag==0){
  117.  
    client.publish(Mqtt_pub_topic,push_msg.c_str());
  118.  
    flag=1;
  119.  
    Serial.println("发送ok!");
  120.  
    }
  121.  
    // for (int d = 0; d <= 180; d = 10)
  122.  
    // {
  123.  
    // ledcWrite(channel, calculatePWM(d)); // 输出PWM,设置 LEDC 通道的占空比。
  124.  
    // Serial.printf("value=%d,calcu=%d\n", d, calculatePWM(d));
  125.  
    // delay(1000);
  126.  
    // }
  127.  
    }
学新通

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

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

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

学新通

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

 学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgabefi
系列文章
更多 icon
同类精品
更多 icon
继续加载