Weather:bit

来自Labplus盛思维基百科
Tangliufeng讨论 | 贡献2018年4月24日 (二) 14:34的版本
跳转至: 导航搜索
Weather bit.png

概述

该套件以micro:bit为主控,拓展建立一个微型气象站。Weather:bit内集成环境传感器可测量气压、 气温、相对湿度。可外接风速、风向计和雨量计、土壤湿度传感器、防水温度传感器。

技术参数

  • 压力传感器:±0.25%(在400m高度变化时相当于1m)
  • 湿度传感器:±3%相对湿度
  • 操作范围(全精度):压力:300-1100 hPa 、温度:-40-85°C

气象站场景

气象站套件清单

  1. weather:bit扩展板(板载气压、温度、湿度传感器)
  2. micro:bit主板 x2
  3. extend:bitⅡ
  4. 风速、风向、降雨量采集器(含支架)
  5. blue:bit-土壤湿度
  6. blue:bit-音乐播放
  7. blue:bit-LED
  8. NTC温度探头(10K)
  9. 32x16 RGB LED 点阵屏

气象站场景连接示意图


Weatherbit conect.png
weather:bit连接示意图

程序

weather:bit气象站实时接收气象数据(风速、风向、降雨量、土壤湿度、土壤温度、大气压强、气温、空气湿度),并利用microbit无线传输将气象数据显示在32x16全彩点阵屏

教程:microbit怎么编程下载?
weatherbit程序下载

  • 气象站端micro:bit数据采集程序
from microbit import *
import struct
import math
import radio
T1=T2=T3=P1=P2=P3=P4=P5=P6=P7=P8=P9=H1=H2=H3=H4=H5=H6=tF=1
tCnt=tCnt1=wScnt=rAcnt=wsBefore=raBefore=0

def BME280Init():
    global T1,T2,T3,H1,H2,H3,H4,H5,H6,tF
    global P1,P2,P3,P4,P5,P6,P7,P8,P9
    i2c.write(0x76, bytearray([0xF2, 0x01]))
    i2c.write(0x76, bytearray([0xF4, 0x27]))
    i2c.write(0x76, bytearray([0xF5, 0]))
    
    i2c.write(0x76, bytearray([0x88]))
    T = i2c.read(0x76, 24)
    T1 = (T[1]<<8) | T[0]    
    T2 = cvt2int16(T[3],T[2])
    T3 = cvt2int16(T[5],T[4])
    P1 = T[6] | (T[7]<<8)    
    P2 = cvt2int16(T[9],T[8])      
    P3 = cvt2int16(T[11],T[10])  
    P4 = cvt2int16(T[13],T[12])      
    P5 = cvt2int16(T[15],T[14])     
    P6 = cvt2int16(T[17],T[16])   
    P7 = cvt2int16(T[19],T[18])  
    P8 = cvt2int16(T[21],T[20])   
    P9 = cvt2int16(T[23],T[22])  
    i2c.write(0x76, bytearray([0xA1]))
    tmp = i2c.read(0x76, 1)    
    H1 = tmp[0]
    i2c.write(0x76, bytearray([0xE1]))
    H = i2c.read(0x76, 7)
    H2 = cvt2int16(H[1],H[0])
    H3 = H[2]
    H4 = struct.unpack("h", struct.pack("H",(H[3]<<4)|(H[4]&0xf)))[0]
    H5 = struct.unpack("h", struct.pack("H",(H[5]<<4)|(H[4]>>4)))[0]
    H6 = H[6]
    getTemp()
    tCnt = tCnt1 = running_time()

def getTemp():
    global tF,T1,T2,T3
    i2c.write(0x76, bytearray([0xFA]))
    tmp = i2c.read(0x76, 3) 
    T = (((tmp[0]<<8)|tmp[1])<<4)|(tmp[2]>>4)
    tmp1 = ((T >> 4) - T1)
    c1 = (((T >> 3) - (T1 << 1)) * T2) >> 11
    c2 = (((tmp1*tmp1) >> 12) * T3) >> 14
    tF = c1+c2
    return ((tF * 5 + 128) >> 8)

def getHumidity():
    global H1,H2,H3,H4,H5,H6,tF
    i2c.write(0x76, bytearray([0xFD]))
    tmp=i2c.read(0x76, 2)
    h=(tmp[0]<<8)|tmp[1]
    hum = tF - 76800
    tmp = (((h<<14)-(H4<<20)-(H5*hum))+16384)>>15
    tmp1 =((((hum*H6)>>10)*(((hum*H3)>>11)+32768))>>10)+2097152
    tmp1 = (tmp1*H2+8192)>>14
    var1 = tmp*tmp1
    hum1 = var1 - (((var1 >> 15) * (var1 >> 15)) >> 7) * (H1 >> 4)
    if hum1<0:
        hum1=0
    if hum1>419430400:
        hum1=419430400
    return (hum1>>12)//100
    
def getPressure():
    global P1,P2,P3,P4,P5,P6,P7,P8,P9,tF
    i2c.write(0x76, bytearray([0xF7]))
    tmp = i2c.read(0x76, 3) 
    P = (((tmp[0]<<8)|tmp[1])<<4)|(tmp[2]>>4)
    var1 = tF - 128000
    var2 = var1 * var1 * P6
    var2 = var2 + ((var1 * P5)<<17)
    var2 = var2 + (P4<<35)
    var1 = ((var1 * var1 * P3)>>8) + ((var1 * P2)<<12)
    var1 = ((((1<<47)+var1))*P1)>>33
    if (var1 == 0):
        return 0
    p_acc = 1048576 - P
    p_acc = int((((p_acc<<31) - var2)*3125)/var1)
    var1 = (P9 * (p_acc>>13) * (p_acc>>13)) >> 25
    var2 = (P8 * p_acc) >> 19;
    p_acc = ((p_acc + var1 + var2) >> 8) + (P7<<4)
    return (p_acc>>8)//100

def cvt2int16(d1,d2):
    d = (d1<<8) | d2
    return struct.unpack("h", struct.pack("H",d))[0]

BME280Init()
display.off()
pin13.read_digital()
pin13.set_pull(pin13.PULL_UP)
pin8.read_digital()
pin8.set_pull(pin8.PULL_UP)
radio.config(length=32, queue=3, channel=7, power=0, data_rate=radio.RATE_1MBIT)
radio.on()
while True:
    s = struct.pack("h", getTemp()) 
    s = s+struct.pack("h", getHumidity())
    s = s+struct.pack("h", getPressure())
    if (wsBefore != pin8.read_digital()):
        wScnt += 1
        #print(wScnt)
        wsBefore = pin8.read_digital()      
    if (raBefore != pin13.read_digital()):
        rAcnt += 1
        raBefore = pin13.read_digital()
    if ((running_time()-tCnt)>10000):
        s = s+struct.pack("H", pin1.read_analog())
        s = s+struct.pack("H", pin2.read_analog())
        pin16.write_digital(1)
        sleep(10)
        #print(pin0.read_analog())
        s = s+struct.pack("H", pin0.read_analog())
        pin16.write_digital(0)
        s = s+struct.pack("H", wScnt)
        s = s+struct.pack("H", rAcnt)
        radio.send_bytes(s)
        #print(s)
        wScnt = 0
        tCnt = running_time()
    if ((running_time()-tCnt1)>86400000):
        rAcnt = 0
        tCnt1 = runing_time()



  • 点阵屏microbit端数据显示程序
from microbit import *
import struct
import radio
import math
tCnt = 0
beginFlag = 1

def MP3CmdWrite(cmd):
    sum = 0
    for i in range(0,6):
        sum += cmd[i]
	sum1 = ((0xFFFF - sum) + 1)
    sum_l = sum1 & 0xff
    sum_h = sum1 >> 8
	
    uart.write(bytearray([0x7E]))
    uart.write(cmd)
    uart.write(bytearray([sum_h]))
    uart.write(bytearray([sum_l]))
    uart.write(bytearray([0xEF]))
    sleep(20)

def MP3Play(num):
    var = bytearray([0xFF,0x06,0x03,0x01,0x00,num])
    MP3CmdWrite(var)

def MP3Volume(vol):
    var = bytearray([0xFF,0x06,0x06,0x00,0x00,vol])
    MP3CmdWrite(var)

pin8.write_digital(0)
radio.config(length=32, queue=3, channel=7, power=0, data_rate=radio.RATE_1MBIT)
radio.on()
uart.init(baudrate=9600, bits=8, parity=None, stop=1, tx=pin0, rx=pin1)
MP3Volume(28)
sleep(4000)
MP3Play(1)
uart.init(baudrate=115200, bits=8, parity=None, stop=1, tx=pin14, rx=pin15)
tCnt = running_time()
while True:
    tmp = radio.receive_bytes()
    if (tmp!=None):
        #print(tmp)
        aT = (struct.unpack('h',struct.pack('h',(tmp[1]<<8)|tmp[0]))[0])/100
        aH = (struct.unpack('h',struct.pack('h',(tmp[3]<<8)|tmp[2]))[0])/10.24
        aP = (struct.unpack('h',struct.pack('h',(tmp[5]<<8)|tmp[4]))[0])/10
        wd = (struct.unpack('h',struct.pack('h',(tmp[7]<<8)|tmp[6]))[0])
        if (wd < 906 and wd > 886):
            wD =  '北风'
        elif (wd < 712 and wd > 692):
            wD = '东北风'
        elif (wd < 415 and wd > 395):
            wD = '东风'
        elif (wd < 498 and wd > 478):
           wD = '东南风'
        elif (wd < 584 and wd > 564):
            wD = '南风'
        elif (wd < 819 and wd > 799):
            wD = '西南风'
        elif (wd < 988 and wd > 968):
            wD = '西风'
        elif (wd < 959 and wd > 939):
            wD = '西北风'
        else:
            wD =  '???'
        sT = (struct.unpack('h',struct.pack('h',(tmp[9]<<8)|tmp[8]))[0])
        sT = 1/(math.log(1024/sT-1)/3935+1/298)-273
        sO = (struct.unpack('h',struct.pack('h',(tmp[11]<<8)|tmp[10]))[0])
        wS = (struct.unpack('h',struct.pack('h',(tmp[13]<<8)|tmp[12]))[0])//30
        rA = (struct.unpack('h',struct.pack('h',(tmp[15]<<8)|tmp[14]))[0])*0.14
        pin8.write_digital(1)
        sleep(500)
        pin8.write_digital(0)
        if (running_time()-tCnt)>60000 or beginFlag == 1:
            tCnt = running_time()
            beginFlag = 0
            s = "@3温度:%.1f℃ 湿度:%.1f%% 气压:%.1fkPa 土壤湿度:%d 土壤温度:%.1f℃ 风速: %d级 风向: %s 降雨量: %dmm.\r\n"%(aT,aH,aP,sO,sT,wS,wD,rA)
            print(s)

版本历史记录

Version Date Note [+]新增[-]删除[^]修复
V1.3 2018/04/24 修改I2C接口引脚排序