ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)

一、硬件简介

光照强度传感器使用的是物联网俱乐部的智慧路灯案例扩展板E53_SC1,购买连接 https://item.taobao.com/item.htm?spm=2013.1.w4004-22244473698.13.354f7535sH8LBt&id=607877846499
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第1张图片
ESP32开发板使用的是本人自己设计的带E53传感器接口的 EVB ,全部设计资料链接:https://blog.csdn.net/wanglichao1989/article/details/122021795?spm=1001.2014.3001.5501

硬件安装完如下图:
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第2张图片

二、创建ESP-IDF Eclipse工程

参考我之前的ESP-IDF搭建教程https://blog.csdn.net/wanglichao1989/article/details/122026138?spm=1001.2014.3001.5501,完成搭建后桌面会生成一个 ESP-IDF Eclipse快捷方式,双击打开,如下图所示:
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第3张图片
然后新建一个名称为E53_SC1_demo的工程,并点击进入下一步:
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第4张图片
然后点击Finish完成创建,这里你也可以选择基于某个IDF模板来创建工程,比如,hello_world
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第5张图片
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第6张图片

三、编写 E53_SC1模块驱动

首先我们在上面创建的E53_SC1_demo工程里面创建一个component,步骤如下:菜单栏点击File-New按下图所示新建模块
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第7张图片
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第8张图片
点击finish后会在工程里生成新的组件E53_SC1.c E53_SC1.h文件,我们可以在这里编写模块驱动。

从第一个章节硬件介绍中,我们知道E53_SC1扩展模块有一个 BH1750光照传感器和一个高亮LED组成,其中高亮LED采取GPIO控制,BH1750采用IIC总线控制。

这里我们编写相应的驱动
使用到的GPIO初始化参考: https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32c3/api-reference/peripherals/gpio.html
使用到的IIC驱动参考:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32c3/api-reference/peripherals/i2c.html

E53_SC1.c 文件源代码如下:

#include 
#include "E53_SC1.h"
#include "esp_log.h"
#include "driver/i2c.h"

int I2C_Init(void)
{
	int i2c_master_port = E53_SC1_I2C_NUM;
	i2c_config_t conf = {
	    .mode = I2C_MODE_MASTER,
	    .sda_io_num = E53_SC1_SDA_IO,         // select GPIO specific to your project
	    .sda_pullup_en = GPIO_PULLUP_ENABLE,
	    .scl_io_num = E53_SC1_SCL_IO,         // select GPIO specific to your project
	    .scl_pullup_en = GPIO_PULLUP_ENABLE,
	    .master.clk_speed = E53_SC1_I2C_FREQ_HZ,  // select frequency specific to your project
	    // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
	};
    i2c_param_config(i2c_master_port, &conf);
    return i2c_driver_install(i2c_master_port, conf.mode, E53_SC1_I2C_RX_BUF_DISABLE, E53_SC1_I2C_TX_BUF_DISABLE, 0);
}


int BH1750_I2C_Master_Transmit(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(E53_SC1_I2C_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

int BH1750_I2C_Master_Receive(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(E53_SC1_I2C_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}


void Init_BH1750(void)
{
    uint8_t data;
    I2C_Init();
    data = BH1750_PWR_ON;
    BH1750_I2C_Master_Transmit(BH1750_SLAVE_ADDR, NULL, &data, 1);
    data = BH1750_CON_H;
    BH1750_I2C_Master_Transmit(BH1750_SLAVE_ADDR, NULL, &data, 1);
}


void Init_Light(void)
{
	gpio_pad_select_gpio(E53_SC1_LED_IO);// 选择要操作的GPIO
	gpio_set_direction(E53_SC1_LED_IO, GPIO_MODE_OUTPUT);// 设置GPIO为推挽输出模式
	gpio_set_level(E53_SC1_LED_IO, 0);// GPIO输出低

}

void Init_E53_SC1(void)
{
	Init_Light();
	Init_BH1750();
}

void E53_SC1_Read_Data(void)
{

    float lux = 0.0;
    uint8_t sensorData[2] = {0};
    BH1750_I2C_Master_Receive(BH1750_SLAVE_ADDR, NULL, sensorData, 2);
    lux = (sensorData[0] << 8 | sensorData[1]) / 1.2;
	E53_SC1_Data.Lux=lux;

}

void E53_SC1_LED_StatusSet(E53_SC1_Status_ENUM status)
{
  if(status == ON)
	  gpio_set_level(E53_SC1_LED_IO, 1);
  else
	  gpio_set_level(E53_SC1_LED_IO, 0);
}

E53_SC1. h文件源代码如下:

#ifndef __E53_SC1_H__
#define __E53_SC1_H__


#define E53_SC1_SCL_IO GPIO_NUM_8
#define E53_SC1_SDA_IO GPIO_NUM_9
#define E53_SC1_I2C_NUM I2C_NUM_0
#define E53_SC1_I2C_FREQ_HZ 100000
#define E53_SC1_I2C_TX_BUF_DISABLE 0
#define E53_SC1_I2C_RX_BUF_DISABLE 0

#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 E53_SC1_LED_IO GPIO_NUM_5


typedef struct
{
		float    Lux;
} E53_SC1_Data_TypeDef;

extern E53_SC1_Data_TypeDef E53_SC1_Data;

typedef enum
{
	OFF = 0,
	ON
} E53_SC1_Status_ENUM;


#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模式

void Init_E53_SC1(void);
void E53_SC1_Read_Data(void);
void E53_SC1_LED_StatusSet(E53_SC1_Status_ENUM status);

#endif

然后在main.c里面添加如下代码

  1. 头文件及声明
#include "E53_SC1.h"

E53_SC1_Data_TypeDef E53_SC1_Data;
  1. app_main函数中添加模块初始化和传感数据读取代码

    E53_SC1_Status_ENUM level = ON;
    Init_E53_SC1();
    E53_SC1_LED_StatusSet(OFF);
    while (true) {
        printf("I am E53_SC1 Demo Task,count is %d\r\n",count++);
        E53_SC1_Read_Data();
        printf("\r\n********E53_SC1_BH1750 Value is  %d\r\n",(int)E53_SC1_Data.Lux);
        E53_SC1_LED_StatusSet(level);
        level = !level;
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }

四、测试运行

完成代码编辑后在Eclipse IDE中设置芯片型号,串口
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第9张图片
完成后对工程进行编译
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第10张图片
然后连接好开发板,选择好串口,按照如下图所示下载程序到开发板:
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第11张图片
下载完成后,打开串口助手,可以看到开发板上E53_SC1模块的高亮LED闪烁,同时串口助手打印光照强度值:
ESP32-C3学习笔记(3):ESP32 C3 IIC总线驱动光照强度传感器(基于ESP-IDF Eclipse)_第12张图片

你可能感兴趣的