【平头哥RVB2601创意应用开发】环境监测终端02-连接阿里云控制LED灯
[复制链接]
本帖最后由 sipower 于 2022-4-5 20:34 编辑
本篇文章介绍使用RVB2601开发板连接阿里云,并通过云端web界面控制开发板上的LED灯开关。
RVB2601开发板内置了联盛德公司⾼性能&安全的 WiFi4 芯⽚ W800,W800 通过 SPI ⼝与 CH2601 连接。W800 已经默认烧录基于 AT 的 WiFi 透传固件,支持飞燕平台,开发者可基于 AT ⽹络指令,快速实现联⽹的应⽤场景。
一、准备工作
首先准备以下文档和软硬件工具。
RVB2601SDK包资源:
https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3706713731985244160/resource/37067137319852441601618490096643H8zf3j4GJ6.zip
⻜燕平台地址:
https://account.aliyun.com/login/login.htm?qrCodeFirst=false&oauth_callback=https%3A%2F%2Fliving.aliyun.com%2F%3Fspm%3Da2cl5.25411629.0.0.2bdf180f04cuvE
RVB2601_W800⽹络透传AT指令集:
https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3706713731985244160/resource/37067137319852441601615533178431smnfeReQnc.pdf
RVB2601开发板⽤户⼿册:
https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3706713731985244160/resource/37067137319852441601615475227781dm4cDSePeY.pdf
RVB2601开发板快速上⼿指南:
https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3706713731985244160/resource/37067137319852441601615533134515mRkykzGxmH.pdf
参考RVB2601开发板⽤户⼿册中校对各跳线帽复⽤功能,保证上⼿使⽤时各硬件功能正常,仔细检查各跳线帽连接是否正确。如下图。
图1、跳线块位置
二、⻜燕平台产品创建
登录平台后,需要先创建⼀个项⽬。数据会根据项⽬进⾏隔离,以确保客户的数据安全。每个项⽬可以独⽴授权给其他阿⾥云账号,可以⽤于项⽬的多⽅开发协作、和运营中⼼的交付。每个项⽬会有
ID,在调⽤云端服务接⼝时,会使⽤到该ID。
图2、创建项目
创建项⽬后,就可以在项⽬中创建⽹关及⼦设备的产品。每个项⽬中,可以新建多个产品,⼀个产品代表⼀种设备型号。选择使⽤ led 进⾏测试,使⽤默认的功能定义。
图3、创建产品
完成创建后,功能定义和⼈机交互⻚⾯都按默认,点击下⼀步进⼊设备调试⻚⾯,WiFi模组随便选一个,然后点击新增测试设备。
图4、新增测试设备
完成后点击查看设备证书,这些信息就是回头要写到程序里面用于联网的关键数据。
图5、查看设备证书
三、CDK⼯程创建
根据RVB2601开发板快速上⼿指南指导,点击 创建⼯程 ,在搜索框输⼊ch2601_webplayer_demo 找到示例⼯程,添加到本地。
图6、创建工程
下载时部分资源包可能会因为版本缺失导致下载失败,按下图操作即可。
图7、重新下载
配置好后先编译下载到板子上测试一下,确保软硬件开发基础是好的,这个例程运行后,可以在串口控制台输入help,能看到这个例程支持很多指令,如下图。
图8、默认指令
四、添加代码连接⻜燕实现
在⼯程的 sdk_chip_ch2601 --> drv_wifi_at_w800 ⾥找到 w800_api.c/h ⽂件。在 w800_api.c ⽂件⾥添加以下代码:
int w800_living_wjap(const char *myssid,const char *mypassword)
{
int ret = -1;
aos_mutex_lock(&g_cmd_mutex,AOS_WAIT_FOREVER);
atparser_clr_buf(g_atparser_uservice_t);
if (atparser_send(g_atparser_uservice_t, "AT+WJAP=%s,%s", myssid ,mypassword) == 0) {
if (atparser_recv(g_atparser_uservice_t, "OK\n") == 0) {
ret = 0;
} else {
printf("Destination Host Unreachable!\r\n");
}
}
atparser_cmd_exit(g_atparser_uservice_t);
if (ret == 0) {
printf("WIFI set OK!\r\n");
}
aos_mutex_unlock(&g_cmd_mutex);
return ret;
}
int w800_living_idmau(const char *mykey,const char *myname,const char *mysecret,const char *mypsecret)
{
int ret = -1;
aos_mutex_lock(&g_cmd_mutex,AOS_WAIT_FOREVER);
atparser_clr_buf(g_atparser_uservice_t);
if (atparser_send(g_atparser_uservice_t,"AT+IDMAU=\"%s\",\"%s\",\"%s\",\"%s\"", mykey , myname , mysecret ,mypsecret) == 0) {
if (atparser_recv(g_atparser_uservice_t, "OK\n") == 0) {
ret = 0;
}else {
printf("Destination Host Unreachable!\r\n");
}
}
atparser_cmd_exit(g_atparser_uservice_t);
if (ret == 0) {
printf("IoT set OK!\r\n");
}
aos_mutex_unlock(&g_cmd_mutex);
return ret;
}
int w800_living_idmcon(void)
{
int ret = -1;
aos_mutex_lock(&g_cmd_mutex,AOS_WAIT_FOREVER);
atparser_clr_buf(g_atparser_uservice_t);
if (atparser_send(g_atparser_uservice_t, "AT+IDMCON") == 0) {
if (atparser_recv(g_atparser_uservice_t, "OK\n") == 0) {
ret = 0;
} else {
printf("Destination Host Unreachable!\r\n");
}
}
atparser_cmd_exit(g_atparser_uservice_t);
if (ret == 0) {
printf("AT+IDMCON \r\n");
}
aos_mutex_unlock(&g_cmd_mutex);
return ret;
}
在 w800_api.h ⽂件⾥添加以下代码:
int w800_living_wjap(const char *myssid,const char *mypassword);
int w800_living_idmau(const char *mykey,const char *myname,const char *mysecret,const char *mypsecret);
int w800_living_idmcon(void);
修改 app --> src --> app_main.c 代码,并根据 3.2 章节⽣成五元组信息在 connect_iot_dome 函数中将其填⼊:
#include <stdlib.h>
#include <string.h>
#include <aos/list.h>
#include <aos/debug.h>
#include <uservice/uservice.h>
#include <uservice/eventid.h>
#include <yoc/sysinfo.h>
#include <board.h>
//#include "player_demo.h"
#include "app_main.h"
#define TAG "APP"
extern int w800_living_wjap(const char *myssid,const char *mypassword);
extern int w800_living_idmau(const char *mykey,const char *myname,const char *mysecret,const char *mypsecretconst);
extern int w800_living_idmcon(void);
int iot_connect_dome(void)
{
char *my_ssid = "*********";//2.4GHZ WiFi ssid
char *my_password = "*********";//2.4GHZ WiFi password
char *my_key = "*********";//ProductKey
char *my_name = "*********";//DeviceName
char *my_secret = "*********";//DeviceSecret
char *my_p_secret = "*********";//Product Secret
int ret1 = -1;
int ret2 = -1;
int ret3 = -1;
ret1 = w800_living_wjap(my_ssid,my_password);
if (ret1 == 0){
printf("AT+WJAP:OK!\n");
}
else{
printf("AT+WJAP:ERROR!\n");
}
ret2 = w800_living_idmau(my_key,my_name,my_secret,my_p_secret);
if (ret2 == 0){
printf("AT+IDMAU:OK!\n");
}
else{
printf("AT+IDMAU:ERROR!\n");
}
ret3 = w800_living_idmcon();
if (ret3 == 0){
printf("AT+IDMCON:OK!\n");
}
else{
printf("AT+IDMCON:ERROR!\n");
}
if(ret1 == 0 && ret2 == 0 && ret3 == 0){
return 0;
}else{
return -1;
}
}
static void network_event(uint32_t event_id, const void *param, void *context)
{
switch(event_id) {
case EVENT_NETMGR_GOT_IP:
LOGD(TAG, "net got ip");
break;
case EVENT_NETMGR_NET_DISCON:
LOGD(TAG, "net disconnect");
break;
}
/*do exception process */
app_exception_event(event_id);
}
int main(void)
{
int ret = -1;
board_yoc_init();
// player_init();
// cli_reg_cmd_player();
/* Subscribe */
event_subscribe(EVENT_NETMGR_GOT_IP, network_event, NULL);
event_subscribe(EVENT_NETMGR_NET_DISCON, network_event, NULL);
ret = iot_connect_dome();
if (ret == 0){
printf("connect iot success\n");
}else{
printf("connect iot error\n");
}
}
修改 sdk_chip_ch2601 --> drv_wifi_at_w800 ⾥找到 w800_devops.c ⽂件的 w800_start 函数。
int w800_start(aos_dev_t *dev, wifi_config_t * config)
{
// w800_set_mode(dev, config->mode);
// return w800_ap_connect((const char *)config->ssid, (const char *)config->password);
return 0;
}
根据RVB2601开发板快速上⼿指南4.2章节进⾏编译,4.3章节进⾏烧录。重启开发板使⽤串⼝⼯具波特率115200连接可看到如下图打印信息。
图9、打印信息
此时⻜燕平台设备调试界⾯的测试设备中,我们新增的设备会显示为在线,如下图。表明开发板已经连上⻜燕平台了。
图10、阿里云连接成功
五、添加LED灯控制
在 w800_api.c ⽂件⾥添加接收云平台下发指令的回调函数,代码如下。
extern int iot_apply(char *strbuff);
static int _iot_recv_handler(atparser_uservice_t *at, void *priv, oob_data_t *oob_data)
{
//+IDMPS:<device_id>,<msg_len>,<message> OK
int id = 0;
int len = 0;
char data[128] = {0};
LOGI(TAG,"%s(%d)",oob_data->buf,oob_data->len);
char *str = strchr(oob_data->buf, ':');
if (str != NULL) {
sscanf(oob_data->buf, "%d,%d,%s\r\n", &id, &len, data);
LOGI(TAG,"==>iot_recv %d(%d):%s\r\n",id, len, data);
iot_apply(data);
}
/* recv data is not enough need recv more */
return 0;
}
在w800_module_init(utask_t *task, w800_wifi_param_t *param)函数中添加初始化代码。
atparser_oob_create(g_atparser_uservice_t, "+IDMPS:", _iot_recv_handler, NULL); //属性设置OOB注册
在app_main.c 文件中添加LED相关的初始化和控制代码,如下。
static csi_gpio_pin_t r;
static csi_gpio_pin_t g;
static csi_gpio_pin_t b;
void led_pin_init()
{
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
csi_gpio_pin_init(&r, PA7);
csi_gpio_pin_dir(&r, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&g, PA25);
csi_gpio_pin_dir(&g, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&b, PA4);
csi_gpio_pin_dir(&b, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_write(&r, GPIO_PIN_HIGH);
csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
csi_gpio_pin_write(&b, GPIO_PIN_HIGH);
}
void led_refreshed(int sw_led)
{
if (sw_led == 1)
{
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
csi_gpio_pin_write(&g, GPIO_PIN_LOW);
csi_gpio_pin_write(&b, GPIO_PIN_LOW);
}
else
{
csi_gpio_pin_write(&r, GPIO_PIN_HIGH);
csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
csi_gpio_pin_write(&b, GPIO_PIN_HIGH);
}
}
unsigned char buff_accept[68];
cJSON *str_json, *str_value; //初始化json结构体指针
int iot_apply(char *strbuff)
{
strcpy((char *)buff_accept,strbuff);
str_json = cJSON_Parse((char *)buff_accept); //创建JSON解析对象,返回JSON格式是否正确
if(str_json == NULL)
{
LOGI(TAG"error:%s;\r\n",cJSON_GetErrorPtr());
cJSON_Delete(str_json);//释放内存
return -1;
}
else
{
cJSON *str_value = cJSON_GetObjectItem(str_json, "powerstate");
LOGI(TAG,"powerstate:%d;\r\n",str_value->valueint);
led_refreshed(str_value->valueint);
cJSON_Delete(str_json);//释放内存
return 1;
}
}
在此处特别说明一下,由于云端传回的信息是JSON格式,需要用到cJSON库进行解码。我推荐一个很容易获得cJSON库的方式。如下图。
图11、欢迎界面
在欢迎页面第一个实例是《WiFi智能灯控》例程,把它下载下来,不用编译,你会发现在《__workspace_pack__》这个文件夹下就有了cJSON库了。如下图。
图12、获得cJSON库
然后在库管理里面将cJSON库添加到工程中即可。如下图。
图13、cJSON库添加
然后除bug编译,代码部分就搞完了。在阿里云平台通过在线调试可以测试代码是否执行正常。如下图。
图14、在线调试
六、添加web应用
在操作之前先介绍一下阿里的生活物联网平台(飞燕平台)与物联网平台的区别。
物联网平台提供原子化的设备接入能力,适用于云开发能力较强的用户,可以在各个行业领域使用。了解更多详情请参见什么是物联网平台。
生活物联网平台提供了设备接入能力、移动端的SDK以及免开发的公版App和界面,更适用于消费级的智能设备开发者,开发门槛较低,可以快速实现消费级设备的智能化,如智能家电、穿戴、家装领域等。
使用同一个阿里云账号登录的用户,在生活物联网平台创建的所有产品和设备,将自动同步到物联网平台中。而在物联网平台中创建的产品,也可以通过手动切换收费模式,将产品转移到生活物联网平台中。
本章用到的物联网应用开发(IoT Studio)是阿里云针对物联网场景提供的生产力工具,是阿里云物联网平台的一部分。可覆盖各个物联网行业核心应用场景,帮助用户高效经济地完成物联网数据分析、设备、服务及应用开发,加速物联网SaaS构建。
物联网应用开发提供了Web可视化开发、移动可视化开发、业务逻辑开发与物联网数据分析等一系列便捷的物联网开发工具,解决物联网开发领域开发链路长、定制化程度高、投入产出比低、技术栈复杂、协同成本高、方案移植困难等问题。详细介绍见以下链接。
https://help.aliyun.com/document_detail/106087.html?scm=20140722.184.2.173
下面介绍web应用创建过程。首先登陆IoT Studio账号,如下连接。
https://account.aliyun.com/login/login.htm?qrCodeFirst=false&oauth_callback=https%3A%2F%2Fstudio.iot.aliyun.com%2Fp%2Fa123jX2VXQqAfhnk%2Fproject%2Fdetail
图15、IoT Studio界面
点击新建按钮,进入到开发界面,从左侧控件栏里选中开关控件拖入布局框中。如下图。
图16、创建开关控件
按照下图顺序和内容设置开关属性,如果一次弄不好,可以多尝试几次,由于图形式操作很简单,很快就能搞清楚其中的逻辑过程。
图17、设置开关属性
配置好后点击预览,即可见到所设计的用户界面。点击这个大按钮,就可控制开发板的LED灯开关了。效果如下。
图18、云端控制LED灯开关
至此,阿里云与RVB2601实验板的连接过程就介绍完了,通过此次实操,基本搭建完成网络通讯部分功能,为后边功能打好基础。
|