esp8266连接AHT20和BMP280

esp8266连接AHT20和BMP280
esp8266 micropython 控制AHT20和BMP280

AHT20手册百度一搜就有,还是免费中文的,BMP280的手册官网上有,是英文的,链接在我后面的代码部分里面有

测试效果

一句话:误差很大
AHT20和BMP280测出来的温度差0.6°左右
AHT20之间测出的温度误差在0.4°左右
BMP280之间温度误差在0.5°左右
我发现一个问题,这些传感器尤其是bmp280,一段时间不测量或者刚开机的时候,得到的温度就会很高,然后会慢慢下降,最好是一直让它测量,这样得出来的结果才能尽可能的可靠

首先看接线

我买的是AHT20和BMP280放在一个板子上的,用I2C通信
vdd接3.3V
GND接GND
SCL接esp8266上的D1(gpio5)
SDA接esp8266上的D2(gpio4)
由于只是学习并不是做产品,这里就只是用杜邦线连接的,没有直接焊上去
AHT20和BMP280
ESP8266

代码部分

先是传感器控制部分,这里是用类进行了封装,两个设备共用一个i2c总线

from machine import Pin,I2C
import utime
from ustruct import unpack

#共用的i2c设备,由于我买的bmp280和AHT20是在一张板子上,共用接口,故用一个i2c就行了
i2c=I2C(scl=Pin(5),sda=Pin(4),freq=100000)

#写寄存器,给BMP280使用的
def writeRegister(addr,rAddr,buf):
    if type(buf) !=bytearray:
        buf=bytearray([buf])
    i2c.writeto_mem(addr,rAddr,buf)     #esp8266没有size参数
    
#读寄存器,给BMP280使用的   
def readRegister(addr,rAddr,size=1):    
    return i2c.readfrom_mem(addr,rAddr,size)     #size表示读几个字节,也就是地址偏移量

class AHT20:
    '''可控制ATH20,21,使用getData读取温度和湿度,返回一个元组.'''
    def __init__(self):
        self.addr=0x38
        
        self.sig_getStatus=bytearray(1)
        self.sig_getStatus[0]=0x71
        #读取的状态字的最后一位如果是0表示测量完成,第四位如果为0表示未校准
        
        self.sig_init=bytearray(3)
        self.sig_init[0]=0xe1
        self.sig_init[1]=0x08
        self.sig_init[2]=0x00
        
        self.sig_measure=bytearray(3)
        self.sig_measure[0]=0xac
        self.sig_measure[1]=0x33
        self.sig_measure[2]=0x00
        #测量后,可以连续读取7字节数据,按需要读取,读取的数据第一个字节和发送0x71一样获得的是状态字
        #第2,3,字节和第四字节的高四位是湿度数据,第四字节底四位和第5,6字节是温度数据,第七字节是crc校验值
        
        self.checkDevice()
        self.initDevice()
        
    #检查是否有设备连接,如果未连接会一直卡在这里
    def checkDevice(self):  
        devList=i2c.scan()
        while self.addr not in devList:
            print("not found devices!")
            utime.sleep_ms(1000)
    
    #检查设备是否就绪,如果未就绪则进行初始化
    def initDevice(self):
        i2c.writeto(self.addr,self.sig_getStatus)
        while not (int.from_bytes(i2c.readfrom(self.addr,1),'big') & 0x18):
            i2c.writeto(self.addr,self.sig_init)
            utime.sleep_ms(100)
    
    #读取并计算温度和湿度
    def getData(self):
        flag=1
        i2c.writeto(self.addr,self.sig_measure) #发送测量信号
        d=0
        while flag: 
            utime.sleep_ms(100)
            d=i2c.readfrom(self.addr,6)
            flag=d[0]&0x01  #检查是否测量完成
            
        humidity=int.from_bytes(bytes.fromhex('0'+d.hex()[2:7]),'big')*100.0/0x100000
        temperature=int.from_bytes(bytes.fromhex('0'+d.hex()[7:12]),'big')*200.0/0x100000 - 50

        return round(temperature,2),round(humidity,2)   #摄氏度,RH%



class BMP280:
    '''可控制BMP280,使用getData读取温度和压强,返回一个元组.
        请注意查看自己的设备地址是0x76还是0x77'''
    def __init__(self):
        self.addr=0x77
        
        self.sig_measure=bytes.fromhex('f456')
        
        self.sig_softReset=bytes.fromhex('e0b6')
        
        #这两个参数是从别人的地方看到的,具体作用不详
        self.sig_setMode=bytes.fromhex('f455')    
        self.sig_setConfig=bytes.fromhex('f510')

        self.checkDevice()
        self.initDevice()
        self.getConfig()
       
    #检查设备是否已经连接
    def checkDevice(self):
        devList=i2c.scan()
        while self.addr not in devList:
            print("not found devices!")
            utime.sleep_ms(1000)
            
    #初始化设备,设置一些参数      
    def initDevice(self):
        writeRegister(self.addr,self.sig_setMode[0],self.sig_setMode[1])
        writeRegister(self.addr,self.sig_setConfig[0],self.sig_setConfig[1])
    
    #读取设备寄存器中的数据,后面计算要用到,每个芯片好像这些值不一样,大概相当于出厂时的校准参数
    def getConfig(self):
        self.T1 = unpack('<H', readRegister(self.addr,0x88, 2))[0]
        self.T2 = unpack('<h', readRegister(self.addr,0x8A, 2))[0]
        self.T3 = unpack('<h', readRegister(self.addr,0x8C, 2))[0]
        self.P1 = unpack('<H', readRegister(self.addr,0x8E, 2))[0]
        self.P2 = unpack('<h', readRegister(self.addr,0x90, 2))[0]
        self.P3 = unpack('<h', readRegister(self.addr,0x92, 2))[0]
        self.P4 = unpack('<h', readRegister(self.addr,0x94, 2))[0]
        self.P5 = unpack('<h', readRegister(self.addr,0x96, 2))[0]
        self.P6 = unpack('<h', readRegister(self.addr,0x98, 2))[0]
        self.P7 = unpack('<h', readRegister(self.addr,0x9A, 2))[0]
        self.P8 = unpack('<h', readRegister(self.addr,0x9C, 2))[0]
        self.P9 = unpack('<h', readRegister(self.addr,0x9E, 2))[0]     
      
    #读取数据并计算压强和温度,计算公式参考手册第22页的代码   
    #参考手册下载地址:https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf
    def getData(self):
        writeRegister(self.addr,self.sig_measure[0],self.sig_measure[1])
        utime.sleep_ms(100)
        d=readRegister(self.addr,0xf7,6)    #根据手册第23页,从这个寄存器中读取压强和温度数据,地址偏移6,也就是连续读取6个字节,读取0xf7-0xfc
        #0xf7,0xf8,0xf9的高4位是压强数据
        #0xfa,0xfb,0xfc的高4位是温度数据
        #温度和压强都占20位,两个半字节
        
        raw_p=int.from_bytes(bytes.fromhex('0'+d.hex()[0:5]),'big')
        raw_t=int.from_bytes(bytes.fromhex('0'+d.hex()[6:11]),'big')
        
        t1 = (((raw_t>>3) - (self.T1<<1))*self.T2) >> 11 
        t2=(((((raw_t>>4) - self.T1) * ((raw_t>>4) - self.T1)) >> 12)* self.T3) >> 14
        t=(((t1+t2)*5+128)/256.0)/100.0     #摄氏度  

        p1=t1+t2-128000
        p2=p1*p1*self.P6
        p2=p2+((p1*self.P5)<<17)
        p2=p2+(self.P4<<35)
        p1=((p1*p1*self.P3)>>8)+((p1*self.P2)<<12)
        p1=(((1<<47)+p1)*self.P1)>>33
        if p1==0:
            return t,0
        p=1048576-raw_p
        p=(((p<<31)-p2)*3125)/p1
        p=int(p)
        p1=(self.P9*(p>>13)*(p>>13))>>25
        p2=(self.P8*p)>>19
        p=((p+p1+p2)>>8)+((self.P7)<<4)
        p=p/256000.0 #KPa

        return round(t,2),round(p,4)    #摄氏度,KPa
        
    #设备软重置
    def softReset(self):
        writeRegister(self.addr,self.sig_softReset[0],self.sig_softReset[1])
  

def test()  
    aht=AHT20()
    for i in range(10):
        print(aht.getData())
    
    bmp=BMP280()
    for i in range(10):
        print(bmp.getData())
    
    for i in range(10):
        print(aht.getData(),'\t',bmp.getData())
        utime.sleep(1)

简单的HTTP示例,基于select

import socket
import select
from sensors import BMP280,AHT20,i2c

serverAddress=('0.0.0.0',80)
sockfd=socket.socket()
sockfd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
sockfd.bind(serverAddress)
sockfd.listen(6)
sockfd.setblocking(False)

bmp=BMP280()
aht=AHT20()


def handle(connfd,data):
    requests=data.decode('utf-8').split("\r\n")
    request=''
    for i in requests:
        if 'GET' in i:
            request=i.split(' ')[1]
            break
    print(request)
    Head='''HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n'''
    if request.lower() == '/getdata':
        d1=aht.getData()
        d2=bmp.getData()
        Page='''AHT20:    温度: {} ℃    湿度: {} % 
        \r\n    BMP280:   温度: {} ℃    压强: {} KPa'''.format(d1[0],d1[1],d2[0],d2[1])
    else:
        Page='''<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>

<body>
    <p>传感器:</br></p>
    <p id="info" name="info"></p>
</body>

<script>
    setInterval(function(){
        $.get("/getdata",function(result){ 
                document.getElementById("info").innerText=result;
                console.log("success")
                })
    },1000);

</script>



</html>
''' 
    connfd.send(Head.encode())
    connfd.send(Page.encode())
    connfd.close()
      

inputs=[sockfd]
outputs=[]


while 1:
    readable,writeables,exceptional=select.select(inputs, outputs, inputs)
    print(readable,writeables,exceptional)
    
    
    #检查可读列表,查看是否有外部连接
    for i in readable:
        
        #来连接了,进行连接
        if i is sockfd:
            coonfd,addr=sockfd.accept()
            print(addr)
            inputs.append(coonfd)
        
        #来数据了,进行接收
        else:
            data=i.recv(4096)
            if data:
                handle(i,data)
            else:
                #数据为空,断开连接,清理连接
                if i in inputs:
                    inputs.remove(i)
                i.close()       
    
    
    #检查错误列表,处理错误,清理错误的连接
    for e in exceptional:
        print(e)
        if e in outputs:
            outputs.remove(e)
        if e in inputs:
            inputs.remove(e)

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
ESP32是一种微控制器开发板,具有强大的处理能力和丰富的通信接口。AHT20BMP280是两种常见的环境传感器,用于测量温度、湿度和气压等环境参数。 如果想要使用ESP32来控制AHT20BMP280传感器,可以按照以下步骤进行操作: 1. 硬件连接:将AHT20BMP280传感器分别连接到ESP32的GPIO引脚,确保引脚的连接正确无误。 2. 引用库文件:在Arduino IDE中,选择适用于ESP32的开发环境,并下载AHT20BMP280传感器的库文件。将库文件导入到Arduino IDE中,以便在编程中使用相关函数。 3. 初始化传感器:在代码中使用合适的函数初始化AHT20BMP280传感器。根据传感器的规格书,设置合适的参数和工作模式。 4. 读取传感器数据:使用传感器库提供的函数,读取AHT20BMP280传感器测量到的温度、湿度和气压数据。 5. 控制传感器:使用ESP32的GPIO引脚向传感器发送控制信号,例如改变工作模式、设置传感器的采样频率等。 6. 数据处理和应用:根据实际需求,对传感器测量到的数据进行处理和计算,并根据需要将数据发送到其他外部设备或者进行相应的操作。 需要注意的是,在编程过程中要仔细阅读传感器和ESP32的规格书,了解传感器和ESP32的通信接口和协议,以便正确地配置和控制传感器。 总之,通过合适的硬件连接和编程代码,我们可以使用ESP32来控制AHT20BMP280传感器,实现对环境参数的监测和控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值