7. NodeMCU上使用RTOS固件读取bh1750传感器数据的实践

来源:互联网 发布:js遍历json对象数组 编辑:程序博客网 时间:2024/05/01 04:00

NodeMCU上使用RTOS固件读取bh1750传感器数据的实践


本文主要是尝试在NodeMCU(硬件)上,使用RTOS(固件、OS)来控制bh1750光照传感器,
采集亮度数据。

关于RTOS固件的编译环境和编译方式的介绍,可参照之前的文章。
ESP8266固件的编译5(RTOS SDK固件)

但是在RTOS固件下,只内置了很少的传感器驱动,bh1750并没有被支持。
需要自己根据I2C协议实现简单的驱动。
(nodeMCU的lua固件预置了相当多的、也包含bh1750的传感器驱动,
作为参考,可参照lua版本的驱动实现 nodemcu-firmware/lua_modules)

bh1750通信通过I2C协议,关于I2C协议本身,可以参照如下文章,有清晰的解释。
http://blog.chinaunix.net/uid-25906157-id-3585430.html

1、I2C驱动库的编译

Esp8266没有硬件I2C接口,是用GPIO软件模拟的,坏处是性能差,好在模拟也不复杂。
RTOS固件开发环境下提供了一个Driver库,内置I2C、SPI、UART等通信实现。
第一步自然是编译这个库。

编译过程中,出现一些问题,应该是维护人员的粗心所致。要如下方法修改:
进入ESP8266_RTOS_SDK\driver_lib\driver目录,如下修正i2c_master.c文件。
1) 增加头文件

#include "c_types.h"#include "esp8266/ets_sys.h"#include "esp8266/eagle_soc.h" /* 新增加头文件 */#include "esp8266/gpio_register.h" /* 新增加头文件 */#include "gpio.h"

2) 修改宏/函数名
在i2c_master_gpio_init函数中,将

ETS_GPIO_INTR_DISABLE() ;ETS_GPIO_INTR_ENABLE() ;

修改为

 ETS_INTR_LOCK(); ETS_INTR_UNLOCK();

3)默认的SDA和SCL管脚定义
默认的I2C的SDA和SCL管脚在i2c_master.h中定义,其默认值为

SDA -- GPIO2SCL -- GPIO4

需要变更的话,可修改此文件。

4)编译
在ESP8266_RTOS_SDK\driver_lib目录下,执行

$ make_lib.sh driver

成功编译成功后,在ESP8266_RTOS_SDK/lib目录下会生成新的libdriver.a。
执行如下命令,能找到i2c对应函数的符号信息。

$nm –A libdriver.a | grep i2c

2、 bh1750驱动的实现

仿照lua版,只实现了【连续 H 分辨率模式】下的数据读取。

Bh1750的I2C接口的说明:

A)Slave地址有 2 种形式,由 ADDR 端口决定。

ADDR=“H” ( ADDR ≧ 0.7VCC ) →“1011100ADDR=“L” ( ADDR ≦ 0.3VCC ) →“0100011

B)bh1750的I2C数据读取协议,如图

这里写图片描述

C)简单实现如下(错误处理等省略)

uint8 addr = 0x23; // bh1750 i2c地址(low) 00100011uint8 cmd = 0x10; // bh1750 高分辨率模式 00010000void init_bh1750(){    // 初始化i2c总线    i2c_master_gpio_init();}uint16 read_bh1750_data(void){    uint8 b1 = 0x00;    uint8 b2 = 0x00;    uint32 data = 0x00;    // 设置高分辨率模式    i2c_master_start();    i2c_master_writeByte( (addr << 1) );    i2c_master_getAck();    i2c_master_writeByte(cmd);    i2c_master_getAck();    i2c_master_stop();    // 采集等待时间要求120ms以上    os_delay_us(60000);    os_delay_us(60000);    os_delay_us(60000);    // 读取数据    i2c_master_start();    i2c_master_writeByte( (addr << 1) | 0x01 );    i2c_master_getAck();    b1 = i2c_master_readByte();    i2c_master_send_ack();    b2 = i2c_master_readByte();    i2c_master_send_ack();    i2c_master_stop();    // 计算结果(取得亮度数据为2字节、除1.2的阈值)    data = b1 * 256 + b2;    return (uint16)(data / 1.2);}

3. 固件入口函数user_init的实现

修改ESP8266_RTOS_SDK\examples\project_template\user\ user_main.c文件
(上面的bh1750驱动实现也可放在此文件中)

因为RTOS不允许在user_init中进行while(1)循环和睡眠等待,
因此用定时器来定时读取lux数据(也可以创建task)。代码如下:

LOCAL void ICACHE_FLASH_ATTR print_data(void* data){    printf("lux: %d\n", read_bh1750_data());}void user_init(void){    int i = 0;    // 设置串口为 115200 波特率。不设的情况,默认波特率为78400    UART_ConfigTypeDef  uart_config;    uart_config.baud_rate               =   BIT_RATE_115200;    uart_config.data_bits               =   UART_WordLength_8b;    uart_config.parity                  =   USART_Parity_None;    uart_config.stop_bits               =   USART_StopBits_1;    uart_config.flow_ctrl               =   USART_HardwareFlowControl_None;    uart_config.UART_RxFlowThresh       =   120;    uart_config.UART_InverseMask        =   UART_None_Inverse;    UART_ParamConfig(UART0, &uart_config);    printf("----------------------\n");    printf("bh1750 reader\n");    printf("----------------------\n");    // 初始化I2C    init_bh1750();    // 设置定时器    os_timer_disarm(&timer);    os_timer_setfn(&timer, (os_timer_func_t *)print_data, NULL);    os_timer_arm(&timer, 2000, 1);}

4. 固件编译

进入ESP8266_RTOS_SDK\examples\project_template目录,执行

make COMPILE=gcc BOOT=none APP=0 SPI_SPEED=40 SPI_MODE=DIO SPI_SIZE_MAP=4

如编译成功,则在BIN_PATH下会生成固件。

5.结果验证

1)接线
esp8266默认的GPIO定义和nodemcu的D管脚定义是不同的体系,使用nodemcu硬件是要注意。
直接用esp8266模块的话,根据gpio号接线就可以。

可参照下图:
这里写图片描述

接线如下:

SDA(bh1750) ---- D4(nodeMCU) ---- GPIO2(esp8266)SCL(bh1750) ---- D2(nodeMCU) ---- GPIO4(esp8266)VCC(bh1750) ---- 3.3vGND(bh1750) ---- GND(nodeMCU)ADDR(bh1750) ---- GND (使用bh1750的0x23地址)

接线效果图

这里写图片描述
2)固件下载
可参照以前的文章
" target="_blank">ESP8266固件的编译6(固件的下载)

3) 效果
用串口工具115200波特率连接nodeMCU硬件,
可以看到bh1750的数据被正常采集,且亮度能随场景变化而不同。
这里写图片描述

原创粉丝点击