小熊派+E53_SC1扩展模块,如下所示:
打开board.h文件,找到IIC的配置处,按照其提示配置:
首先,打开【RT-Thread Settings】,开启软件模拟I2C,然后保存使之生效
通过查看原理图,可以知道,其连接到的引脚是I2C1_SDA -> PB7
和I2C1_SCL -> PB6
,将board.h的I2C1的注释打开,并输入对应的引脚:
然后编译烧录下载,在msh下输入list_device
查看一下,可以看到,I2C注册成功
打开【RT-Thread Settings】,点击添加软件包,搜索BH1750,然后点击添加:
保存使之生效后,我们可以看到,bh1750软件包已经添加进来了:
打开sensor_rohm_bh1750.c
,找到bh1750_port()
函数,将其中的I2C修改为我们使用的"i2c1"
然后就可以编译烧录运行了,在msh下输入list_device
查看,bh1750已经注册好了:
然后我们输入命令sensor probe li_bh1750
,将BH1750打开,可以看到,打开成功,然后使用sensor read
命令,可以看到,没有数据
这是因为没有写入环境光照强度打印代码,我们打开\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;
新建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);