Qt+ESP32+SQLite 智能大棚
环境简介
硬件环境
ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器
基本工作流程
- 上位机先运行,下位机启动后尝试连接上位机
- 连接成功后定时上报传感器数据到上位机,上位机将信息进行处理展示
- 判断下位机传感器数据,如果超过设置的阈值,则下发控制命令控制下位机硬件
- 点击上位机控制按钮,即可下发控制指令控制硬件
上位机运行效果

硬件连接图


DHT11 温湿度传感器
接线图
VCC 3V3
GND GND
DATA GPIO21(D21)

读取代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"#define DHT11_PIN (21) //可通过宏定义,修改引脚#define DHT11_CLR gpio_set_level(DHT11_PIN, 0)
#define DHT11_SET gpio_set_level(DHT11_PIN, 1)
#define DHT11_IN gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT)
#define DHT11_OUT gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT)uint8_t DHT11Data[4]={0};
uint8_t Temp, Humi;//us延时函数,误差不能太大
void DelayUs( uint32_t nCount)
{ets_delay_us(nCount);
} void DHT11_Start(void)
{ DHT11_OUT; //设置端口方向DHT11_CLR; //拉低端口 DelayUs(19*1000);
// vTaskDelay(19 * portTICK_RATE_MS); //持续最低18ms;DHT11_SET; //释放总线DelayUs(30); //总线由上拉电阻拉高,主机延时30uS;DHT11_IN; //设置端口方向while(!gpio_get_level(DHT11_PIN)); //DHT11等待80us低电平响应信号结束while(gpio_get_level(DHT11_PIN));//DHT11 将总线拉高80us
}uint8_t DHT11_ReadValue(void)
{ uint8_t i,sbuf=0;for(i=8;i>0;i--){sbuf<<=1; while(!gpio_get_level(DHT11_PIN));DelayUs(30); // 延时 30us 后检测数据线是否还是高电平 if(gpio_get_level(DHT11_PIN)){sbuf|=1; }else{sbuf|=0;}while(gpio_get_level(DHT11_PIN));}return sbuf;
}uint8_t DHT11_ReadTemHum(uint8_t *buf)
{uint8_t check;buf[0]=DHT11_ReadValue();buf[1]=DHT11_ReadValue();buf[2]=DHT11_ReadValue();buf[3]=DHT11_ReadValue();check =DHT11_ReadValue();if(check == buf[0]+buf[1]+buf[2]+buf[3])return 1;elsereturn 0;
} void app_main(void)
{printf("ESP32 DHT11 TEST:%s,%s!\r\n",__DATE__,__TIME__);gpio_pad_select_gpio(DHT11_PIN);while(1) {DHT11_Start();if(DHT11_ReadTemHum(DHT11Data)){Temp=DHT11Data[2];Humi=DHT11Data[0]; printf("Temp=%d, Humi=%d\r\n",Temp,Humi);}else{printf("DHT11 Error!\r\n");}vTaskDelay(1000); //目前10s读取一次}
}
TEMT6000
接线图
VCC VCC
GND GND
OUT GPIO34(D34)

读取代码
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"// ADC所接的通道 GPIO34 if ADC1 = ADC1_CHANNEL_6
#define ADC1_TEST_CHANNEL ADC1_CHANNEL_6
// ADC斜率曲线
static esp_adc_cal_characteristics_t *adc_chars;
// 参考电压
#define DEFAULT_VREF 3300 //使用adc2_vref_to_gpio()获得更好的估计值void check_efuse(void)
{//检查TP是否烧入eFuseif (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {printf("eFuse Two Point: Supported\n");} else {printf("eFuse Two Point: NOT supported\n");}//检查Vref是否烧入eFuseif (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {printf("eFuse Vref: Supported\n");} else {printf("eFuse Vref: NOT supported\n");}
}
void adc_init(void)
{adc1_config_width(ADC_WIDTH_BIT_12);// 12位分辨率adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_DB_11);// 电压输入衰减adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); // 为斜率曲线分配内存esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);// print_char_val_type(val_type);
}
void app_main(void)
{uint32_t read_raw;check_efuse();adc_init();while(1){read_raw = adc1_get_raw(ADC1_TEST_CHANNEL);// 采集ADC原始值//这里可以多次采样取平均值uint32_t voltage = esp_adc_cal_raw_to_voltage(read_raw, adc_chars);//通过一条斜率曲线把读取adc1_get_raw()的原始数值转变成了mVprintf("ADC原始值: %d 转换电压值: %dmV\n", read_raw, voltage);vTaskDelay(1000 / portTICK_RATE_MS);}
}
延时1s
- 1200 手电筒1档
- 2688 手电筒2档
- 4079 手电筒3档

烟雾传感器
接线图
| 3V3 | VCC |
| GND | GND |
| DO | GPIO15 |
| AO | GPIO2 |
读取代码
/* ADC1 ExampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"#define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES 64 //Multisamplingstatic esp_adc_cal_characteristics_t *adc_chars;
#if CONFIG_IDF_TARGET_ESP32
static const adc_channel_t channel = ADC_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
#elif CONFIG_IDF_TARGET_ESP32S2
static const adc_channel_t channel = ADC_CHANNEL_6; // GPIO7 if ADC1, GPIO17 if ADC2
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
#endif
static const adc_atten_t atten = ADC_ATTEN_DB_0;
static const adc_unit_t unit = ADC_UNIT_1;static void check_efuse(void)
{
#if CONFIG_IDF_TARGET_ESP32//Check if TP is burned into eFuseif (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {printf("eFuse Two Point: Supported\n");} else {printf("eFuse Two Point: NOT supported\n");}//Check Vref is burned into eFuseif (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {printf("eFuse Vref: Supported\n");} else {printf("eFuse Vref: NOT supported\n");}
#elif CONFIG_IDF_TARGET_ESP32S2if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {printf("eFuse Two Point: Supported\n");} else {printf("Cannot retrieve eFuse Two Point calibration values. Default calibration values will be used.\n");}
#else
#error "This example is configured for ESP32/ESP32S2."
#endif
}static void print_char_val_type(esp_adc_cal_value_t val_type)
{if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {printf("Characterized using Two Point Value\n");} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {printf("Characterized using eFuse Vref\n");} else {printf("Characterized using Default Vref\n");}
}void app_main(void)
{//Check if Two Point or Vref are burned into eFusecheck_efuse();//Configure ADCif (unit == ADC_UNIT_1) {adc1_config_width(width);adc1_config_channel_atten(channel, atten);} else {adc2_config_channel_atten((adc2_channel_t)channel, atten);}//Characterize ADCadc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);print_char_val_type(val_type);//Continuously sample ADC1while (1) {uint32_t adc_reading = 0;//Multisamplingfor (int i = 0; i < NO_OF_SAMPLES; i++) {if (unit == ADC_UNIT_1) {adc_reading += adc1_get_raw((adc1_channel_t)channel);} else {int raw;adc2_get_raw((adc2_channel_t)channel, width, &raw);adc_reading += raw;}}adc_reading /= NO_OF_SAMPLES;//Convert adc_reading to voltage in mVuint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);vTaskDelay(pdMS_TO_TICKS(1000));}
}
蜂鸣器
接线图
VCC VCC
GND GND
I/O D2(GPIO2)
设置代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "driver/gpio.h"#define LED_PIN 2void app_main(void)
{gpio_reset_pin(LED_PIN); //引脚复位gpio_pad_select_gpio(LED_PIN); //GPIO引脚功能选择gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); //设置方向为输出while (1){gpio_set_level(LED_PIN,1); //设置LED_PIN为高电平sleep(1);gpio_set_level(LED_PIN,0); //设置LED_PIN为低电平sleep(1);}
}
继电器
DC+(VCC) 接 1口
DC- (GND)接 6 口
IN1 接 7 口
系统整体代码
Github仓库地址
相关文章:
Qt+ESP32+SQLite 智能大棚
环境简介 硬件环境 ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器 基本工作流程 上位机先运行,下位机启动后尝试连接上位机连接成功后定时上报传感器数据到上位机,上位机将信息进行处理展示判断下位机传感器数据,如果超过设置的阈值&a…...
Android Viewpager2 remove fragmen不生效解决方案
一、介绍 在如今的开发过程只,内容变化已多单一的fragment,变成连续的,特别是以短视频或者直播为主的场景很多。从早起的Viewpage只能横向滑动,到如今的viewpage2可以支持横向或者竖向滑动。由于viewpage2的adapter在设计时支持缓…...
桃园南路上的红绿灯c++
题目描述 XXX非常讨厌等红绿灯,于是他仔细观察了桃园南路与科技路交叉口的一个红绿灯的周期。 从七点半开始,这个红绿灯的每个周期会按照下面四个阶段变化: 先保持 x 分钟的红灯然后保持 y 分钟的黄灯然后保持 z 分钟的绿灯最后保持 y 分钟…...
有关去中心化算路大模型的一些误区:低带宽互连导致训练速度太慢;小容量设备无法生成基础规模的模型;去中心化总是会花费更多;虫群永远不够大
目录 有关去中心化算路大模型的一些误区 低带宽互连导致训练速度太慢 挑战与解决方案 展望 小容量设备无法生成基础规模的模型 1. 模型规模与设备内存 2. 解决方案 3. 效率挑战 FSDP(Fully Sharded Data Parallel) Zero-3 去中心化总是会花费更多 虫群永远不够大…...
uni-app iOS上架相关App store App store connect 云打包有次数限制
app store上架成功,亲测在苹果开发者通过审核后在数小时内app store是不会更新的,昨天4点多通过审核,在下班六点半时app store仍未更新,早上来看更新了。 相册权限 uni-app云打包免费有次数 切换一个账号继续...
python单测框架之pytest常见用法
单测框架的作用 测试发现:从多个文件中寻找测试用例。测试执行:按照一定顺序去执行并且生成结果。测试断言:判断最终结果与实际结果的差异。测试报告:统计测试进度、耗时、通过率,生成测试报告。 pytest简介 pytest是…...
[终端安全]-8 隐私保护和隐私计算技术
1 隐私保护相关法规和标准 1)国内法规和标准 1.1)中华人民共和国网络安全法(2017年) - 规定了个人信息的保护和数据安全的基本原则。 - 要求网络运营者采取措施防止数据泄露、篡改和丢失。 1.2)信息安全技术&#x…...
MySQL 日志深度解析:从查询执行到性能优化
引言 MySQL 日志是数据库管理员和开发者的宝贵资源,它提供了查询执行的详细情况,帮助我们诊断问题和优化性能。本文将深入分析一个具体的 MySQL 日志条目,解释其含义,并提供针对性的优化建议。 日志信息概览 让我们先来快速了解…...
sql server 练习题5
课后作业 在homework库下执行 作业1: 案例:根据用户分数划分等级。小于60分为不及格,[60,80)为及格,[80,90)为良好,大于等于90分以上为优秀。 建表语句: CREATE TABLE Grades ( ID INT PRIMARY KEY, Name V…...
ai伪原创生成器app,一键伪原创文章效率高
如今,在自媒体创作的领域,ai伪原创生成器app的出现,给写作带来了一种全新的方式和效率。ai伪原创生成器app通过使用先进的自然语言处理技术和深度学习算法,能够将原始文章进行重组和改写,生成新的文章,从而…...
【ZhangQian AI模型部署】目标检测、SAM、3D目标检测、旋转目标检测、人脸检测、检测分割、关键点、分割、深度估计、车牌识别、车道线识别
在模型部署落地(主要部署到rk3588)折腾了这么多年,把这些年折腾过的模型整理了一下,所有的流程说明、代码模型都完全开放的,欢迎交流学习。有的是为了项目、有的是为了学习、还有的是为了找点事做、有的完全是为了安抚…...
DROO论文笔记
推荐文章DROO源码及论文学习 读论文《Deep Reinforcement Learning for Online Computation Offloading in Wireless Powered Mobile-Edge Computing Networks》的笔记 论文地址:用于无线移动边缘计算网络在线计算卸载的深度强化学习 论文代码地址:DR…...
修BUG:程序包javax.servlet.http不存在
貌似昨晚上并没有成功在tomcat上面运行,而是直接运行了网页。 不知道为啥又报错这个。。。 解决方案: https://developer.baidu.com/article/details/2768022 就整了这一步就行了 而且我本地就有这个tomcat就是加进去了。 所以说啊,是不是&a…...
python常用库
目录 from sklearn import metrics:评估 编辑 svm: 编辑 逻辑回归预测 编辑 朴素贝叶斯分类 编辑 主成分分析 编辑 其实就是求b.T的协方差阵 编辑 【因子分析,因子旋转有点复杂,略】 【层次聚类,原理…...
【UE5.3】笔记11
一、变量的SET&&GET 1、创建变量保存数据,如下图,找到左侧我的蓝图下的变量,新增一个,并选择类型。使用的时候直接将变量拖到蓝图中,此时会显示两个选项一个是获取一个是设置。 选择获取就是个GET蓝图&#x…...
加密与安全 密钥体系的三个核心目标之完整性解决方案
在密钥体系中,确保数据完整性是重要目标之一。以下为您详细讲解相关的完整性解决方案: 消息认证码(MAC): 消息认证码是基于共享密钥和特定算法生成的固定长度代码。在发送方,将消息和共享密钥作为输入&…...
FastAPI 学习之路(四十一)定制返回Response
接口中返回xml格式内容 from fastapi import FastAPI, Responseapp FastAPI()# ① xml app.get("/legacy") def get_legacy_data():data """<?xml version"1.0"?><shampoo><Header>Apply shampoo here.</Header&…...
C++ //练习 15.9 在什么情况下表达式的静态类型可能与动态类型不同?请给出三个静态类型与动态类型不同的例子。
C Primer(第5版) 练习 15.9 练习 15.9 在什么情况下表达式的静态类型可能与动态类型不同?请给出三个静态类型与动态类型不同的例子。 环境:Linux Ubuntu(云服务器) 工具:vim 解释 当print_t…...
斐波那契查找算法
斐波那契查找原理,仅仅改变了中间结点(mid)的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即midlowF(k-1)-1(F代表斐波那契数列) F[k]F[k-1]F[k-2],>(F[k]-1) (F[k-1]-1)(F[k-2]-1)1 说明:只要顺序表的长度为F[k]-1,则可以将该…...
CAN总线学习
can主要用于汽车、航空等控制行业,是一种串行异步通信方式,因为其相较于其他通信方式抗干扰能力更强,更加稳定。原因在于CAN不像其他通信方式那样,以高电平代表1,以低电平代表0,而是通过电压差来表示逻辑10…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
