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

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


前言

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


有点模糊,但是实际功能实现啦!微信小程序端来自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输出的日志;

 ​​​​​

猜你喜欢

转载自blog.csdn.net/weixin_47024334/article/details/127216666
今日推荐