作者:niu

在RVB2601开发板上,CH2601主芯片通过SPI接口和W800 WIFi/BLE模块通信,W800芯片在此接口上提供AT命令的方式供主芯片使用W800的功能。

根据《W800模组AT指令集》中的描述,W800芯片中实现了WiFi配网、WiFi连接、TCP连接、阿里云飞燕生活物联网平台接入等功能。W800模组AT指令集.pdf (aliyuncs.com)

从RVB2601的SDK看,已经实现了基于W800 AT命令的Socket抽象设备,本文中将尝试在现有功能基础上,实现和测试验证阿里云平台接入的等相关功能,同时去了解YoC中网络设备和AT解析器框架。 AT指令解析器 AT指令解析器 主要用于发送命令、等待响应,用户可通过atparser_response_recv()获取并解析该应答数据,对于对端主动发送的数据(数据即为带外数据),则传入对应的带外处理函数中。 AT指令解析器 · GitBook (t-head.cn)

接口详细说明

初始化一个AT指令解析器

atparser_uservice_t *atparser_init(utask_t *task, const char *name, uart_config_t *config)

根据指定的微服务任务,串口名以及串口配置信息创建一个AT 指令解析器,成功则返回atparser_uservice_t指针,失败返回NULL

参数:

  • task:微服务任务
  • name: 串口名
  • config: 串口配置信息

返回值:

成功则返回atparser_uservice_t指针,失败返回NULL

初始化一个用户自定义的AT指令解析器

atparser_uservice_t *atparser_channel_init(utask_t *task, const char *name, void *config, at_channel_t *channel);

根据指定的微服务任务,串口名以及串口配置信息创建一个AT 指令解析器,成功则返回atparser_uservice_t指针,失败返回NULL

参数:

  • task:微服务任务
  • name: 设备名
  • config: 设备配置信息
  • channel:at指令解析器的channel

返回值:

成功则返回atparser_uservice_t指针,失败返回NUL

at_channel是具体执行AT命令内容收发的通道,比如串口、SPI接口等,RVB2601开发板上使用SPI接口;atparse负责对命令内容的解析和格式化拼装。

带外数据处理函数的格式

typedef int (*oob_callback)(atparser_uservice_t *at, void *pive, oob_data_t *oob_data);

用户根据传入的数据,做相关的处理,若处理完成则返回0;若处理未完成则返回-1

参数:

  • at: AT 指令解析器
  • pive:用户自定义数据
  • oob_data: 带外数据结构体

返回值:

0表示处理完成并退出本次OOB,-1表示处理未完成,需要继续执行OOB

创建一个带外数据服务

int atparser_oob_create(atparser_uservice_t *at, const char *prefix, oob_callback cb, void *context);

根据指定的AT 指令解析器,带外数据匹配字符串,带外数据处理函数,以及用户自定义的上下文创建一个带外数据处理服务,成功则返回0,失败则返回负值

代码实现

cli中注册一个命令去触发连接云等动作,在获取到IP后去给w800发AT命令,开始连接云。

//应用层,添加cli命令
extern int set_aliyun_key( );
extern int set_aliyun_smartconf( );
extern int cloud_connect();static void do_yun_cmd(char *wbuf, int wbuf_len, int argc, char **argv)
{if (argc > 1) {if (0 == strcmp(argv[1], "config")) {printf("do smart confg\r\n");set_aliyun_smartconf( );return;} else if (0 == strcmp(argv[1], "conn")) {printf("do cloud_connect\r\n");cloud_connect();return;} else if (0 == strcmp(argv[1], "set")) {printf("do set_aliyun_key\r\n");set_aliyun_key( );return;}}
}void cli_reg_cmd_user(void)
{static const struct cli_command cmd_yun = {"yun","yun comand",do_yun_cmd,};aos_cli_register_command(&cmd_yun);
}

W800的AT解析器实现中增加对云连接状态和属性设置下发的处理

extern at_channel_t spi_channel;
int w800_module_init(utask_t *task, w800_wifi_param_t *param)
{if (w800_module_inited) {return 0;}if (task == NULL) {task = utask_new("w800", 7 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI + 4);}if (task == NULL) {return -1;}if (param->reset_pin) {csi_gpio_pin_init(&g_reset_pin, param->reset_pin);csi_gpio_pin_mode(&g_reset_pin,GPIO_MODE_PULLUP);csi_gpio_pin_dir(&g_reset_pin,GPIO_DIRECTION_OUTPUT);csi_gpio_pin_write(&g_reset_pin, GPIO_PIN_LOW);aos_msleep(200);csi_gpio_pin_write(&g_reset_pin, GPIO_PIN_HIGH);aos_msleep(1000);LOGD(TAG, "hard reset");}g_atparser_uservice_t = atparser_channel_init(task, NULL, param, &spi_channel);aos_mutex_new(&g_cmd_mutex);atparser_debug_control(g_atparser_uservice_t, 1);atparser_oob_create(g_atparser_uservice_t, "2,CLOSED", _closed2_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "1,CLOSED", _closed1_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "0,CLOSED", _closed0_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=NET,LINK_UP", _gotip_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=NET,LINK_DOWN", _disconnect_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=RECV,", _recv_data_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=DISCONNECT,0", _closed0_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=DISCONNECT,1", _closed1_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+EVENT=DISCONNECT,2", _closed2_handler, NULL);atparser_oob_create(g_atparser_uservice_t, "+IDMSTA:", cloud_connsta_handler, NULL);   //连接状态OOB注册atparser_oob_create(g_atparser_uservice_t, "+IDMPS:", cloud_recv_handler, NULL);       //属性设置OOB注册w800_module_inited = 1;return 0;
}/* 接收到云端下发的属性设置 */
/* oob_data->buf和oob_data->len为AT通道上接收到的"+IDMPS:"之后的内容和长度 */
static int cloud_recv_handler(atparser_uservice_t *at, void *priv, oob_data_t *oob_data)
{//+IDMPS:<device_id>,<msg_len>,<message>  OKint 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,"==>cloud_recv %d(%d):%s\r\n",id, len, data);oob_data->used_len += (str - oob_data->buf+1);}/* recv data is not enough need recv more */return 0;
}/*云连接状态上报OOB处理*/
static int cloud_connsta_handler(atparser_uservice_t *at, void *priv, oob_data_t *oob_data)
{LOGI(TAG,"==>cloud_conn: %s(%d)",oob_data->buf,oob_data->len);/* recv data is not enough need recv more */return 0;
}

实现云连接等功能的AT命令收发

int cloud_connect()
{int ret = -1;g_net_status = NET_STATUS_READY;aos_mutex_lock(&g_cmd_mutex, AOS_WAIT_FOREVER);atparser_set_timeout(g_atparser_uservice_t, 30 * 1000);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") == 0) {ret = 0;LOGI(TAG,"===>IDMCON OK");}}atparser_set_timeout(g_atparser_uservice_t, 8 * 1000);atparser_cmd_exit(g_atparser_uservice_t);aos_mutex_unlock(&g_cmd_mutex);return ret;
}int set_aliyun_key( )
{int ret = -1;g_net_status = NET_STATUS_READY;aos_mutex_lock(&g_cmd_mutex, AOS_WAIT_FOREVER);atparser_set_timeout(g_atparser_uservice_t, 30 * 1000);atparser_clr_buf(g_atparser_uservice_t);if (atparser_send(g_atparser_uservice_t, "AT+IDMAU=\"%s\",\"%s\",\"%s\",\"%s\"", PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, PRODUCT_SECRET) == 0) {if (atparser_recv(g_atparser_uservice_t, "OK") == 0) {ret = 0;LOGI(TAG,"===>IDMAU OK");}}atparser_set_timeout(g_atparser_uservice_t, 30 * 1000);atparser_clr_buf(g_atparser_uservice_t);if (atparser_send(g_atparser_uservice_t, "AT+IDMPID=%ld", PRODUCT_ID) == 0) {if (atparser_recv(g_atparser_uservice_t, "OK") == 0) {ret = 0;LOGI(TAG,"===>IDMPID OK");}}atparser_set_timeout(g_atparser_uservice_t, 8 * 1000);atparser_cmd_exit(g_atparser_uservice_t);aos_mutex_unlock(&g_cmd_mutex);return ret;
}int set_aliyun_smartconf( )
{int ret = -1;g_net_status = NET_STATUS_READY;aos_mutex_lock(&g_cmd_mutex, AOS_WAIT_FOREVER);atparser_set_timeout(g_atparser_uservice_t, 30 * 1000);atparser_clr_buf(g_atparser_uservice_t);if (atparser_send(g_atparser_uservice_t, "AT+IDMCLS") == 0) {if (atparser_recv(g_atparser_uservice_t, "OK") == 0) {ret = 0;LOGI(TAG,"===>IDMCLS OK");}}atparser_set_timeout(g_atparser_uservice_t, 30 * 1000);atparser_clr_buf(g_atparser_uservice_t);if (atparser_send(g_atparser_uservice_t, "AT+IWSSTART=0") == 0) {if (atparser_recv(g_atparser_uservice_t, "OK") == 0) {ret = 0;LOGI(TAG,"===>IWSSTART OK");}}atparser_set_timeout(g_atparser_uservice_t, 8 * 1000);atparser_cmd_exit(g_atparser_uservice_t);aos_mutex_unlock(&g_cmd_mutex);return ret;
}

在阿里云物联网平台创建产品并定义功能

为w800模块配网和配置五元组

手机app配网没有调通,后续再调,先用手动配网;       调用set_aliyun_key( )配置五元组后,重启,w800将会自动连接路由器;

在连上路由器获取到IP后,调用cloud_connect(),待手动连接状态OOB回调时,“+IDMSTA:2“”说明已经连上阿里云了,在阿里云后台可以看到设备已在线;

通过在阿里云后台的设备调试页面,可进行在线调试,对设备属性进行设置,开发板上将收到对应的属性值,如下图:

到此,阿里云接入和属性设置功能验证通过了,后续将继续完善功能,基于在阿里云上定义的产品功能,做进一步的开发实现更多的应用功能。

本文源自:平头哥芯片开放社区

欢迎关注公众号:芯片开放社区(ID:OCC_THEAD),查看更多应用实战文章。

【平头哥RVB2601开发板试用体验】AT解析器和通过w800 AT命令接入阿里云生活物联网平台相关推荐

  1. 【平头哥RVB2601开发板试用体验】I/O扩展

    一.概述 RVB2601是基于平头哥生态芯片CH2601的开发板,板载JTAG调试器,WiFi&BLE芯片W800,音频ADCES7210,音频DACES8156,128x64 OLED屏幕, ...

  2. 【平头哥RVB2601开发板试用体验】基于NTP的网络校时及WIFI驱动Bug调试

    作者:czxin NTP全称Network time Protocol,即网络时间协议,顾名思义就是通过与网络服务器之间通信来达到时间校准的协议,它是基于UDP的协议,记住这里的UDP,和后面遇到的W ...

  3. 【平头哥RVB2601开发板试用体验】基于 HTTPClient 的云语音识别 1

    作者:哈猪猪 前言 本系列共有三篇文章,目的是在 RVB2601 上实现基于 HTTPClient 组件的云语音识别.文章连接与主要内容如下: 文章1:设计思路:HTTPClient 组件测试 文章2 ...

  4. 阿里云HaaS100物联网开发板学习笔记(四)轻应用初步--用javascript连接阿里云物联网平台

    摘要:本篇文章讲解如何使用JavaScript"轻应用"连接阿里云物联网平台并上报一个数据.仍然延续前几篇文章的结构,从安装软件环境开始讲,以使零基础的同学看了本篇文章之后,也能够 ...

  5. ESP8266开发之旅 阿里云生活物联网平台篇② 使用云智能App,配置自己的App,无需开发

    文章目录 1.前言 2.云智能App -- 免开发公版App 授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥 ...

  6. qt工程在linux系统里颜色显示错误_【飞凌嵌入式RK3399开发板试用体验】+QT开发环境搭建测试(二)...

    作者:飞扬的青春 在拿到开发板之后,已经体验了Android操作系统,接下来就是体验Linux下的开发,本次以QT的一个小案例来测试下. 首先是自己先搭建了一个Ubuntu18.04的虚拟机,使用真机 ...

  7. 飞凌嵌入式iMX8MP 开发板试用体验--编译内核源码

    FETMX8MP-C核心板基于NXP i.MX 8M Plus处理器开发设计,该系列处理器专注于机器学习与视觉.高级多媒体以及具有高可靠性的工业自动化.旨在满足智慧城市.工业互联网.智能医疗.智慧交通 ...

  8. esp32对接阿里云生活物联网平台 天猫精灵控制 云智能APP远程控制 ali-sdk开发

    一,提前搭建好Linux ESP-IDF开发环境,本博客不叙述具体搭建过程,请参考网上教程. ESP-IDF: 请切换到 release v4.2 tag 版本: git checkout v4.2 ...

  9. RVB2601开发板试用5——远程音频采集系统

    本文作者:我爱下载 1.概述 远程音频采集系统利用RVB2601的ES7210麦克风数字化采样,W800的WiFi通讯和OLED液晶显示相关信息,进行音频收集和存储.开发专用的上位软件,通过以太网通讯 ...

最新文章

  1. Linq Coding -- Part Three [Let子句]
  2. python专业名词_python 术语
  3. fatal error C1070: mismatched wabtags.h
  4. Java、Apache Tomcat下载与安装及环境变量配置
  5. Silverlight 4.0 Accordion 解决ScrollViewer 的问题
  6. 为什么女性创业举步维艰?
  7. odoo pivot中去掉求和_评比算分,去掉最高分和最低分算平均,PLC怎样编程实现?...
  8. C# Winform编程ListBox之DrawItem事件
  9. Solaris 10 的基本操作
  10. BZOJ3835 [Poi2014]Supercomputer 【斜率优化】
  11. 「LOJ#10068」「一本通 3.1 练习 3」秘密的牛奶运输(次小生成树
  12. 计算机二进制编码原理,计算机组成原理--二进制编码
  13. PSC-Net: Learning Part Spatial Co-occurrence for Occluded Pedestrian Detection 用于遮挡行人检测的部分空间共现网络 翻译
  14. unity 刷新layout_【Unity源码学习】Layout
  15. 北鲲云超算平台助力国产芯片设计
  16. 答读者:数学不好,能学好算法吗?
  17. 浅谈5G通信中的两个微波技术
  18. 自制随机小姐姐摄影api
  19. 目标检测-SSD算法详细总结
  20. 问卷调查:vue element动态生成表单、表单校验以及表单提交

热门文章

  1. 低配本用win10服务器系统,杜宇低配置的电脑到底是安装win10系统好还是选择win7操作系统更好一点呢...
  2. 华为云SparkRTC面向低时延、大通量传输业务的技术探索
  3. 游戏创作者的宝藏资源:游戏UI数据库
  4. 基于手写字体的识别系统
  5. VTK在Windows上的安装
  6. 视频教程-用友U8视频教程全集(全模块)-ERP
  7. S7300与G120变频器控制上位机 C#与S7300通讯上位机
  8. centos找不到ens33
  9. UE4 回合游戏项目 15- 生成玩家、控制玩家
  10. 【每日随笔】网文小说工具及书籍推荐 ① ( 网文写手的入门书籍推荐 | 网文写手的进阶书籍推荐 | 提高文学素养的写作课 )