780|2

324

帖子

4

TA的资源

纯净的硅(中级)

楼主
 

【nRF7002-DK Wi-Fi® 6开发套件评测】接入开发板到node-red控制板载LED [复制链接]

nRF7002-DK联网功能一级棒,在SDK中,还提供了mqtt连接的模块,这篇分享,就基于mqtt,将nRF7002-DK接入到node-red系统,实现在nod-red中控制板载的两个LED。

 

一、nRF7002-DK接入到mqtt服务

1. 从mqtt样例新建工程:

在VSCode的nRF Connect插件界面中,可以直接创建一个新的程序,模版使用样例:

 

有好几个mqtt样例,这里直接选择第一个即可: 

 

添加完成,就会自动打开新建的工程:

 

2. 配置修改:

要让这个工程,能够为nRF7002-DK所用,需要做一些配置处理。

1) 首先,先打开dts文件,看一下led的定义:

文件:/opt/nordic/ncs//v2.5.0/nrf/boards/arm/nrf7002dk_nrf7001_nrf5340/nrf7002dk_nrf7001_nrf5340_cpuapp.dts

led定义:

    aliases {
        led0 = &led0;
        led1 = &led1;
        sw0 = &button0;
        sw1 = &button1;
        bootloader-led0 = &led0;
    };

从上述dts中可以看到,nRF7002-DK定义了两个led,命名为led0、led1

 

2) 在prj.conf中开启GPIO,并设置WIFI连接信息

文件:prj.conf

# WiFi
CONFIG_WIFI_CREDENTIALS_STATIC_SSID="OpenBSD"
CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="********"
CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_PSK=y

# GPIO
CONFIG_GPIO=y

 

3) 配置Kconfig:

文件:src/modules/transport/Kconfig.transport

config MQTT_SAMPLE_TRANSPORT_BROKER_HOSTNAME
	string "MQTT broker hostname"
	default "192.168.1.15"

config MQTT_SAMPLE_TRANSPORT_BROKER_USERNAME
	string "MQTT broker username"
	default "test"

config MQTT_SAMPLE_TRANSPORT_BROKER_PASSWORD
	string "MQTT broker password"
	default "********"

config MQTT_SAMPLE_TRANSPORT_PUBLISH_TOPIC
	string "MQTT publish topic"
	default "device/report"

config MQTT_SAMPLE_TRANSPORT_SUBSCRIBE_TOPIC
	string "MQTT subscribe topic"
	default "device/cmd"

在上述配置中,定义了mqtt服务的地址、用户名、密码,以及用于发布消息对应的topic:device/report,和接受命令对应的topic:device/cmd

在开发板上,通过mqtt发送消息出去,那么就发送到了 设备MAC/device/report

在开发板上,通过mqtt祸首命令消息,那么就要订阅 设备MAC/device/cmd

 

4) 修改sdk源码

sdk中,mqtt连接部分,之列把password留空了,不知道咋想的。好在提供了源码,我们可以自己修改。

文件:/opt/nordic/ncs/v2.5.0/nrf/include/net/mqtt_helper.h

struct mqtt_helper_conn_params {
	/* The hostname must be null-terminated. */
	struct mqtt_helper_buf hostname;
	struct mqtt_helper_buf device_id;
	struct mqtt_helper_buf user_name;
	struct mqtt_helper_buf password; // 新增的部分
};

 

文件:/opt/nordic/ncs/v2.5.0/nrf/subsys/net/lib/mqtt_helper/mqtt_helper.c

static int client_connect(struct mqtt_helper_conn_params *conn_params)
{
	int err;
	struct mqtt_utf8 user_name = {
		.utf8 = conn_params->user_name.ptr,
		.size = conn_params->user_name.size,
	};

	// 新增的部分-开始
	struct mqtt_utf8 password = {
		.utf8 = conn_params->password.ptr,
		.size = conn_params->password.size,
	};
	// 新增的部分-结束
	
	...
	
	mqtt_client.user_name	        = conn_params->user_name.size > 0 ? &user_name : NULL;
	// 新增的部分-开始
	mqtt_client.password	        = conn_params->password.size > 0 ? &password : NULL;
	// 新增的部分-结束
	
	...
	
}

在上述代码中,添加password的定义,并在实际发送参数给mqtt服务的时候,带上传入参数的password

 

5) 修改工程源码

首先修改文件: src/modules/sampler/sampler.c

#define FORMAT_STRING "Board is ready, uptime is: %d"

然后修改核心处理文件:src/modules/transport/transport.c

// GPIO头文件
#include <zephyr/drivers/gpio.h>

// LED定义
#define LED1_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);

#define LED2_NODE DT_ALIAS(led1)
static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);

// LED状态
static uint8_t status1 = 0;
static uint8_t status2 = 0;

static void on_mqtt_publish(struct mqtt_helper_buf topic, struct mqtt_helper_buf payload)
{
	LOG_INF("Received payload: %.*s on topic: %.*s", payload.size,
							 payload.ptr,
							 topic.size,
							 topic.ptr);

	// 检查收到的指令
	payload.ptr[payload.size] = '\0';
	if(strcmp(payload.ptr, "LED1ON") == 0 ) {
		LOG_INF("led1: ON");
		status1 = 1;
	}
	else if(strcmp(payload.ptr, "LED1OFF") == 0 ) {
		LOG_INF("led1: OFF");
		status1 = 0;
	}
	else if(strcmp(payload.ptr, "LED2ON") == 0 ) {
		LOG_INF("led2: ON");
		status2 = 1;
	}
	else if(strcmp(payload.ptr, "LED2OFF") == 0 ) {
		LOG_INF("led2: OFF");
		status2 = 0;
	}
	else if(strcmp(payload.ptr, "LEDON") == 0 ) {
		LOG_INF("led1~2: ON");
		status1 = 1;
		status2 = 1;
	}
	else if(strcmp(payload.ptr, "LEDOFF") == 0 ) {
		LOG_INF("led1~2: OFF");
		status1 = 0;
		status2 = 0;
	}
	gpio_pin_set_dt(&led1, status1);
	gpio_pin_set_dt(&led2, status2);
}


static void transport_task(void)
{
    // 此处为添加的代码-开始
	// LED设备初始化
	int ret;

	if (!gpio_is_ready_dt(&led1)) {
		LOG_ERR("led1 is not ready");
		return;
	}

	if (!gpio_is_ready_dt(&led2)) {
		LOG_ERR("led2 is not ready");
		return;
	}

	ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		LOG_ERR("led1 configure, error: %d", ret);
		return;
	}

	ret = gpio_pin_configure_dt(&led2, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		LOG_ERR("led2 configure, error: %d", ret);
		return;
	}

	// 默认关闭
	status1 = 0;
	status2 = 0;
	gpio_pin_set_dt(&led1, status1);
	gpio_pin_set_dt(&led2, status2);
    // 此处为添加的代码-结束
}

 

以上代码,实在原有演示代码的基础上进行添加的。

主要添加的内容包括:

  • 添加gpio头文件
  • 定义LED1、LED2,分别对应dts中定义的led0、led1
  • 在 on_mqtt_publish() 中,收到消息后,检查是否对应的控制指令
  • 在 transport_task() 中,进行GPIO LED设备的初始化

控制指令具体对应关系如下:

  • LED1ON:打开LED1(对应dts-led0)
  • LED1OFF:关闭LED1(对应dts-led0)
  • LED2ON:打开LED2(对应dts-led1)
  • LED2OFF:关闭LED2(对应dts-led1)
  • LEDON:打开两个LED
  • LEDOFF:关闭两个LED

 

 

3. 编译测试

编译上述代码并下载到nRF7002-DK开发板:

 

 

下载完成后,使用串口监听工具监听,可以看到下面的输出信息:

 

从上述输出可以看到,实际订阅的topic为:F4CE360026BC/device/cmd,那么上报消息对应的topic为:F4CE360026BC/device/report

根据不同的开发板,这里的 设备MAC地址前缀,是不同的。

 

4) 使用mqttf客户端接受消息和下发控制指令

首先订阅 F4CE360026BC/device/report 主题,以便接受消息。

然后给 F4CE360026BC/device/cmd 发送控制指令:

 

在串口监听工具中,也可以看到输出:

 

同时,开发板上的LED,会跟随控制指令点亮或者熄灭。

 

二、nRF7002-DK接入node-red平台

nRF7002-DK要接入node-red平台,本质是在node-red平台上,与对应的控制nRF7002-DK的mqtt的topic关联起来,从而实现在node-red上,通过mqtt控制nRF7002-DK。

 

1. 安装node-red

我是在鲁班猫上安装node-red的,具体步骤如下:

sudo apt update
sudo apt install npm
node -v
npm -v

# 配置国内镜像
npm config set registry http://mirrors.cloud.tencent.com/npm/
npm config get registry

# 建立工作目录
mkdir mkdir ~/Projects/node-red/node_modules
cd ~/Projects/node-red

# 安装node-red
npm install --unsafe-perm node-red
export PATH=/home/cat/Projects/node-red/node_modules/.bin:$PATH

# 启动出错,版本太低,至少要node 14
node-red

但是,运行的时候,居然出错了:

 

 

经过查找资料,确定是nodejs版本太低,至少需要nodejs 14才可以运行。

 

鲁班猫使用的是Ubuntu 22.04系统,使用nvm可以很方便的管理nodejs版本,下面就使用nvm来安装nodejs 14.

# 安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
vim ~/.bashrc_nvm

# 使用nvm安装stable版本node
. ~/.bashrc_nvm
nvm install 14
nvm use 14
node -v
npm -v

# 重新安装:务必删除了,重新安装
rm -rf node_modules
npm install --unsafe-perm node-red
export PATH=/home/cat/Projects/node-red/node_modules/.bin:$PATH

# 启动
node-red

需要注意的是,一定要把原有的node_modules目录删除了,重新进行,分则可能运行node-red的时候出现段错误。

安装完成,启动node-red,输出信息如下:

 

2. node-red中文设置

 

 

设置完成后,要刷新一下界面,才会变为中文界面。

 

3. 安装dashboard

要在界面上显示按钮,点击按钮时产生操作,需要安装dashboard界面ui模块,具体如下:

 

 

4. 添加按钮

在左边搜索button,然后依次添加6个按钮,对应如下:

 

并依次设置每个按钮:

 

5. 设置mqtt

在左边搜索mqtt,添加mqtt out,用于发送mqtt指令。

 首次添加mqtt节点的时候,需要添加mqtt服务器的配置。 

 

6. 关联按钮到mqtt

从按钮尾部拉线到mqtt节点即可,将所有的按钮都连接到刚才添加的mqtt out节点:

 

7. 添加UI界面:

在按钮配置界面的Group中,添加新的Tab和Group:

 

然后从右上角的小箭头,选择dashboard,进入界面排版设置:

 

在该界面,可以拖动按钮节点的位置,从而实现最终的按钮顺序:

 

8. 部署查看

设置完成后,点击右上角的部署按钮:

 

 

如果提示有的按钮设置不正确,需要依次点进去,设置好对应的Group即可。

 

正确无误部署好,打开浏览器:  http://node-red服务器ip:1880/ui 即可查看基础的UI界面:

 

在该界面上,点击对应的按钮,开发板会收到对应的控制指令,并进行LED的控制:

  

三、总结

只要将nRF7002-DK接入了mqtt服务,那就相当于是给一座孤岛通上了网络,从此可以方便的和外界发生联系了。

在这片分享中,使用node-red这个低代码IoT平台,来实现简单快捷的接入nRF7002-DK,并实现通过界面按钮,来控制板载LED。

当然,这里只是一个基础的展示,还可以在nRF7002-DK上接入传感器,读取传感器的数值,并通过mqtt发布出去,例如使用温湿度传感器获取环境数据,mqtt发布后,node-red可以收到,并在界面上进行呈现,从而实现更丰富的功能和界面了。

此帖出自RF/无线论坛

最新回复

楼主的分享十分有用,先收藏起来,慢慢学习,非常感谢楼主的无私奉献   详情 回复 发表于 2023-12-15 23:17
点赞 关注
 

回复
举报

755

帖子

5

TA的资源

纯净的硅(高级)

沙发
 

楼主的分享十分有用,先收藏起来,慢慢学习,非常感谢楼主的无私奉献

此帖出自RF/无线论坛

点评

好东西,就是要一起分享  详情 回复 发表于 2023-12-16 21:14
 
 

回复

324

帖子

4

TA的资源

纯净的硅(中级)

板凳
 
chejm 发表于 2023-12-15 23:17 楼主的分享十分有用,先收藏起来,慢慢学习,非常感谢楼主的无私奉献

好东西,就是要一起分享

此帖出自RF/无线论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表