RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据

通过I2C获取BH1750光传感器数据

一、硬件准备

小熊派+E53_SC1扩展模块,如下所示:

二、开启IIC设备

打开board.h文件,找到IIC的配置处,按照其提示配置:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第1张图片
首先,打开【RT-Thread Settings】,开启软件模拟I2C,然后保存使之生效
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第2张图片
通过查看原理图,可以知道,其连接到的引脚是I2C1_SDA -> PB7I2C1_SCL -> PB6,将board.h的I2C1的注释打开,并输入对应的引脚:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第3张图片
然后编译烧录下载,在msh下输入list_device查看一下,可以看到,I2C注册成功
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第4张图片

三、导入BH1750软件包

打开【RT-Thread Settings】,点击添加软件包,搜索BH1750,然后点击添加:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第5张图片
保存使之生效后,我们可以看到,bh1750软件包已经添加进来了:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第6张图片
打开sensor_rohm_bh1750.c,找到bh1750_port()函数,将其中的I2C修改为我们使用的"i2c1"
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第7张图片
然后就可以编译烧录运行了,在msh下输入list_device查看,bh1750已经注册好了:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第8张图片
然后我们输入命令sensor probe li_bh1750,将BH1750打开,可以看到,打开成功,然后使用sensor read命令,可以看到,没有数据
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第9张图片
这是因为没有写入环境光照强度打印代码,我们打开\components\drivers\sensors\sensor_cmd.c,在sensor_show_data函数后面自行增加环境光照强度打印代码:

case RT_SENSOR_CLASS_LIGHT:
        LOG_I("num:%3d, light:%4d.%d, timestamp:%5d", num, sensor_data->data.light / 10, sensor_data->data.light % 10, sensor_data->timestamp);
        break;

然后重新编译烧录运行,可以看到可以读取出数据了:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第10张图片

四、编写应用代码

新建app_bh1750.c文件,创建一个线程,每隔一秒读取一次光照数据,然后将其打印出来,并结合之前的内容:RT-Thread开发之路(4)— MQTT通信,将光照数据发送到EMQ服务器。代码如下:

#include "sensor.h"

/* 定义一个BH1750线程句柄结构体指针 */
static rt_thread_t app_bh1750_thread = RT_NULL;

/* 发布"BH1750_Pub"主题消息函数 */
void BH1750_Publish(char * msg);

char data_buf[32];

static void app_bh1750_thread_entry(void *parameter)
{
    rt_device_t dev = RT_NULL;
    struct rt_sensor_data data;
    rt_size_t res;

    /* 查找系统中的传感器设备 */
    dev = rt_device_find("li_bh1750");
    if (dev == RT_NULL)
    {
        rt_kprintf("Can't find device:li_bh1750\n");
        return;
    }

    /* 以轮询模式打开传感器设备 */
    if (rt_device_open(dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK)
    {
        rt_kprintf("open device failed!");
        return;
    }

    while(1)
    {
        /* 从传感器读取一个数据 */
        res = rt_device_read(dev, 0, &data, 1);
        if (res != 1)
        {
            rt_kprintf("read data failed!size is %d", res);
        }
        else
        {
            rt_kprintf("light:%4d.%d lux \n", (&data)->data.light / 10, (&data)->data.light % 10);
            rt_sprintf(data_buf,"\"light\":%4d.%d lux \n", (&data)->data.light / 10, (&data)->data.light % 10);
            BH1750_Publish(data_buf);
        }
        rt_thread_mdelay(1000);
    }
    /* 关闭传感器设备 */
    rt_device_close(dev);
}

static int app_bh1750_init(void)
{
    rt_err_t rt_err;

    /* 创建BH1750线程*/
    app_bh1750_thread = rt_thread_create("app_bh1750 thread",
            app_bh1750_thread_entry, RT_NULL, 2048, 6, 10);
    /* 如果获得线程控制块,启动这个线程 */
    if (app_bh1750_thread != RT_NULL)
        rt_err = rt_thread_startup(app_bh1750_thread);
    else
        rt_kprintf("app_bh1750_thread create failure !!! \n");

    /* 判断线程是否启动成功 */
    if( rt_err == RT_EOK)
        rt_kprintf("app_bh1750_thread startup ok. \n");
    else
        rt_kprintf("app_bh1750_thread startup err. \n");

    return rt_err;
}

INIT_APP_EXPORT(app_bh1750_init);


另外修改过的app_mqtt.c文件如下:

#include 
#include 
#include 
#include 
#include "netdb.h"
#include 
#include 
#include 
#include "paho_mqtt.h"

#define MQTT_Uri    "tcp://39.96.35.207:1883"   // MQTT服务器的地址和端口号
#define ClientId    "BearPi8266"                // ClientId需要唯一
#define UserName    "BearPi"                    // 用户名
#define PassWord    "123456"                    // 用户名对应的密码

/* 定义一个MQTT线程句柄结构体指针 */
static rt_thread_t app_mqtt_thread = RT_NULL;

/* 定义一个MQTT客户端结构体 */
static MQTTClient client;

/* 标识MQTT是否启动成功 */
static int is_started = 0;

/* 发布"BH1750_Pub"主题函数 */
void BH1750_Publish(char * msg)
{
    if(is_started == 1)
        paho_mqtt_publish(&client, QOS1, "BH1750_Pub", msg);
}

/* 收到订阅的"Bear_Pi"主题的消息时的回调函数*/
static void mqtt_sub_callback(MQTTClient *c, MessageData *msg_data)
{
    *((char *)msg_data->message->payload + msg_data->message->payloadlen) = '\0';
    rt_kprintf("Receive topic: %.*s, message data:\r\n", msg_data->topicName->lenstring.len, msg_data->topicName->lenstring.data);
    rt_kprintf("%.*s\r\n", msg_data->message->payloadlen, (char *)msg_data->message->payload);
}

/* 默认的订阅回调函数,如果有订阅的 Topic 没有设置回调函数,则使用该默认回调函数 */
static void mqtt_sub_default_callback(MQTTClient *c, MessageData *msg_data)
{
    *((char *)msg_data->message->payload + msg_data->message->payloadlen) = '\0';
    rt_kprintf("Receive topic: %.*s, message data:\r\n", msg_data->topicName->lenstring.len, msg_data->topicName->lenstring.data);
    rt_kprintf("%.*s\r\n", msg_data->message->payloadlen, (char *)msg_data->message->payload);
}

/* 连接成功回调函数 */
static void mqtt_connect_callback(MQTTClient *c)
{
    rt_kprintf("mqtt connect success! \r\n");
}

/* 上线回调函数 */
static void mqtt_online_callback(MQTTClient *c)
{
    rt_kprintf("mqtt online \r\n");
    paho_mqtt_publish(&client, QOS1, "BH1750_Pub", "Hello, I am BearPi with RT_Thread.");
}

/* 下线回调函数 */
static void mqtt_offline_callback(MQTTClient *c)
{
    rt_kprintf("mqtt offline \r\n");
}

static void app_mqtt_thread_entry(void *parameter)
{
    //int count = 1;
    //char msg_buf[128];
    /* 对MQTT客户端结构体变量进行配置 */
    client.isconnected = 0;
    client.uri = MQTT_Uri;

    /* 配置MQTT的连接参数 */
    MQTTPacket_connectData condata = MQTTPacket_connectData_initializer;
    memcpy(&client.condata, &condata, sizeof(condata));
    client.condata.clientID.cstring = ClientId;
    client.condata.keepAliveInterval = 30;
    client.condata.cleansession = 1;
    client.condata.username.cstring = UserName;
    client.condata.password.cstring = PassWord;

    /* 为mqtt申请内存 */
    client.buf_size = client.readbuf_size = 1024;
    client.buf = rt_calloc(1, client.buf_size);
    client.readbuf = rt_calloc(1, client.readbuf_size);
    if (!(client.buf && client.readbuf))
    {
        rt_kprintf("no memory for MQTT client buffer!\r\n");
        return ;
    }

    /* 设置回调函数  */
    client.connect_callback = mqtt_connect_callback;
    client.online_callback = mqtt_online_callback;
    client.offline_callback = mqtt_offline_callback;

    /* 订阅一个主题,并设置其回调函数 */
    client.messageHandlers[0].topicFilter = rt_strdup("BH1750_Sub");
    client.messageHandlers[0].callback = mqtt_sub_callback;
    client.messageHandlers[0].qos = QOS1;

    /* 设置默认的回调函数 */
    client.defaultMessageHandler = mqtt_sub_default_callback;

    /* 启动 mqtt client */
    paho_mqtt_start(&client);

    is_started = 1;

    while(1)
    {
        //rt_sprintf(msg_buf, "publish %d times.", count++);
        //paho_mqtt_publish(&client, QOS1, "BearPi_Pub", msg_buf);
        rt_thread_mdelay(1000);
    }
}

static int app_mqtt_init(void)
{
    rt_err_t rt_err;
    /* 创建MQTT线程*/
    app_mqtt_thread = rt_thread_create("app_mqtt thread",
            app_mqtt_thread_entry, RT_NULL, 2048, 6, 10);
    /* 如果获得线程控制块,启动这个线程 */
    if (app_mqtt_thread != RT_NULL)
        rt_err = rt_thread_startup(app_mqtt_thread);
    else
        rt_kprintf("app_mqtt_thread create failure !!! \n");

    /* 判断线程是否启动成功 */
    if( rt_err == RT_EOK)
        rt_kprintf("app_mqtt_thread startup ok. \n");
    else
        rt_kprintf("app_mqtt_thread startup err. \n");

    return rt_err;
}

INIT_APP_EXPORT(app_mqtt_init);

编译烧录运行,可以看到,运行成功:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第11张图片

然后再MQTT上也接收到了数据:
RT-Thread开发之路(6)— 通过I2C获取BH1750光传感器数据_第12张图片

你可能感兴趣的:(RT-Thread)