提示:站在巨人肩膀上的小白,大家可以提出自己的看法。如有侵删;
目录
随着智能化时代的到来,你是否想解放双手,实现家居智能化,这多酷啊!!懒人开关专属于你的定制。

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





先来科普一下舵机的小知识:
(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:
舵机的购买和详细知识在这里不做过过多的解释了,自行从参考链接中查询。
整体就是判断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!");
}
看一下端口

外壳的打印使用的是solidworks,其中有很多偏差就自行又添加了一些小组件,后期可能会发布一下完成版的外壳源码。
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输出的日志;

导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:
文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L