1. 程式人生 > >用樹莓派學程式設計系列4——環境光照強度測量

用樹莓派學程式設計系列4——環境光照強度測量

樹莓派系列4——環境光照強度測量

前期準備

  • 環境要求
    GY30模組(BH1750FVI感測器),樹莓派系統,python-smbus,iic開啟
  • 安裝python-smbus
    這個安裝會附帶安裝i2c-tools,省的單獨安裝了
 sudo apt-get install python-smbus

光照強度測量

建立illuminance應用

具體方法請參考本系列前面文章

BH1750FVI與樹莓派連線

BH1750FVI簡介

BH1750FVI 是一種用於兩線式序列匯流排介面的數字型光強度感測器積體電路。這種積體電路可以根據收集的光線強度資料來調整液晶或者鍵盤背景燈的亮度。利用它的高解析度可以探測較大範圍的光強度變化。(1lx-65535lx)

  • 產品特點
    1. 支援I2C BUS介面(f/s Mode Support)。
    2. 接近視覺靈敏度的光譜靈敏度特性(峰值靈敏度波長典型值:560nm)。
    3. 輸出對應亮度的數字值。
    4. 對應廣泛的輸入光範圍(相當於1-65535lx)。
    5. 通過降低功率功能,實現低電流化。
    6. 通過50Hz/60Hz除光噪音功能實現穩定的測定
    7. 支援1.8V邏輯輸入介面。
    8. 無需其他外部件。
    9. 光源依賴性弱(白熾燈,熒光燈,鹵素燈,白光LED,日光燈)。
    10. 有兩種可選的I2C slave地址。
    11. 可調的測量結果影響較大的因素為光入口大小。
    12. 使用這種功能能計算1.1 lx到100000 lx馬克斯/分鐘的範圍。
    13. 最小誤差變動在±20%。

BH1750的I2C說明

BH1750支援倆種地址, ADDR=”H”(ADDR≥0.7VCC) ,地址為0x5c ADDR=”L”(ADDR≤0.3VCC),地址為0x23 由於GY-30模組已經在ADDR管腳與地之間加了一個1000歐姆的電阻,所以預設地址為0x23,

BH1750命令說明

命令 命令含義
0x00 斷電
0x01 通電
0x07 復位
0x10 連續H解析度模式
0x11 連續H解析度模式2
0x13 連續L解析度模式
0x20 一次H解析度模式
0x21 一次H解析度模式2
0x23 一次L解析度模式
0x42 0x65 靈敏度100%
0x44 0x6A 靈敏度50%
0x41 0x73 靈敏度200%

BH1750讀取方法

通電(0x01)-設定模式(0x10\0x11\0x13\0x20\0x21\0x23)-等待測量-讀取資料

光照強度計算

=1.2

GY-30模組與樹莓派連線

GY-30 樹莓派
VCC —— 1
GND —— 9
SDA —— 3
SCL —— 5
ADDR —— 不接

連線測試

使用I2C TOOLS進行檢視
sudo i2cdetect -y 1
可看到以下結果,與我們前面所說地址為0x23相符 ![I2C](https://img-blog.csdn.net/20161011194738376)

光照強度測量

程式的設定

設定方式方法與前面相同

程式

  • 建立illuminance.py
 cd /home/pi/helloworld/illuminance
 vim illuminance.py

illuminance.py

#!/usr/bin/env python
# encoding: utf-8

import smbus
import time

#BH1750地址
__DEV_ADDR=0x23

#控制字
__CMD_PWR_OFF=0x00  #關機
__CMD_PWR_ON=0x01   #開機
__CMD_RESET=0x07    #重置
__CMD_CHRES=0x10    #持續高解析度檢測
__CMD_CHRES2=0x11   #持續高解析度模式2檢測
__CMD_CLHRES=0x13   #持續低解析度檢測
__CMD_THRES=0x20    #一次高解析度
__CMD_THRES2=0x21   #一次高解析度模式2
__CMD_TLRES=0x23    #一次解析度
__CMD_SEN100H=0x42  #靈敏度100%,高位
__CMD_SEN100L=0X65  #靈敏度100%,低位
__CMD_SEN50H=0x44   #50%
__CMD_SEN50L=0x6A   #50%
__CMD_SEN200H=0x41  #200%
__CMD_SEN200L=0x73  #200%

bus=smbus.SMBus(1)
bus.write_byte(__DEV_ADDR,__CMD_PWR_ON)
bus.write_byte(__DEV_ADDR,__CMD_RESET)
bus.write_byte(__DEV_ADDR,__CMD_SEN100H)
bus.write_byte(__DEV_ADDR,__CMD_SEN100L)
bus.write_byte(__DEV_ADDR,__CMD_PWR_OFF)
def getIlluminance():
    bus.write_byte(__DEV_ADDR,__CMD_PWR_ON)
    bus.write_byte(__DEV_ADDR,__CMD_THRES2)
    time.sleep(0.2)
    res=bus.read_word_data(__DEV_ADDR,0)
    #read_word_data
    res=((res>>8)&0xff)|(res<<8)&0xff00
    res=round(res/(2*1.2),2)
    result="光照強度: "+str(res)+"lx"
    return result

測試結果

  • 重啟uwsgi服務
sudo systemctl restart emperor.uwsgi.service

  • 測試

與C語言程式對比

illuminance.c

#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#define I2C_ADDR 0x23
int main(void)
{
    int fd;
    char buf[3];
    char val,value;
    float flight;
    fd=open("/dev/i2c-1",O_RDWR);
    if(fd<0)
    {
        printf("開啟檔案錯誤:%s\r\n",strerror(errno)); return 1;
    }
    if(ioctl( fd,I2C_SLAVE,I2C_ADDR)<0 )
    {
        printf("ioctl 錯誤 : %s\r\n",strerror(errno));return 1;
    }
    val=0x01;
    if(write(fd,&val,1)<0)
    {
        printf("上電失敗\r\n");
    }
    val=0x11;
    if(write(fd,&val,1)<0)
    {
        printf("開啟高解析度模式2\r\n");
    }
    usleep(200000);
    if(read(fd,&buf,3)){
        flight=(buf[0]*256+buf[1])*0.5/1.2;
        printf("光照度: %6.2flx\r\n",flight);
    }
    else{
        printf("讀取錯誤\r\n");
    }
}

結果一樣
c

參考