Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ART-Pi
https
RT-Thread实战笔记|语音控制实现获取心知天气信息
发布于 2022-01-21 22:13:57 浏览:1504
订阅该版
[tocm] # 前言 上篇文章介绍了LD3320的用法,小飞哥“灵光一现”,何不做一个语音控制获取天气信息的东东,既然想了,那就干它,来,淦~小飞哥前面说过rt-thread好用,那今天一起来看看到底有多好用...内容比较多,建议泡杯茶,慢慢看 # 演示效果 见公众号 # 硬件环境 - ART-PI(其他开发板也可以) - LD3320语音模块 - 板载wifi(ESP8266也可以) - “一张会说话的嘴” # 软件环境 - RT-Thread studio 版本2.1.1 - 软件包 - webclient V2.1.2 - mbedtls V2.7.10.1 - cjson V1.7.14 - netutils V1.3.1 - fal V0.5.0 本次的知识点还是相当的丰富的,搬好小板凳,泡杯茶,坐一会慢慢看吧... # wifi配置 在LD3320的工程基础之上,来添加wifi,ART-PI上板载的wifi模组是AP6212,是蓝牙于wifi一体的模组,本次我们只使用wifi功能  在setting勾选即可,对应的宏为ART_PI_USING_WIFI_6212_LIB,勾选之后,工程会自动添加相关宏定义控制的代码   完了,CTRL+S保存到我们的工程就可以了...好像啥也没干,来看看效果是怎样的 在控制台可以看到,很多关于网络的配置已经初始化完成了,终端输入wifi,可以看到几个关于wifi的指令,本次用到的是wifi的AP功能,连接家里的wifi  输入wifi scan,来看看附近都有哪些“hot pot”,还是有几个的,也不隐藏了,欢迎过来蹭网~  使用wifi join命令加入网络即可,千万不要跟着教程输入我家的... ``` wifi join "你家热点名称" "你家无线密码" ``` 网络状况好像不太好,还重连了,顺便把重连功能验证了,连接成功之后,可以看到是自动获取IP地址的,输入ifconfig,来看看获取到的地址相关的,DHCP功能是使能的  接下来,开发板“点灯”,网络经典ping百度...还算比较顺利  就这样,我们的wifi就完成了,对,就这样...一行代码没写,sun le dog,好怀念写代码的日子 这样直接添加wifi功能的方式,掉电是不会保存wifi信息的,需要重新wifi join # https访问组件配置 ## webclient 软件包 setting->Add->输入webclient->确认找到对应软件包  双击打开可以详细看到关于此软件包的用法  -点击软件包,进入详细配置界面, - Enable webclient GET/POST samples :添加示例代码; - Select TLS mode :配置开启 HTTPS 支持,选择支持的模式 - Not support:不支持 TLS 功能 - SAL TLS support:配置 SAL 组件中 TLS 功能支持,SAL 组件中抽象 TLS 操作,用户还需要手动配置开启使用的 TLS 软件包类型(目前只支持 MbedTLS 软件包) - MbedTLS support:配置 MbedTLS 功能支持 - Version :配置软件包版本  ## mbedtls软件包 使能mbedtls功能之后,mbedtls软件包自动添加,mbedTLS(前身 PolarSSL)是一个由 ARM 公司开源和维护的 SSL/TLS 算法库。其使用 C 编程语言以最小的编码占用空间实现了 SSL/TLS 功能及各种加密算法,易于理解、使用、集成和扩展,方便开发人员轻松地在嵌入式产品中使用 SSL/TLS 功能  详细配置 - Select Root Certificate ---> # 选择证书文件 - mbedtls: An portable and flexible SSL/TLS library # 打开 mbedtls 软件包 - Store the AES tables in ROM # 将 AES 表存储在 ROM 中 - Maximum window size used # 用于点乘的最大“窗口”大小(2-7) (3584) Maxium fragment length in bytes # 配置数据帧大小 - Enable a mbedtls client example # 开启 mbedtls 测试例程 - Enable Debug log output # 开启调试 log 输出 - version (latest) ---> # 选择软件包版本,默认为最新版本  ## 注意: 在调试的时候,获取不同的信息时,有时候返回的数据量太大,报错-0x7200  不要慌,百度错误码,可能是数据buffer太小了,增大buffer即可解决   关于证书的内容就比较多了,小伙伴可以自行百度或者查看mbedtls软件包的使用教程 ## netutils 这里汇集了 RT-Thread 可用的全部网络小工具集合,你所需要的小工具都可以在这里找到。  TLS 握手是证书验证需要时间的验证,添加此网络工具用于时间同步   同时要开启RTC功能,否则会报错   RTC详细配置界面  至此,网络功能就配置完成了,接下来跑一下例程,看下效果  web_get我们是获取到一串字符串,看看源码地址什么  浏览器输入此地址,获取到的正是这些字符  TLS例程比较麻烦点,要先进行SSL/TLS 认证,才能连接,这就牵扯到HTTP和HTTPS的区别了,篇幅太大,不易展开...  同样的,看下源地址是什么内容   到这里,我们的HTTPS访问就建立完成了,还没有写一句代码... # 心知天气API 大家需要注册一个心知天气账号,注册完之后使用免费的即可  天气API https://api.seniverse.com/v3/weather/now.json?key=“你的秘钥”&location=“地点”  我们点击一个进去看看,我查看的是北京的天气,数据是json格式的,我们只需要解析json包就可以啦  原始数据  这里教大家一个小技巧,如何查看网址的IP地址,端口号,只需要在网页按F12进入调试界面,宣导网络,重新加载   # 代码编写 新建文件,或者在上面例程里面修改,首先把网址改为心知天气的API接口  成功获取到天气数据  json解析 ```c static int cJSON_NowWeatherParse(char *JSON) { cJSON *json,*arrayItem,*object,*subobject,*item; int size; json = cJSON_Parse(JSON);//解析JSON数据包 if(json == NULL) //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效 { rt_kprintf("Error before: [%s]\r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置 return 1; } else { if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容 { size = cJSON_GetArraySize(arrayItem); //获取数组中对象个数 rt_kprintf("cJSON_GetArraySize: size=%d\n",size); if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容 { rt_kprintf("--------------------------------Now Weather Data Begin------------------------------\r\n"); /* 匹配子对象1 */ if((subobject = cJSON_GetObjectItem(object,"location")) != NULL) { rt_kprintf("---------------------------------subobject1-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"id")) != NULL) { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //地名--需要用到的数据 { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"country")) != NULL) { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"path")) != NULL) { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL) { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL) { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } } /* 匹配子对象2 */ if((subobject = cJSON_GetObjectItem(object,"now")) != NULL) { rt_kprintf("---------------------------------subobject2-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//天气预报文字--需要用到的数据 { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//天气预报代码--需要用到的数据 { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string, item->valuestring); } if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //温度--需要用到的数据 { rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",item->string, item->valuestring); } } /* 匹配子对象3 */ if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL) { rt_kprintf("---------------------------------subobject3-------------------------------\r\n"); rt_kprintf("cJSON_GetObjectItem: %s:%s\r\n",subobject->string,subobject->valuestring); } rt_kprintf("--------------------------------Now Weather Data End--------------------------------\r\n"); } } } cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间 return 0; } ``` 解析后的数据:  接下来,结合上节我们做的LD3320,实现语音控制获取不同地点的天气信息: 先来定义几个地点: ```c static char *REQUEST[4] ={ "GET /v3/weather/now.json?key=SYahiZcoJ587MEA3R&location=beijing HTTP/1.1\r\n" "Host: api.seniverse.com\r\n" //"User-Agent: rtthread/3.1 rtt\r\n" "\r\n", "GET /v3/weather/now.json?key=SYahiZcoJ587MEA3R&location=suzhou HTTP/1.1\r\n" "Host: api.seniverse.com\r\n" //"User-Agent: rtthread/3.1 rtt\r\n" "\r\n", "GET /v3/weather/now.json?key=SYahiZcoJ587MEA3R&location=shanghai HTTP/1.1\r\n" "Host: api.seniverse.com\r\n" //"User-Agent: rtthread/3.1 rtt\r\n" "\r\n", "GET /v3/weather/now.json?key=SYahiZcoJ587MEA3R&location=shenzhen HTTP/1.1\r\n" "Host: api.seniverse.com\r\n" //"User-Agent: rtthread/3.1 rtt\r\n" "\r\n", }; ``` 然后在语音中添加相应的识别信息: ```c //Identification code (Customer Modification Office) #define CODE_RUN 1 //commond code for LED waterfall #define CODE_KEY 2 //commond code for LED flash #define CODE_FLASH 3 //commond code for LED reversal #define CODE_PLAY 4 //commond code for PLAY MP3 #define CODE_BEIJING_Weather 5 //北京 #define CODE_SUZHOU_Weather 6 //苏州 #define CODE_SHANGHAI_Weather 7 //上海 #define CODE_SHENZHEN_Weather 8 //深圳 rt_uint8_t sRecog[DATE_A][DATE_B] = { //add commond,use pinying "ni hao", "ni lai zi na li", "bei yi shou shi", "shi jie zhe me da", "bei jing tian qi", "shang hai tian qi", "su zhou tian qi", "shen zhen tian qi" }; rt_uint8_t pCode[DATE_A] = { //add commond code to do the commond CODE_RUN, CODE_KEY, CODE_FLASH, CODE_PLAY, CODE_BEIJING_Weather, CODE_SHANGHAI_Weather, CODE_SUZHOU_Weather, CODE_SHENZHEN_Weather }; ``` 函数执行: ```java rt_uint8_t status =0; void rt_Board_text(rt_uint8_t Code_Val) { switch (Code_Val) { case CODE_RUN: //Commond "liu shui deng" rt_LED_run(); break; case CODE_KEY: //Commond "an jian" rt_LED_key(); break; case CODE_FLASH: //Commond "shan shuo" rt_LED_flash(); break; case CODE_PLAY: //Commond "bo fang" rt_Play_demo(); break; case CODE_BEIJING_Weather: status=0; Weather(); break; case CODE_SUZHOU_Weather: status=1; Weather(); break; case CODE_SHANGHAI_Weather: status=2; Weather(); break; case CODE_SHENZHEN_Weather: status=3; Weather(); break; default: break; } } ``` 然后改一下例程里面的请求函数,根据识别到的语音置相应的状态,调用不同的API: ```java while ((ret = mbedtls_client_write(tls_session, (const unsigned char *) REQUEST[status], rt_strlen(REQUEST[status]))) <= 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { rt_kprintf("mbedtls_ssl_write returned -0x%x\n", -ret); goto __exit; } } ``` # 资料获取 关注公众号,即可获取源码资料,欢迎添加小飞哥好友,进群交流,喜欢RTT的小年轻,期待和RTT一起变得越来越好 
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
Enthusiasm
公众号:小飞哥玩嵌入式
文章
8
回答
7
被采纳
0
关注TA
发私信
相关文章
1
RT-Thread Studio 编译ART-Pi 的SDK报错 求助!-
2
ART-Pi 在 Studio 中使用TouchGFX Library 编译报错
3
RT-Thread Studio 更新错误
4
基于ART-Pi开发板创建的工程,RT-Thread Settings打不开
5
在 ART-Pi 平台使用 openocd 直接烧录到外部 spi flash?
6
ART-Pi工程用mdk5打开后提示文件找不到
7
ART-PI demo是否能够增加demo流程框图或者详细设计文档
8
ART-Pi 的ST_Link无法识别
9
请把ART-Pi仓库放到gitee上一份。
10
仅有ART-Pi开发包时,RTT Studio无法创建ART-Pi工程
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
10
个答案
3
次被采纳
xiaorui
3
个答案
2
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
8
个答案
1
次被采纳
KunYi
8
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
9
次点赞
swet123
1
篇文章
4
次点赞
Days
1
篇文章
4
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部