使用 ESP32-WROOM + DHT11 做个无屏温湿度计

最近梅雨天,有个房间湿度很大,而我需要远程查看温湿度,所以无所谓有没有显示屏,某宝上的温湿度计都是带屏的,如果连WIFI查看温湿度操作也比较麻烦,还需要换电池,实在不能满足我的需求,于是买了ESP32-WROOM和DHT11。

ESP32是乐鑫开发的一系列低成本、低功耗的片上系统微控制器,具有 Wi-Fi 和蓝牙无线功能以及双核处理器。手上的ESP32-WROOM-32是38针角版,板载一颗蓝色LED可由Pin1控制。

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,内部由一个 8 位单片机控制一个电阻式感湿元件和一个 NTC 测温元件。DHT11 采用单总线协议。

手上的DHT11板是把DHT11传感器封装在板上了,板载10k上拉电阻,使用时直接接单片机,引脚定义为:

1:data(S)

2:VCC

3:GND(-)

接线用杜邦线,data接G22,VCC接3V3(3.3V,接5V也可以):

最后用阳光板做了个外壳(红白线交换了)

胶带固定,留LED窗口

工作原理是定时测量温湿度后通过webhook推送到钉钉的,钉钉消息包括成功连接WIFI,成功同步网络时间,时间是GMP0时区时间,未换算为8区,我尝试输出摄氏度符号℃,但网络请求会报错,所以暂时用C代替。

程序是用python,具体说是使用MicroPyhton编写的,MicroPython是一种适用于微控制器的Python3编程语言实现。它基于Python语言,并且与标准的Python解释器具有相同的语法和语义。MicroPython可以在微型计算机上运行,比如Arduino、ESP8266和ESP32等。它可以通过串口或WiFi连接进行编程和传输,可以控制各种传感器、执行各种操作和处理各种数据。它提供了便捷的开发环境,具有高效的脚本语言和小巧的代码大小,更容易理解和编写代码。它是一个非常流行的嵌入式开发语言,可用于开发各种物联网、机器人和嵌入式系统。

使用MicroPyhton需先刷入MicroPyhton固件,可以使用Thonny就很方便地刷入,步骤:工具->设置->Install or update firmware->Port+Firmware->安装。

MicroPyhton固件下载地址(MicroPython - Python for microcontrollers)

需要把WEBHOOK_DINGDING改为自己的机器人webhook,上电后会尝试连接WIFI,成功后会收到钉钉,然后马上同步到网络时间,成功也会钉钉,然后马上测量温湿度,同时LED会闪烁,直到测量成功(如果传感器有问题会一直闪),并钉钉。

# -*- coding: UTF-8 -*-

import network
import urequests
import ntptime
import time
import dht
from machine import Pin,RTC,Timer

ssid = 'ssid'
password = '123456'
WEBHOOK_DINGDING = 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxx'
TIME_MINUTES = 15

rtc = RTC()

# 设置温湿度传感器引脚
dht_pin = Pin(22, Pin.IN, Pin.PULL_UP)  # 将传感器引脚连接到ESP32的GPIO 22引脚
# 创建DHT对象
dht_sensor = dht.DHT11(dht_pin)

# 连接WIFI
def connect_wifi(ssid,password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    print('scan wifi',wlan.scan())
    wlan.connect(ssid,password)
    while not wlan.isconnected():
        print('.',end='')
        time.sleep(0.2)
    text = 'WIFI connect OK'
    print(text)
    r = dingMe(text)
    print(r)
    
# 同步时间
def sync_time():
    print(rtc.datetime())
    print('Sync time')
    for i in range(60):   #时间校准
        try:
            print('.',end='')
            ntptime.settime()
            print('time ok')
            break;
        except:
            time.sleep(3)
    print(rtc.datetime())
    (y,m,d,H,M,S,w,dd) = time.localtime()
    text = '{}-{} {}:{} sync time OK'.format(m,d,H,M)
    print(text)
    r = dingMe(text)
    print(r)
    
def measure():
    try:
        # 读取传感器数据
        dht_sensor.measure()
        # 获取温度和湿度
        temperature = dht_sensor.temperature()
        humidity = dht_sensor.humidity()
        data=[temperature,humidity]
        return data
    except:
        return [0,0]

# 发送消息到钉钉
# https://open.dingtalk.com/document/orgapp/custom-robot-access
def dingMe(content,WEBHOOK_DINGDING=WEBHOOK_DINGDING):
    mHeader = {'Content-Type': 'application/json; charset=UTF-8'}
    mBody = {
        "text": {
            "content":'WT:'+content
        },
        "msgtype": "text"
    }
    # 注意:json=mBody  必须用json    
    r = urequests.post(url=WEBHOOK_DINGDING, json=mBody, headers=mHeader)
    return r.text

# 读取传感器数据并传到钉钉
def push_message():
    # 声明LED引脚对象
    led_pin = Pin(1, Pin.OUT)
    for i in range(60):
        data = measure()
        # 测量失败,闪烁LED
        led_pin.value(0)
        time.sleep(0.5)
        led_pin.value(1)
        time.sleep(0.5)
        if [0,0] != data:
            break
        
    (y,m,d,H,M,S,w,dd) = time.localtime()
    text = '{}-{} {}:{} {}C {}%'.format(m,d,H,M,data[0],data[1])
    print(text)
    r = dingMe(text)
    print(r)

if __name__ == '__main__':
    connect_wifi(ssid,password)
    sync_time()
    push_message()
    # 创建定时器对象
    timer = Timer(0)
    # 设置定时器触发时间为TIME_MINUTES分钟
    timer.init(period=TIME_MINUTES*60*1000, mode=Timer.PERIODIC, callback=lambda t: push_message())

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

剖析DeFi交易产品之UniswapV3:交易路由合约

本文首发于公众号:Keegan小钢 SwapRouter 合约封装了面向用户的交易接口,但不再像 UniswapV2Router 一样根据不同交易场景拆分为了那么多函数,UniswapV3 的 SwapRouter 核心就只有 4 个交易函数: exactInputSingle:指…

Vue进阶(四十五)Jest集成指南

文章目录 一、前言二、环境检测三、集成问题汇总四、拓展阅读 一、前言 在前期博文《Vue进阶(八十八)Jest》中,讲解了Jest基本用法及应用示例。一切顺利的话,按照文档集成应用即可,但是集成过程中遇到的问题可能五花八…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第55课-芝麻开门(语音 识别 控制3D纪念馆开门 和 关门)

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第55课-芝麻开门(语音识别控制3D纪念馆开门和关门) 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtn…

KVM使用命令行添加新磁盘(注:支持热插拔)

1、使用qemu-img创建格式为qcow2的磁盘 [rootkvm ~]# qemu-img create -f qcow2 /var/lib/libvirt/images/test-disk.qcow2 15G 2、显示虚拟机硬盘列表,查看未使用的target [rootkvm ~]# virsh domblklist kvm-client 3、添加硬盘到kvm-client虚拟机中 [rootkvm…

SpringBoot | 大新闻项目后端(redis优化登录)

该项目的前篇内容的使用jwt令牌实现登录认证,使用Md5加密实现注册,在上一篇:http://t.csdnimg.cn/vn3rB 该篇主要内容:redis优化登录和ThreadLocal提供线程局部变量,以及该大新闻项目的主要代码。 redis优化登录 其实…

html+css+js图片手动轮播

源代码在界面图片后面 轮播演示用的几张图片是Bing上的&#xff0c;直接用的几张图片的URL&#xff0c;谁加载可能需要等一下&#xff0c;现实中替换成自己的图片即可 关注一下点个赞吧&#x1f604; 谢谢大佬 界面图片 源代码 <!DOCTYPE html> <html lang&quo…

C++继承初识

一。继承 1.继承本质是复用相同的代码&#xff08;属性&#xff09; 2.格式&#xff1a;class 类名&#xff1a;继承方式 父类 3.继承方式的规律&#xff1a; 父类的&#xff1a; 对于私有成员&#xff0c;不管哪种继承方式都不可见--->不想被子类继承的成员 对于保护…

代码随想录——划分字母区间(Leetcode763)

题目链接 贪心 class Solution {public List<Integer> partitionLabels(String s) {int[] count new int[27];Arrays.fill(count,0);// 统计元素最后一次出现的位置for(int i 0; i < s.length(); i){count[s.charAt(i) - a] i;}List<Integer> res new Ar…

非对称加密算法原理与应用2——RSA私钥加密文件

作者:私语茶馆 1.相关章节 (1)非对称加密算法原理与应用1——秘钥的生成-CSDN博客 第一章节讲述的是创建秘钥对,并将公钥和私钥导出为文件格式存储。 本章节继续讲如何利用私钥加密内容,包括从密钥库或文件中读取私钥,并用RSA算法加密文件和String。 2.私钥加密的概述…

JDK都出到20多了,你还不会使用JDK8的Stream流写代码吗?

目录 前言 Stream流 是什么&#xff1f; 为什么要用Steam流 常见stream流使用案例 映射 map() & 集合 collect() 单字段映射 多字段映射 映射为其他的对象 映射为 Map 去重 distinct() 过滤 filter() Stream流的其他方法 使用Stream流的弊端 前言 当你某天看…

深度学习模型加密python版本

支持加密的模型: # torch、torch script、onnx、tensorrt 、torch2trt、tensorflow、tensorflow2tensorrt、paddlepaddle、paddle2tensorrt 深度学习推理模型通常以文件的形式进行保存&#xff0c;相应的推理引擎通过读取模型文件并反序列化即可进行推理过程. 这样一来&#…

跨平台Ribbon UI组件QtitanRibbon全新发布v6.7.0——支持Qt 6.6.3

没有Microsoft在其办公解决方案中提供的界面&#xff0c;就无法想象现代应用程序&#xff0c;这个概念称为Ribbon UI&#xff0c;目前它是使应用程序与时俱进的主要属性。QtitanRibbon是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件&#xff0c;QtitanRibb…

vue3【实战】来回拖拽放置图片

效果预览 技术要点 img 标签默认就是可拖拽的&#xff08;a 标签也是&#xff09;事件 e 内的 dataTransfer 对象可用于临时存储事件过程中的数据拖拽事件的默认行为是用浏览器新开页签打开被拖拽对象&#xff0c;所以通常需要禁用默认的浏览器行为被拖拽元素必须设置 id&#…

拉曼光谱入门:2.拉曼光谱发展史、拉曼效应与试样温度的确定方法

1.拉曼光谱技术发展史 这里用简单的箭头与关键字来概括一下拉曼光谱技术的发展史 1928年&#xff1a;拉曼效应的发现 → 拉曼光谱术的初步应用20世纪40年代&#xff1a;红外光谱术的发展 → 拉曼光谱术的限制20世纪60年代&#xff1a;激光作为光源的引入 → 拉曼光谱术的性能提…

阿里云人工智能平台PAI部署开源大模型chatglm3之失败记录

想学习怎么部署大模型&#xff0c;跟着网上的帖子部署了一个星期&#xff0c;然而没有成功。失败的经历也是经历&#xff0c;记在这里。 我一共创建了3个实例来部署chatglm3&#xff0c;每个实例都是基于V100创建的&#xff08;当时没有A10可选了&#xff09;&#xff0c;其显…

数据库缓存管理

1. 简介 缓存管理器是数据库管理系统&#xff08;DBMS&#xff09;中负责管理内存中page并处理文件和索引管理器的page请求的组件。由于内存空间有限&#xff0c;我们不能将所有page存储在缓存池中。因此&#xff0c;缓存管理器需要制定替换策略&#xff0c;当空间填满时选择哪…

rider使用libman

问题 rider没有libman的相关功能&#xff0c;需要使用cli 安装Libman dotnet tool install -g Microsoft.Web.LibraryManager.Cli # 如果存在可以尝试更新 dotnet tool update -g Microsoft.Web.LibraryManager.Cli查看命令 libman --help初始化 cdnjs官网 libman init安…

【十三】图解 Spring 核心数据结构:BeanDefinition 其二

图解 Spring 核心数据结构&#xff1a;BeanDefinition 其二 概述 前面写过一篇相关文章作为开篇介绍了一下BeanDefinition&#xff0c;本篇将深入细节来向读者展示BeanDefinition的设计&#xff0c;让我们一起来揭开日常开发中使用的bean的神秘面纱&#xff0c;深入细节透彻理解…

CTFShow的RE题(三)

数学不及格 strtol 函数 long strtol(char str, char **endptr, int base); 将字符串转换为长整型 就是解这个方程组了 主要就是 v4, v9的关系&#xff0c; 3v9-(v10v11v12)62d10d4673 v4 v12 v11 v10 0x13A31412F8C 得到 3*v9v419D024E75FF(1773860189695) 重点&…

刷代码随想录有感(127):动态规划——判断是否为子序列

题干&#xff1a; 代码&#xff1a; class Solution { public:bool isSubsequence(string s, string t) {vector<vector<int>>dp(s.size() 1, vector<int>(t.size() 1, 0));for(int i 1; i < s.size(); i){for(int j 1; j < t.size(); j){if(s[i …