Qt+ESP32+SQLite 智能大棚

环境简介

硬件环境

ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器

基本工作流程

  1. 上位机先运行,下位机启动后尝试连接上位机
  2. 连接成功后定时上报传感器数据到上位机,上位机将信息进行处理展示
  3. 判断下位机传感器数据,如果超过设置的阈值,则下发控制命令控制下位机硬件
  4. 点击上位机控制按钮,即可下发控制指令控制硬件

上位机运行效果

硬件连接图

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仓库地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/46444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NumPy库学习之arange函数

NumPy库学习之arange函数 一、简介 NumPy是一个开源的科学计算库&#xff0c;用于Python语言。它提供了大量的数学函数来对数组进行操作。arange函数是NumPy库中用来生成一个指定范围的值的数组。 二、语法和参数 arange函数的基本语法如下&#xff1a; numpy.arange(star…

[misc]-流量包-wireshark-icmp

wireshark打开&#xff0c;大部分都是icmp,查看data部分 提取data长度&#xff1a; tshark.exe -r 1.pcapng -T fields -e data.len > length.txt 使用python解析这个文件&#xff0c;剔除异常值&#xff0c;每8个取一个值&#xff0c;得到flag ds [] with open(length.tx…

188家国产大模型:挑战与机遇,未来杀手级AI应用究竟该长什么样子?

未来的杀手级AI应用究竟该长什么样子&#xff1f;这篇文章里&#xff0c;作者梳理了国内外LLMs基础大模型的特征&#xff0c;并于最后发表了自己关于杀手级AI应用的看法和见解&#xff0c;一起来看一下。 摘要&#xff1a; 本文详细列表展示国外18家&#xff0c;国内188家大模…

使用AIOHTTP模块:提高网络请求效率

链接&#xff1a;https://pan.quark.cn/s/c6df12a6efcc​ 本文将介绍如何利用AIOHTTP模块提高网络请求效率&#xff0c;以及如何编写一个异步下载图片的程序&#xff0c;并展示如何通过AIOHTTP和AIO files的异步功能优化Python爬虫程序的读写操作。 00:00 - AIOHTTP模块&…

Ant 风格的路径模式和 MVC 风格的路径模式 是什么

Ant 风格的路径模式和 MVC 风格的路径模式是 Spring 框架中用于匹配 URL 路径的两种模式。它们各有不同的语法和用途&#xff0c;主要用于配置 Spring Security 和 Spring MVC 中的请求映射。 Ant 风格的路径模式 Ant 风格的路径模式使用 Ant 文件路径匹配语法来匹配 URL。常…

部署运维之一:发展历史

在当今数字化转型加速的时代&#xff0c;部署运维作为技术栈中至关重要的一环&#xff0c;不仅承载着确保应用平稳运行的重任&#xff0c;还深刻影响着企业的业务连续性、用户体验以及市场竞争力。随着云计算、大数据、人工智能等技术的飞速发展&#xff0c;应用系统的复杂性日…

深度学习-5-如何选择损失函数和激活函数以及层数

参考神经网络结构选择的智慧:层数、连接与神经元数量的奥秘 参考终于知道如何选择深度学习的损失函数和激活函数了! 参考神经网络动画讲解 - 权重W、偏置b和激活函数 1 神经网络结构的选择 不同的神经网络结构,如层数、连接方式以及神经元数量等,都会对模型的学习能力、泛…

ReentrantLock的源码实现和原理介绍

目录 一、概述 二、ReentrantLock的整体结构 三、ReentrantLock 和Synchronized相比 四、ReentrantLock 公平锁和非公平锁实现 4.1 ReentrantLock 源码解读 4.1.1 ReentrantLock 类源码解读 4.1.1.1 Lock接口 4.1.1.2 Sync抽象类 4.1.1.3 NonfairSync()和FairSync() 4…

React 18 + Babel 7 + Webpack 5 开发环境搭建

文章目录 一、基础开发环境搭建1. 新建项目目录2. 项目目录结构及内容3. 安装 React 18 Babel 7 Webpack 54. 配置 Babel 和 Webpack5. 调试/构建项目 二、扩展项目支持的能力&#xff08;待补充&#xff09;1. JS 扩展&#xff08;待补充&#xff09;2. CSS 扩展&#xff08…

EasyCVR视频技术:城市电力抢险的“千里眼”,助力抢险可视化

随着城市化进程的加速和电力需求的不断增长&#xff0c;电力系统的稳定运行对于城市的正常运转至关重要。然而&#xff0c;自然灾害、设备故障等因素常常导致电力中断&#xff0c;给城市居民的生活和企业的生产带来严重影响。在这种情况下&#xff0c;快速、高效的电力抢险工作…

产品介绍|九芯语音芯片的特点与应用市场

随着物联网与智能家居的普及&#xff0c;越来越多的电子产品有了语音播报的需求。九芯语音芯片集成了语音识别和语音合成技术&#xff0c;能够准确地捕捉并解析人类的语言&#xff0c;同时以清晰、自然的语调进行回应&#xff0c;为各类智能设备注入了强大的语言交互能力。 特点…

Knife4j的原理及应用详解(四)

本系列文章简介&#xff1a; 在当今快速发展的软件开发领域&#xff0c;API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;作为不同软件应用之间通信的桥梁&#xff0c;其重要性日益凸显。随着微服务架构的兴起&#xff0c;API的数量…

2024智慧竞技游戏俱乐部线下面临倒闭?

在2024年的中国&#xff0c;智慧竞技游戏俱乐部如雨后春笋般在二三线城市中兴起&#xff0c;它们不仅是年轻人娱乐的场所&#xff0c;更是智慧与技巧的较量场。然而&#xff0c;随着疫情的冲击&#xff0c;这些俱乐部面临着前所未有的挑战。本文将通过一个小镇上的故事&#xf…

OSI 七层模型与五层模型

OSI&#xff08;开放系统互连&#xff09;七层模型和五层模型是描述计算机网络协议的两种不同层次划分方法。两者用于帮助理解和设计网络协议&#xff0c;但它们在层次划分上有所不同。

使用Elasticsearch Python SDK 查询Easysearch

随着数据分析需求的不断增长&#xff0c;能够高效地查询和分析大数据集变得越来越重要。Elasticsearch作为一种强大的分布式搜索和分析引擎&#xff0c;被广泛应用于各种场景。Easyearch 支持原生 Elasticsearch 的 DSL 查询语法&#xff0c;确保原业务代码无需调整即可无缝迁移…

优化校园设施维护,故障类型功能全解析

在智慧校园的日常运作中&#xff0c;报修管理系统的故障类型功能扮演着至关重要的角色。它不仅简化了设备维修的流程&#xff0c;还极大地提升了校园设施的维护效率。该功能的核心在于&#xff0c;它允许系统管理员创建、编辑和删除一系列故障类型&#xff0c;涵盖从网络连接问…

vue实现动态图片(gif)

目录 1. 背景 2. 分析 3. 代码实现 1. 背景 最近在项目中发现一个有意思的小需求&#xff0c;鼠标移入一个盒子里&#xff0c;然后盒子里的图就开始动起来&#xff0c;就像一个gif一样&#xff0c;然后鼠标移出&#xff0c;再按照原来的变化变回去&#xff0c;就像变形金刚…

QT--控件篇二

一、文本框 1. QLineEdit 文本框通常使用QLineEdit和QTextEdit这两个类来实现。 QLineEdit&#xff1a;用于单行文本输入。QTextEdit&#xff1a;用于多行文本输入&#xff0c;可以包含丰富的文本格式。 用setText(QString txt);设置默认的显示内容&#xff0c;用QString tex…

【NOI】C++数据结构入门之一维数组(一)数组基础

文章目录 前言一、概念1.导入2.数组2.1 数组的创建2.2 数组的使用 二、例题讲解问题&#xff1a;1423 - 考试成绩的简单统计问题&#xff1a;1153 - 查找“支撑数”问题&#xff1a;1156 - 排除异形基因问题&#xff1a;1155 - 找找谁的身高超过全家的平均身高问题&#xff1a;…

计算机网络生成树协议介绍与实践

生成树协议 1.环路 二层环路&#xff1a;数据链路层&#xff0c;交换机&#xff08;二层设备&#xff09;通过线路连接环状。即物理成环并且没有开启防环协议。 危害&#xff1a;广播风暴&#xff1a;交换机将未知帧广播&#xff0c;收到后的交换机继续广播&#xff0c;不断…