首页
归档
分类
标签
更多
留言板
说说
关于
Search
1
饥荒联机版控制台代码大全
1,024 阅读
2
编译安装带 Brotli 压缩的 Nginx
930 阅读
3
Obsidian多端快速同步插件
901 阅读
4
树莓派+EC20模块实现连接蜂窝网和短信收发
887 阅读
5
EC20通过gammu接收短信再转发优化
865 阅读
软件
CSS
Python
MySql
Java
typecho自定义
Vue
学习笔记
Linux
Shell脚本
Nginx
树莓派
邮件
拍照
热点
ec20
云盘
系统烧录
好玩
饥荒
硬件
工具
笔记
随心记
登录
Search
标签搜索
树莓派
Linux
Java
CSS
饥荒
小妙招
个人热点
nextcloud
云盘
DHT11
学习笔记
树莓派拍照
Nginx
MySql
ESP
娱乐
ec20模块
文件共享
git
图床
Mango
累计撰写
51
篇文章
累计收到
7
条评论
首页
栏目
软件
CSS
Python
MySql
Java
typecho自定义
Vue
学习笔记
Linux
Shell脚本
Nginx
树莓派
邮件
拍照
热点
ec20
云盘
系统烧录
好玩
饥荒
硬件
工具
笔记
随心记
页面
归档
分类
标签
留言板
说说
关于
搜索到
4
篇与
的结果
2024-04-08
树莓派+EC20模块实现连接蜂窝网和短信收发
软硬件树莓派ec20wvdialgammuSIM卡EC20模块概述EC20-CE是移远通信最近推出的LTE Cat 4无线通信模块,采用LTE 3GPP Release 11 技术,支持最大下行速率 150 Mbps和最大上行速率50 Mbps;同时在封装上兼容移远通信多网络制式LTE EC21系列、EC25系列和EG25-G 模块,实现了3G网络与4G网络之间的无缝切换。EC20-CE采用镭雕工艺,镭雕工艺具有外观更漂亮、金属质感强、散热更好、信息不容易被抹除、更能适应自动化需求等优点。EC20-CE内置多星座高精度定位GNSS(GPS/GLONASS/BDS/Galileo/QZSS)接收机;在简化产品设计的同时,还大大提升了定位速度及精度。EC20-CE内置丰富的网络协议,集成多个工业标准接口,并支持多种驱动和软件功能(适用于Windows 7/8/8.1/10/11、Linux、Android等操作系统下的USB驱动等),极大地拓展了EC20-CE在M2M领域的应用范围,如CPE、路由器、数据卡、平板电脑、车载、智能安全以及工业级PDA等。产品特性更多详情可到官网查看{%link LTE EC20-CE,QUECTEL,https://www.quectel.com.cn/product/lte-ec20-ce %}产品手册 Quectel_Product_Brochure_CN_V7.8)查看设备是否挂载成功使用命令sudo ls /dev |grep ttyUSB挂载成功会有如图输出要是没有看到设备则检查设备是否稳定插入、更换USB口或者重启设备之后再重新使用命令查看拨号上网wvdial安装wvdial是一个方便使用的PPP拨号模块,它能调用调制调节器,并通过PPP上网,无需像手动拨号一样配置繁琐的文件sudo apt update sudo apt install wvdial配置修改配置文件sudo vim /etc/wvdial.conf可以继续使用 [Dialer Defaults]也可以重新根据自己需要添加,我这里为了没有多余手机卡,也为了方便输入命令,就直接使用电信/移动SIM卡使用以下配置[Dialer Defaults] Init1 = ATZ Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 Modem Type = Analog Modem Modem = /dev/ttyUSB3 Baud = 115200 New PPPD = yes ISDN = 0 Phone = *99# Username = card Password = card联通卡使用以下配置[Dialer Defaults] Init1 = ATZ Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 Init3 = at+cgdcont=1,"ip","uninet" Modem Type = Analog Modem Modem = /dev/ttyUSB3 Baud = 115200 New PPPD = yes ISDN = 0 Phone = *99# Password = card Username = card配置来源于 Quectel EC20 在 Linux 上的使用在配置文件中大部分都不需要自己调整,只有Modem和Baud需要根据自己设备情况进行调整Modem:根据情况选择合适的设备我的这个ttyUSB2和ttyUSB3都能正常使用Baud:根据情况选择合适的波特率,对于ec20来说9600-115200都可以启动wvdialsudo wvdial查看网络设备ifconfig可以看到多了ppp0和wwan0两个设备正常情况还无法访问网络,因为默认路由在其他网络设备中,需要重新配置路由配置路由查看路由sudo route配置路由的方式有很多种,我这里的方法比较简单粗暴,需要具体配置的可自己查找方法sudo route add default dev ppp0该命令会在路由表中添加一条新的默认路由在每次重启后都会刷新路由,可以将命令加到/etc/rc.local中,每次开机都执行添加方法sudo vim /etc/rc.local在exit 0前添加su - root -c `route add default dev ppp0`通过systemctl来管理wvdial开机自启wvdial的方法有很多种,并不一定要使用systemctl最简单的就是和添加路由一样,在/etc/rc.local中添加启动命令sudo vim /etc/rc.local # 添加 wvdial &编写控制wvdial启动和检测wvdial运行脚本新建sh脚本文件,可以放到你想存放的地方我这里在root用户下/root/shell中sudo mkdir /root/shell && cd shell # 名字可以任起 sudo vim onwvdial.shwvdial控制脚本内容#!/bin/bash DEVICE_NAME="/dev/ttyUSB3" # 和wvdial配置设备一致 LOG_FILE="/var/log/wvdial_on.log" # 日志文件存储位置 PROCESS_NAME=(wvdial pppd) # 需检查占用软件 # 定义函数检查进程是否占用设备 check_device_usage() { local process_name=$1 local device=$2 local pids=$(pgrep -f "$process_name") if [ -z "$pids" ]; then return fi for pid in $pids; do echo "pid:$pid" local device_count=$(lsof -p "$pid" 2>/dev/null | grep -e "$device" | wc -l) if [ "$device_count" -gt 0 ]; then echo "占用设备:$device" kill $pid fi done return } function check_wvdial() { if pgrep -x "wvdial" >/dev/null; then return 0 # wvdial 进程在运行 else return 1 # wvdial 进程未运行 fi } for process in $PROCESS_NAME; do echo "进程名: $process" check_device_usage $process $DEVICE_NAME done wvdial >> "$LOG_FILE" 2>&1 & route add default dev ppp0 while true;do if ! check_wvdial;then echo "$(date +"%Y-%m-%d %H:%M:%S") - wvdial 进程未运行,正在重新启动..." >> "$LOG_FILE" wvdial >> "$LOG_FILE" 2>&1 & fi sleep 120 done该脚本包含功能:停止wvdial启动前所需设备的占用启动wvdial添加ppp0默认路由每120秒检测wvdial是否运行记录启动、错误日志设置可执行权限sudo chmod u+x /root/shell/onwvdial.sh编写systemctl控制文件sudo vim /etc/systemd/system/wvdial_on.service配置文件内容如下:[Unit] Description=Safe Start Wvadil After=dev-ttyUSB3.device Requires=dev-ttyUSB3.device [Service] User=root Group=root ExecStart=/root/shell/onwvdial.sh # 路径根据自己配置修改 [Install] WantedBy=multi-user.target 启动服务systemctl daemon-reload systemctl start wvdial_on.service systemctl enable wvdial_on.service设置自启动后就不需要在/etc/rc.local中添加修改路由和启动wvdial命令了配置防火墙如果在ec20模块连接4G网络后还需要使用wifi则需要配置防火墙,不需要则不用配置sudo iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE sudo iptables -A FORWARD -i ppp0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i wlan0 -o ppp0 -j ACCEPT 将防火墙规则写入文件 sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"顺序执行命令即可收发短信安装软件gammusudo apt install gammu gammu-smsd配置gammu使用命令sudo gammu-config配置可参考我的或者直接修改/root/.gammurc,效果是一样的如果没有/root/.gammurc文件就使用命令[gammu] port = /dev/ttyUSB2 model = connection = at19200 synchronizetime = yes logfile = logformat = nothing use_locking = no gammuloc =修改 /etc/gammu-smsdrc[gammu] # Please configure this! port = /dev/ttyUSB2 connection = at19200 # Debugging #logformat = textall # SMSD configuration, see gammu-smsdrc(5) [smsd] service = files logfile = syslog RunOnReceive = /root/msmtp/sh/send-smsd.sh # 发送邮件脚本 # Increase for debugging information debug = yes #debuglevel = 0 # Paths where messages are stored inboxpath = /var/spool/gammu/inbox/ outboxpath = /var/spool/gammu/outbox/ sentsmspath = /var/spool/gammu/sent/ errorsmspath = /var/spool/gammu/error/编辑收到短信后自动发送邮件脚本树莓派配置邮件这里不再赘述,可以自行搜索,或者参考我之前的一篇博客{% link 树莓派开机自动发送邮件,TeohZY,https://blog.teohzy.com/posts/smpxjfsyj/ %}编辑脚本vim /root/msmtp/sh/send-smsd.sh文件路径根据自己需要修改#!/bin/bash for i in `seq $SMS_MESSAGES` ; do if [ $i -eq 1 ]; then phone="$SMS_1_NUMBER" fi tmp="$(eval echo '$'SMS_${i}_TEXT)" message="$text$tmp" done echo "$message" |mutt -s "树莓派短信转发" xxx@163.com重启gammusystemctl restart gammu-smsd.service短信测试向目标号码发送短信后邮箱能收到短信通过终端向其他号码发送短信gammu-smsd-inject TEXT 目标号码 -text '短信内容' -unicode如果收到短信说明配置成功短信发送失败踩坑查看端口占用sudo lsof /dev/ttyUSB2如果有其他进程和gammu-sms占用设备,可以使用kill命令结束非必须进程设备波特率和wvdial重复检查wvdial配置和gammu配置,如果wvdial已经使用了ttyUSB3和波特率115200则gammu配置中就不要再使用相同设备和波特率,可以使用ttyUSB2和波特率at19200ModemManager占用设备查看设备后发现有进程ModemMnana在使用设备,可以停用ModemManager需要考虑实际使用情况来判断,在确认ModemManager确实不是必要软件后再进行操作sudo systemctl disable ModemManager.service sudo systemctl stop ModemManager.service
2024年04月08日
887 阅读
0 评论
0 点赞
2023-02-05
ESP32通过SmartConfig扫码配网
前引对于ESP配网方式和SmartConfig的介绍,在ESP-IDF编程指南中已经介绍得很详细了,这里就不在赘述。{% link ESP配网API,ESPRESSIF,https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/provisioning/index.html %}这里主要来介绍一下在Arduino中怎么使用SmartConfig来实现微信扫码配网,配网失败的一些解决办法,主要代码参考了CSDN上的一篇文章(不能确定是不是原作者,对贡献代码的人都表示感谢){% link ESP8266/ESP32 SmartConfig一键配网+自动重连+微信扫码配网,lw1997的博客-CSDN博客_esp32蓝牙配网,https://blog.csdn.net/u014091490/article/details/105178037 %}正文我只是在代码的原基础上做了简单的添加,指定了SmartConfig的Type#include "WiFi.h" void SmartConfig() { WiFi.mode(WIFI_AP_STA); Serial.println("\r\nWait for Smartconfig..."); WiFi.beginSmartConfig(SC_TYPE_ESPTOUCH_AIRKISS); //我做了修改的部分添加了“SC_TYPE_ESPTOUCH_AIRKISS” while (1) { Serial.print("."); delay(500); // wait for a second if (WiFi.smartConfigDone()) { Serial.println("SmartConfig Success"); Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str()); Serial.printf("PSW:%s\r\n", WiFi.psk().c_str()); break; } } } bool AutoConfig() { WiFi.begin(); //如果觉得时间太长可改 for (int i = 0; i < 20; i++) { int wstatus = WiFi.status(); if (wstatus == WL_CONNECTED) { Serial.println("WIFI SmartConfig Success"); Serial.printf("SSID:%s", WiFi.SSID().c_str()); Serial.printf(", PSW:%s\r\n", WiFi.psk().c_str()); Serial.print("LocalIP:"); Serial.print(WiFi.localIP()); Serial.print(" ,GateIP:"); Serial.println(WiFi.gatewayIP()); return true; } else { Serial.print("WIFI AutoConfig Waiting......"); Serial.println(wstatus); delay(1000); } } Serial.println("WIFI AutoConfig Faild!" ); return false; } void setup() { Serial.begin(115200); delay(100); if (!AutoConfig()) { SmartConfig(); } } void loop() { // put your main code here, to run repeatedly: }在使用作者源代码的时候,微信扫码和ESPTouch APP都没有成功,然后看到说要指定连接的类型,就可以解决根据自己的需求选合适的类型就行。关于连接工具微信扫码官方给的工具网址为:https://iot.espressif.cn/configWXDeviceWiFi.html可以利用网址链接转二维码工具生成二维码,像我生成的二维码:利用ESPTouch可以到ESP官网下载软件,有Android和iOS版本{% link 资源 | 乐鑫科技,ESPRESSIF,https://www.espressif.com.cn/zh-hans/products/software/esp-touch/resources %}乐鑫信息科技微信公众号
2023年02月05日
409 阅读
0 评论
0 点赞
2022-11-26
DHT11模块 Arduino代码补充
前引Arduino中已经有关于DHT11的库,但是为了理解模块的运行原理,而写了这个代码,代码中的不足之处还请多多指正。关于DHT11的原理,在之前的文章中已经提到过,就不再赘述。{% link DHT11温湿度模块部分代码实例,Mstzf,https://mstzf.cn/posts/dhtcode %}代码部分#define DHT11 15 void setup() { Serial.begin(115200); } void loop() { dht(); delay(2000); } void dht(){ double hum,tem; pinMode(DHT11,OUTPUT); digitalWrite(DHT11,HIGH); delay(2); digitalWrite(DHT11,LOW); delay(25); digitalWrite(DHT11,HIGH); delayMicroseconds(30); pinMode(DHT11,INPUT); if(!digitalRead(DHT11)){ Serial.println("ok"); while(!digitalRead(DHT11)); delayMicroseconds(10); while(digitalRead(DHT11)); int humInt=getData(); int humDec=getData(); int temInt=getData(); int temDec=getData(); int Check=getData(); if((humInt+humDec+temInt+temDec)==Check){ if(humDec<10){ hum=humInt+humDec/10.0; }else if(humDec<100){ hum=humInt+humDec/100.0; } if(temDec<10){ tem=temInt+temDec/10.0; }else if(temDec<100){ tem=temInt+temDec/100.0; } Serial.print("温度:"); Serial.print(tem); Serial.println(); Serial.print("湿度:"); Serial.print(hum); Serial.println(); } } else{ Serial.println("error"); } } int getData(){ byte Data; byte temp; for(int i=0 ;i<8;i++){ while(!digitalRead(DHT11)); delayMicroseconds(35); if(digitalRead(DHT11)){ temp=0x01; }else{ temp=0x00; } Data<<=1; Data|=temp; while(digitalRead(DHT11)); delayMicroseconds(10); } return Data; }
2022年11月26日
308 阅读
0 评论
0 点赞
2022-03-18
DHT11温湿度模块部分代码实例
产品概述DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度 复合传感器。应用专用的数字模块采集技术和温湿度传感技术,可以将获取到的环境温湿度信号通过单总线传输;信号中携带有校验码,一定程度上保证了数据的准确性。性能指标参数最小最大温度范围-20℃60℃湿度范围5%RH95%RH电压3.3V5.5V电流0.06mA1.0mA参数精确度温度±2℃湿度±5%RH引脚说明:VDD 供电3.3~5.5V DCDATA 串行数据,单总线NC 空脚GND 接地,电源负极工作原理数据时序图起始信号:微处理器把数据总线(SDA)拉低一段时间至少 18ms(最大不得超过 30ms),在拉高20us-40us,通知传感器准备数据。响应信号:传感器把数据总线(SDA)拉低 83µs,再拉高 87µs 以响应主机的起始信号。数据格式:收到主机起始信号后,传感器一次性从数据总线(SDA)串出 40 位数据,高位先出当检测到这一位数据的高电平后,我们要看这段高电平究竟会持续多长时间,0信号的高电平持续26-28us,1信号则持续70us。所以在上一步检测到高电平之后我们不妨等一等,等个30us看看高电平是不是还是存在,若还是高电平,那这一位信号就是1信号,若已经变低了,就是0信号,将这个1或0赋值给一个变量。温度:温度高位为温度整数部分数据,温度低位为温度小数部分数据,且温度低位 Bit8 为 1 则表示负温度,否则 为正温度湿度:湿度高位为湿度整数部分数据,湿度低位为湿度小数部分数校验位:校验位=湿度高位+湿度低位+温度高位+温度低位以上内容来自奥松电子DHT11官方文档,详细内容请查看文档代码实例树莓派Python3代码实例#!/usr/bin/python3 coding=utf-8 import RPi.GPIO as GPIO import time data = 18 # DHT11的data引脚连接到的树莓派的GPIO引脚,使用BCM编号 tmp=[] # 用来存放读取到的数据 a,b=0,0 def delayMicrosecond(t): # 微秒级延时函数 start,end=0,0 # 声明变量 start=time.time() # 记录开始时间 t=(t-3)/1000000 # 将输入t的单位转换为秒,-3是时间补偿 while end-start<t: # 循环至时间差值大于或等于设定值时 end=time.time() # 记录结束时间 def DHT11(): GPIO.setmode(GPIO.BCM) # 设置为BCM编号模式 GPIO.setwarnings(False) del tmp[0:] # 删除列表 time.sleep(1) # 延时1秒 GPIO.setup(data, GPIO.OUT) # 设置GPIO口为输出模式 #GPIO.output(data,GPIO.HIGH) # 设置GPIO输出高电平 #delayMicrosecond(10*1000) # 延时10毫秒 GPIO.output(data,GPIO.LOW) # 设置GPIO输出低电平 delayMicrosecond(25*1000) # 延时25毫秒 GPIO.output(data,GPIO.HIGH) # 设置GPIO输出高电平 GPIO.setup(data, GPIO.IN) # 设置GPIO口为输入模式 a=time.time() # 记录循环开始时间 while GPIO.input(data): # 一直循环至输入为低电平 b=time.time() # 记录结束时间 if (b-a)>0.1: # 判断循环时间是否超过0.1秒,避免程序进入死循环卡死 break # 跳出循环 a=time.time() while GPIO.input(data)==0: # 一直循环至输入为高电平 b=time.time() if (b-a)>0.1: break a=time.time() while GPIO.input(data): # 一直循环至输入为低电平 b=time.time() if (b-a)>=0.1: break for i in range(40): # 循环40次,接收温湿度数据 a=time.time() while GPIO.input(data)==0: #一直循环至输入为高电平 b=time.time() if (b-a)>0.1: break delayMicrosecond(28) # 延时28微秒 if GPIO.input(data): # 超过28微秒后判断是否还处于高电平 tmp.append(1) # 记录接收到的bit为1 a=time.time() while GPIO.input(data): # 一直循环至输入为低电平 b=time.time() if (b-a)>0.1: break else: tmp.append(0) # 记录接收到的bit为0 humidity_bit=tmp[0:8] # 分隔列表,第0到7位是湿度整数数据 humidity_point_bit=tmp[8:16]# 湿度小数 temperature_bit=tmp[16:24] # 温度整数 temperature_point_bit=tmp[24:32] # 温度小数 check_bit=tmp[32:40] # 校验数据 humidity_int=0 humidity_point=0 temperature_int=0 temperature_point=0 check=0 for i in range(8): # 二进制转换为十进制 humidity_int+=humidity_bit[i]*2**(7-i) humidity_point+=humidity_point_bit[i]*2**(7-i) temperature_int+=temperature_bit[i]*2**(7-i) temperature_point+=temperature_point_bit[i]*2**(7-i) check+=check_bit[i]*2**(7-i) humidity=humidity_int+humidity_point/10 temperature=temperature_int+temperature_point/10 check_tmp=humidity_int+humidity_point+temperature_int+temperature_point if check==check_tmp and temperature!=0 and temperature!=0: # 判断数据是否正常 print("Temperature is ", temperature,"℃\nHumidity is ",humidity,"%")# 打印温湿度数据 else: print("error") while True: DHT11() GPIO.cleanup() time.sleep(5)树莓派C语言代码实例// //mydht11.c //gcc dht11.c -o dht11 -lwiringPi //代码非原创,已经找不到原作者了,感谢大佬 // #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> typedef unsigned char uint8; typedef unsigned int uint16; typedef unsigned long uint32; #define HIGH_TIME 32 int pinNumber = 1; //use gpio1 to read data uint32 databuf; uint8 readSensorData(void) { uint8 crc; uint8 i; pinMode(pinNumber,OUTPUT); // set mode to output digitalWrite(pinNumber, 1); // output a low level delayMicroseconds(4); digitalWrite(pinNumber, 0); // output a high level delay(25); digitalWrite(pinNumber, 1); // output a low level delayMicroseconds(60); pinMode(pinNumber, INPUT); // set mode to input pullUpDnControl(pinNumber,PUD_UP); if(digitalRead(pinNumber)==0) //SENSOR ANS { while(!digitalRead(pinNumber)); //wait to high delayMicroseconds(80); for(i=0;i<32;i++) { while(digitalRead(pinNumber)); //data clock start while(!digitalRead(pinNumber)); //data start delayMicroseconds(HIGH_TIME); databuf*=2; if(digitalRead(pinNumber)==1) //1 { databuf++; } } for(i=0;i<8;i++) { while(digitalRead(pinNumber)); //data clock start while(!digitalRead(pinNumber)); //data start delayMicroseconds(HIGH_TIME); crc*=2; if(digitalRead(pinNumber)==1) //1 { crc++; } } return 1; } else { return 0; } } int main (void) { if (-1 == wiringPiSetup()) { //printf("Setup wiringPi failed!"); return 1; } pinMode(pinNumber, OUTPUT); // set mode to output digitalWrite(pinNumber, 1); // output a high level //while(1) //{ pinMode(pinNumber,OUTPUT); // set mode to output digitalWrite(pinNumber, 1); // output a high level //delay(3000); if(readSensorData()) { printf("OK!\n"); printf("RH:%d.%d\n",(databuf>>24)&0xff,(databuf>>16)&0xff); printf("TMP:%d.%d\n",(databuf>>8)&0xff,databuf&0xff); databuf=0; } else { printf("Error!\n"); databuf=0; } //} return 0; }ESP32C语言代码实例(ESP-IDF官方编译烧写工具)#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "sdkconfig.h" #define DHT11_PIN (15) //可通过宏定义,修改引脚 #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); } //DHT11初始化 void DHT11_Start(void) { /*************************** * * 主机发送给DHT11复位信号 * * 首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,取中间值 30us,此时复位信号发送完毕。 * * **********************************/ DHT11_OUT; //设置端口方向 DHT11_CLR; //拉低端口 DelayUs(19 * 1000); // vTaskDelay(19 * portTICK_RATE_MS); //持续最低18ms; DHT11_SET; //主机拉高端口 DelayUs(30); //总线由上拉电阻拉高,主机延时30uS; /******************************** * DHT11发送响应信号 * * DHT11 检测到复位信号后,触发一次采样, * 并拉低总线 80us 表示响应信号,告诉主机数据已经准备好了; * 然后 DHT11 拉高总线 80us, * 之后开始传输数据。如果检测到响应信号为高电平, * 则 DHT11 初始化失败, * 请检查线路是否连接正常。 * *******************************/ 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(40); // 延时 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; else return 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("ESP32 DHT11 TEST:%s,%s!\r\n", __DATE__, __TIME__); printf("Temp=%d.%d, Humi=%d.%d\r\n", Temp,DHT11Data[3],Humi,DHT11Data[1]); } else { printf("DHT11 Error!\r\n"); } vTaskDelay(5000 / portTICK_PERIOD_MS); } }附录:树莓派GPIO
2022年03月18日
515 阅读
0 评论
0 点赞