锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

ESP32学习笔记(18)——光强度GY-30(BH1750)使用

时间:2023-07-23 15:37:00 光强度传感器bh1750fvi

一、简介

BH1750FVI 它是一种用于两线串行总线接口的数字光强度传感器集成电路。该集成电路可根据收集的光强数据调整液晶或键盘背景灯的亮度。利用其高分辨率,可以探测到大范围的光强度变化。

传感器特点:

  • 支持I2CBUS接口
  • 接近视觉灵敏度的光谱灵敏度特征
  • 输出相应亮度的数字值
  • 对应广泛的输入光范围。(相当于1-65535lx)
  • 通过降低功率功能,实现低电流化。
  • 通过50Hz/60Hz实现除光噪声功能的稳定测定。
  • 支持1.8v逻辑输入接口。
  • 没有其他外部部件。
  • 光源依赖性弱。
  • 有两种选择I2Cslave地址。
  • 影响可调测量结果的因素是光入口大小。
  • 使用此功能计算1.1lx到100000lx马克斯/分钟范围。
  • 最小误差变化在±20%。
  • 受红外线影响很小。

1.1 测量程序步骤

1.2 指令集合

1.3 说明测量模式

二、硬件连接

功能口 引脚
SCL GPIO23
SDA GPIO18
ADDR ADDR ≥ 0.7VCC 从机地址为1011100
ADDR ≤ 0.3VCC 0100011从机地址

三、添加I2C驱动

查看 ESP32学习笔记(17)——I2C接口使用

四、I2C通信流程

测量结果为2字节(高字节) High Byte 和低字节 Low Byte)计算公式为:

光强(单位)lx)=(High Byte Low Byte)/ 1.2

五、ESP32作为主机与BH1750光强传感器通信

连续高分辨率模式

I2C_Init()初始化I2C后

BH1750_Init()配置BH1750连续高分辨率模式

BH1750_ReadLightIntensity()获取光强度

#include  #include "esp_log.h" #include "driver/i2c.h"  static const char *TAG = "i2c-example";  #define I2C_MASTER_SCL_IO GPIO_NUM_23 /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO GPIO_NUM_18 /*!< gpio number for I2C master data */ #define I2C_MASTER_NUM 1 /*!< I2C port number for master dev */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */  #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */

#define BH1750_SLAVE_ADDR 0x23 // 从机地址
#define BH1750_PWR_DOWN 0x00 // 关闭模块
#define BH1750_PWR_ON 0x01 // 打开模块等待测量指令
#define BH1750_RST 0x07 // 重置数据寄存器值在PowerOn模式下有效
#define BH1750_CON_H 0x10 // 连续高分辨率模式,1lx,120ms
#define BH1750_CON_H2 0x11 // 连续高分辨率模式,0.5lx,120ms
#define BH1750_CON_L 0x13 // 连续低分辨率模式,4lx,16ms
#define BH1750_ONE_H 0x20 // 一次高分辨率模式,1lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_H2 0x21 // 一次高分辨率模式,0.5lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_L 0x23 // 一次低分辨率模式,4lx,16ms,测量后模块转到PowerDown模式

SemaphoreHandle_t print_mux = NULL;

/** @brief I2C驱动初始化 @param 无 @return 无 */
int I2C_Init(void)
{ 
        
    int i2c_master_port = I2C_MASTER_NUM;
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_IO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_MASTER_SCL_IO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    i2c_param_config(i2c_master_port, &conf);
    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

/** @brief I2C写数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 写入数据 @param dataLen -[in] 写入数据长度 @return 错误码 */
int I2C_WriteData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slaveAddr << 1) | WRITE_BIT, ACK_CHECK_EN);
    if(NULL != regAddr)
    { 
        
        i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
    }
    i2c_master_write(cmd, pData, dataLen, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(1, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

/** @brief I2C读数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 读出数据 @param dataLen -[in] 读出数据长度 @return 错误码 */
int I2C_ReadData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slaveAddr << 1) | READ_BIT, ACK_CHECK_EN);
    if(NULL != regAddr)
    { 
        
        i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
    }
    i2c_master_read(cmd, pData, dataLen, ACK_VAL);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(1, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

/** @brief BH1750初始化函数 @param 无 @return 无 */
void BH1750_Init(void)
{ 
        
    uint8_t data;
    data = BH1750_PWR_ON;              // 发送启动命令
    I2C_WriteData(BH1750_SLAVE_ADDR, NULL, &data, 1);
    data = BH1750_CON_H;               // 设置连续高分辨率模式,1lx,120ms
    I2C_WriteData(BH1750_SLAVE_ADDR, NULL, &data, 1);
}

/** @brief BH1750获取光强度 @param 无 @return 光强度 */
float BH1750_ReadLightIntensity(void)
{ 
        
    float lux = 0.0;
    uint8_t sensorData[2] = { 
        0};
    I2C_ReadData(BH1750_SLAVE_ADDR, NULL, sensorData, 2);
    lux = (sensorData[0] << 8 | sensorData[1]) / 1.2;
    return lux;
}

static void i2c_test_task(void *arg)
{ 
        
    int cnt = 0;
    float lux;
    
    BH1750_Init();
    vTaskDelay(180 / portTICK_RATE_MS); // 设置完成后要有一段延迟

    while (1) { 
        
        ESP_LOGI(TAG, "test cnt: %d", cnt++);
        lux = BH1750_ReadLightIntensity();
        xSemaphoreTake(print_mux, portMAX_DELAY);
        printf("sensor val: %.02f [Lux]\n", lux);
        xSemaphoreGive(print_mux);
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
    vSemaphoreDelete(print_mux);
    vTaskDelete(NULL);
}

void app_main(void)
{ 
        
    print_mux = xSemaphoreCreateMutex();
    ESP_ERROR_CHECK(I2C_Init());
    xTaskCreate(i2c_test_task, "i2c_test_task_0", 1024 * 2, NULL, 10, NULL);
}

查看打印:


• 由 Leung 写于 2021 年 5 月 14 日

• 参考:BH1750FVI光强度传感器及其STM32驱动程序
    BH1750 STM32 驱动程序

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章