简介
使用BearPi IOT Std开发板及其扩展板E53_SC1, SC1上有I2C1 的光照强度传感器BH1750 和 EEPROM AT24C02, 智慧路灯功能, 实现亮度达到对应阈值则开启点灯
主板:
主芯片: STM32L431RCT6
LED : PC13 \ 推挽输出\ 高电平点亮
串口: Usart1
I2C使用 : I2C1
E53_SC1扩展板 :
LED : PB9 \ 推挽输出 \ 高电平点亮
光照强度传感器:BH1750
EEPROM芯片 : AT24C02
当 读取 BH1750 的值达到设定值, 打开LED灯, 低于设定值, 关闭LED灯
电路图原理图一览
扩展板 BH1750
扩展板 LED
步骤
-
创建工程, 初始化I2C, 添加I2C1设备到RT-Thread系统中
参考 BearPi Std 板从入门到放弃 - 先天神魂篇(3)(RT-Thread I2C设备) -
添加用户代码
a. LED灯设定代码
#define SMART_SL_LED_PIN GET_PIN(B, 9)
typedef enum
{
OFF,
ON
}Smart_Streetlights_Status;
void Smart_Sl_LED_Set(Smart_Streetlights_Status status)
{
rt_pin_write(SMART_SL_LED_PIN, status == OFF ? PIN_LOW : PIN_HIGH);
}
b. BH1750 功能代码
rt_err_t smart_sl_bh1750_init(void)
{
uint8_t cmd = 0x11; // 连续读H分辨率模式2
if (RT_NULL == i2c_bus)
{
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(SMART_SL_I2C_NAME); // 获取注册i2c1设备
}
if (RT_NULL == i2c_bus)
{
rt_kprintf("[smart_sl_led_set] get i2c1 device failed!\n");
return -RT_ERROR;
}
if (1 != rt_i2c_master_send(i2c_bus, SMART_SL_BH1750_ADDR, RT_I2C_WR, &cmd, 1)) // 发送指令, 开启连续读模式
{
rt_kprintf("[smart_sl_led_set] send command failed!\n");
return -RT_ERROR;
}
rt_thread_mdelay(180); // 写指令后最长读取等待时间180ms
return RT_EOK;
}
rt_err_t smart_sl_bh1750_read(float *pLux)
{
uint8_t temp[2];
rt_uint8_t recvLength = sizeof(temp)/sizeof(uint8_t);
if (recvLength != rt_i2c_master_recv(i2c_bus, 0x23, RT_I2C_RD, temp, recvLength))
{
return -RT_ERROR;
}
/* 计算光照强度数据 */
*pLux = (float)((temp[0]<<8)|temp[1]);
*pLux /= (float)(1.2);
return RT_EOK;
}
c. 初始化和线程创建部分
rt_err_t smart_sl_init(void)
{
rt_pin_mode(SMART_SL_LED_PIN, PIN_MODE_OUTPUT);
if (RT_EOK == smart_sl_bh1750_init())
{
initialized = 1;
return RT_EOK;
}
return -RT_ERROR;
}
static void smart_sl_entry(void *parameter)
{
float lux = 0.0;
uint16_t fCnt = 0; // 错误次数, 不可原谅次数
uint16_t fMaxTime = 10;
Smart_Streetlights_Status status = OFF;
if (!initialized)
{
if (RT_EOK != smart_sl_init())
{
rt_kprintf("fail to init smart streetlights!\n");
return;
}
}
smart_sl_led_set(OFF);
while (1)
{
rt_thread_mdelay(500); // 500ms 遍历一次
if (RT_EOK != smart_sl_bh1750_read(&lux))
{
fCnt += 1;
if (fCnt >= fMaxTime)
{
rt_kprintf("The BH1750 has read an error more than %d times!\n", fMaxTime);
fCnt -= 1;
}
continue;
}
if (lux > luminosity_threshold)
{
if (status == OFF)
continue;
status = OFF;
}
else
{
if (status == ON)
continue;
status = ON;
}
smart_sl_led_set(status);
rt_kprintf("The current light intensity is %flx, and the LED light is turned %s.\n", lux, status == ON ? "on" : "off");
}
}
static int smart_sl(int argc, char *argv[])
{
rt_thread_t tid;
rt_err_t ret = RT_EOK;
tid = rt_thread_create("smart_sl",
smart_sl_entry,
RT_NULL,
512,
RT_THREAD_PRIORITY_MAX / 3,
20);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
ret = RT_ERROR;
}
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(smart_sl, led sample);
扩展目标
实现 smart_sl on/off [阈值]指令扩展
可以打开/关闭,及设定阈值
代码
完整代码
参考
BearPi Std 板 创建I2C设备的过程