54

MicroPython开发实例之自制小型家庭气象站

 6 years ago
source link: http://www.freebuf.com/geek/175548.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

众所周知,iPhone6/6Plus内置气压传感器,不过大家对于气压传感器还是很陌生。跟字面的意思一样,气压传感器就是用来测量气压的,但测量气压对于普通的手机用户来说又有什么作用呢?

海拔高度测量

对于喜欢登山的人来说,会非常关心自己所处的高度。海拔高度的测量方法,一般常用的有2种方式,一是通过GPS全球定位系统,二是通过测出大气压,然后根据气压值计算出海拔高度。由于受到技术和其它方面原因的限制,GPS计算海拔高度一般误差都会有十米左右,而如果在树林里或者是在悬崖下面时,有时候甚至接收不到GPS卫星信号。而气压的方式可选择的范围会广些,而且可以把成本控制的比较低。在手机原有GPS的基础上再增加气压传感器的功能,可让三维定位更加精准。

最近发现一块好玩的开发板——TPYBoardv702,这个板子可以定位、发短信、打电话,并且板载温湿度传感器、光敏传感器以及蜂鸣器,可以DIY很多有趣的东西,下面我们可以用这个板子加一个气压传感器来做一个小型气象站,来张实物图:

MJfQVb2.jpg!web

TPYBoardv702

定位功能我就不多说了,如果需要的话可以私聊。

那么我们利用这块板子跟BMP180气压传感器来做一个小型家庭气象站,来检测当地温度以及当地气压与海拔,如果想做更好玩的东西,可以接其他传感器或者加个继电器来控制其他设备。

BMP180是一直常见的气压传感器,BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,精度最低可以达到0.03hPa,并且耗电极低,只有3μA;BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。

u63E3u2.jpg!web

硬件接线图

TPYBoard v702 BMP180 3.3V VIN GND GND Y9 SCL Y10 SDA

效果展示图

JBNjIzr.jpg!web

连接完毕后,将font.py,upcd8544.py与bmp180的库导入,就可以通过以下方法分别读取温度、气压、海拔高度了。

源代码

oot.py,upcd8544.py库的下载地址

http://www.tpyboard.com/support/studyexample14/206.html

导入需要的类库,编辑好main.py,直接运行就ok了,下面是main.py的程序源码

# main.py -- put your code here!
import pyb
import upcd8544
from machine import SPI,Pin
from ubinascii import hexlify
from ubinascii import *
from bmp180 import BMP180
bmp=BMP180(2)
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST    = pyb.Pin('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
while True:
       tem=bmp.getTemp()
       press=bmp.getPress()
       altitude=bmp.getAltitude()
       lcd_5110.lcd_write_string('Tem:',0,0)
       lcd_5110.lcd_write_string(str(tem),0,1)
       lcd_5110.lcd_write_string('C',65,1)
       lcd_5110.lcd_write_string('Press:',0,2)
       lcd_5110.lcd_write_string(str(press),0,3)
       lcd_5110.lcd_write_string('Pa',65,3)      
       lcd_5110.lcd_write_string('Hight:',0,4)
       lcd_5110.lcd_write_string(str(altitude),0,5)
       lcd_5110.lcd_write_string('M',65,5)

bmp180.py库的源码

import pyb
from pyb import I2C
BMP180_I2C_ADDR = const(0x77)
class BMP180():
    def __init__(self, i2c_num):
        self.i2c = I2C(i2c_num, I2C.MASTER, baudrate = 100000)
        self.AC1 = self.short(self.get2Reg(0xAA))
        self.AC2 = self.short(self.get2Reg(0xAC))
        self.AC3 = self.short(self.get2Reg(0xAE))
        self.AC4 = self.get2Reg(0xB0)
        self.AC5 = self.get2Reg(0xB2)
        self.AC6 = self.get2Reg(0xB4)
        self.B1 = self.short(self.get2Reg(0xB6))
        self.B2 = self.short(self.get2Reg(0xB8))
        self.MB = self.short(self.get2Reg(0xBA))
        self.MC = self.short(self.get2Reg(0xBC))
        self.MD = self.short(self.get2Reg(0xBE))
        self.UT = 0
        self.UP = 0
        self.B3 = 0
        self.B4 = 0
        self.B5 = 0
        self.B6 = 0
        self.B7 = 0
        self.X1 = 0
        self.X2 = 0
        self.X3 = 0
    def short(self, dat):
        if dat > 32767:
            return dat - 65536
        else:
            return dat
    def setReg(self, dat, reg):
        buf = bytearray(2)
        buf[0] = reg
        buf[1] = dat
        self.i2c.send(buf, BMP180_I2C_ADDR)
    def getReg(self, reg):
        buf = bytearray(1)
        buf[0] = reg
        self.i2c.send(buf, BMP180_I2C_ADDR)
        t = self.i2c.recv(1, BMP180_I2C_ADDR)
        return t[0]
    def get2Reg(self, reg):
        a = self.getReg(reg)
        b = self.getReg(reg + 1)
        return a*256 + b
    def measure(self):
        self.setReg(0x2E, 0xF4)
        pyb.delay(5)
        self.UT = self.get2Reg(0xF6)
        self.setReg(0x34, 0xF4)
        pyb.delay(5)
        self.UP = self.get2Reg(0xF6)
    def getTemp(self):
        self.measure()
        self.X1 = (self.UT - self.AC6) * self.AC5/(1<<15)
        self.X2 = self.MC * (1<<11) / (self.X1 + self.MD)
        self.B5 = self.X1 + self.X2
        return (self.B5 + 8)/160
    def getPress(self):
        self.getTemp()
        self.B6 = self.B5 - 4000
        self.X1 = (self.B2 * (self.B6*self.B6/(1<<12))) / (1<<11)
        self.X2 = (self.AC2 * self.B6)/(1<<11)
        self.X3 = self.X1 + self.X2
        self.B3 = ((self.AC1*4+self.X3) + 2)/4
        self.X1 = self.AC3 * self.B6 / (1<<13)
        self.X2 = (self.B1 * (self.B6*self.B6/(1<<12))) / (1<<16)
        self.X3 = (self.X1 + self.X2 + 2)/4
        self.B4 = self.AC4 * (self.X3 + 32768)/(1<<15)
        self.B7 = (self.UP-self.B3) * 50000
        if self.B7 < 0x80000000:
            p = (self.B7*2)/self.B4
        else:
            p = (self.B7/self.B4) * 2
        self.X1 = (p/(1<<8))*(p/(1<<8))
        self.X1 = (self.X1 * 3038)/(1<<16)
        self.X2 = (-7357*p)/(1<<16)
        p = p + (self.X1 + self.X2 + 3791)/16
        return p
    def getAltitude(self):
        p = self.getPress()
        return (44330*(1-(p/101325)**(1/5.255)))
    def get(self):
        t = []
        t.append(self.getPress())
        t.append(self.getAltitude())
        t.append(self.getTemp())
        return t

*本文作者:bodasister,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK