1854|4

281

帖子

7

TA的资源

一粒金砂(高级)

楼主
 

【平头哥RVB2601创意应用开发】环境监测终端06-将数据同步到阿里云 [复制链接]

 

本篇文章介绍将采集到的温度、湿度、噪声水平数据和指示灯设置上传到阿里云平台,还可以通过云端控制指示灯开关。

1、阿里云设置

在我的第二篇文章中介绍了在阿里云飞燕平台创建产品的过程。这次介绍在阿里云IoT Studio平台创建产品,添加设备的过程,具体的这两个平台有什么区别,可以参见我之前文章的介绍,链接如下。

https://occ.t-head.cn/community/post/detail?id=4031864498838708224

登陆阿里云IoT Studio平台,地址如下。

https://account.aliyun.com/login/login.htm?qrCodeFirst=false&oauth_callback=https%3A%2F%2Fstudio.iot.aliyun.com%2Fproject%2Fa123jX2VXQqAfhnk%2Fdevices%2Fa1iO8mTqhOz%2Fdev_001%2F1

在主页中点击“产品”一栏,进入产品列表,然后点击“创建产品”如下图:

1、主页操作

在如下界面中录入自己想要的信息,点击最下面的确认,产品就创建完成。

2、创建产品

进入产品管理界面,按照下图添加产品属性,其中标识符是单片机和阿里云通讯的重要握手信息,最好设成简明好记的,编程时方便调试。

3、添加产品属性

我的产品主要是温度、湿度、噪声水平三个参数的采集,和一个指示灯的设置,共有四个属性。这些参数的数据类型和数据定义也要和单片机程序里面的一致。

产品设置好后,添加设备,按照下图操作,填入自己喜欢的信息,点击确定添加成功。

4、添加设备

在设备信息界面可以查看相关的证书密钥,这个回头用于单片机程序和阿里云连接用。具体如何使用见我的第二篇文章。

5、设备信息

至此阿里云端的设置就完成了。可以通过不同的界面查看各种配置,多熟悉一下就能熟练使用,整个操作界面还是很友好的。

2、单片机程序编写

在我的第二篇文章中已经介绍了如何连接到阿里云平台,这里不再赘述,重点介绍上传相关的代码和调试中遇到的问题。

首先说一下我遇到代码容量不够问题。当把lvgl库和wifi库同时加入工程后,编译会提示编译完的代码超范围,貌似之前其他同学也遇到过此类问题。我仔细研究了flash默认配置,发现总共512KB的容量,只给了用户程序分配了256KB,剩下还有好多留给升级缓存了。在我这个作品中,没有计划做OTA升级,因此完全可以把用户空间扩大。具体操作如下图。

6、修改分区表

打开config.yaml分区表文件,将prim用户空间扩大,具体扩大到多少根据自己需要改,别超出flash有效范围就行。我这改到384KB。misc为升级缓存空间,起始地址也要注意修改成对应的新地址。改完注意保存。打开gcc_flash.ld文件,将flash长度修改成和config.yaml一样的,保存。

这两个文件改完后,我们就有更多空间存代码了。我的代码编译完成后如下图,还有足够的空间扩展。

7、代码占用情况

然后是在原来物联网代码基础上添加属性上报代码。在w800_api.c中添加通用属性上报函数,代码如下。

int w800_living_idmpp(const char *dev_id, const char *msg, int *packet_id)
{
    int ret = -1;
    int rsp_dev_id = -1;
    int rsp_packet_id = -1;
    int rsp_code = -1;
    int rsp_reply_len = -1;
    char event_str[64] = {0};


    if (!dev_id || !msg || !packet_id) {
        return ret;
    }
    aos_mutex_lock(&g_cmd_mutex, AOS_WAIT_FOREVER);
    atparser_clr_buf(g_atparser_uservice_t);
    /**
     *    AT+IDMPP=0,"{"temp":25.8,"humi":26.5,"noise":18,"led":0}"
    */
    char at_string_msg[80] = {0};
    snprintf(at_string_msg, 80, "AT+IDMPP=0,\"%s\"", msg);
    LOGD(TAG, "Send msg: %s\r\n", at_string_msg);
    if (atparser_send(g_atparser_uservice_t, at_string_msg) == 0) {
        if (((atparser_recv(g_atparser_uservice_t, "+IDMPP:%d\n", packet_id) == 0) && 
            (atparser_recv(g_atparser_uservice_t, "OK\n") == 0)) ||
            (atparser_recv(g_atparser_uservice_t, "+IDMPP:%d,%d,%d,%d,%s\n", 
                    &rsp_dev_id, &rsp_packet_id, &rsp_code, &rsp_reply_len, event_str) == 0)) {
            ret = 0;
            LOGD(TAG, "Send at cmd ok\r\n");
        }
    } else {
        LOGD(TAG, "Send at cmd err\r\n");
    }
    atparser_cmd_exit(g_atparser_uservice_t);
    aos_mutex_unlock(&g_cmd_mutex);
    return ret;
}

创建yun_app.c文件,将云端操作相关代码放这个里面。代码如下。

#include <stdlib.h>
#include <string.h>
#include <aos/list.h>
#include <aos/debug.h>

#include <drv/gpio.h>
#include <drv/gpio_pin.h>
#include <drv/pin.h>

#include <uservice/uservice.h>
#include <uservice/eventid.h>
#include <yoc/sysinfo.h>
#include <board.h>
//#include "player_demo.h"
#include "cJSON.h"

#include "thp_get.h"
#include "yun_app.h"

#define TAG "APP"

extern Result_S res_data; 

int iot_con_flag = 0;

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);
extern int w800_living_idmpp(const char *dev_id, const char *msg, int *packet_id);

int iot_upload(void)
{
	int ret = -1;
	const char *dev_id = "0";
	char msg_buf[80];
	int pkt_id = 0;
	
	if(iot_con_flag==1)
	{
		snprintf(msg_buf,80,"{\\\"temp\\\":%.1f,\\\"humi\\\":%.1f,\\\"noise\\\":%d,\\\"led\\\":%d}",res_data.temp,res_data.humi,res_data.noise,res_data.led);
		printf( "==> start attribute upload\n");
		ret = w800_living_idmpp(dev_id, msg_buf, &pkt_id);
	}
	return(ret);
}

static csi_gpio_pin_t g;

void led_pin_init()
{
    csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
    csi_gpio_pin_init(&g, PA25);
    csi_gpio_pin_dir(&g, GPIO_DIRECTION_OUTPUT);

	csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
}

void led_refreshed(int sw_led)
{
    if (sw_led == 1)
    {
        csi_gpio_pin_write(&g, GPIO_PIN_LOW);
    }
    else
    {
        csi_gpio_pin_write(&g, 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, "led");
		LOGI(TAG,"led powerstate:%d;\r\n",str_value->valueint);
		led_refreshed(str_value->valueint);
		res_data.led = str_value->valueint;
		cJSON_Delete(str_json);//释放内存 	
		return 1;
	}
	
}

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 yun_app(void)
{
    int ret = -1;

//    board_yoc_init();
    led_pin_init();

    /* 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)
	{
		iot_con_flag = 1;
		printf("connect iot success\n");
	}else
	{
		iot_con_flag = 0;
		printf("connect iot error\n");
	}
	return(0);
}

注意在编辑上报字符串中,\的数量,我开始没注意,少敲了一个,导致数据上传出错,查找了好长时间才发现。

在数据更新任务中添加属性上报函数调用,此处由于屏幕更新较快,我做了一个累加,将上传频次降低。代码如下。

static void res_update_task(void *arg)
{
	char cdata[10] = { 0 };
	int time_num = 0;
	
	while(1)
	{
		res_data.noise = sound_max / 15;  //此处系数用于校准分贝大小
		if(res_data.noise > 100)
			res_data.noise = 100;
			
		sprintf((char*)cdata, "%.1fC", res_data.temp);//格式化输出 浮点数转成字符串输出
		lv_label_set_text_fmt(pGui_label_temp,"%s", (const char*)cdata);
		
		sprintf((char*)cdata, "%.1f%%", res_data.humi);//格式化输出 浮点数转成字符串输出
		lv_label_set_text_fmt(pGui_label_humi,"%s", (const char*)cdata);
		
		lv_label_set_text_fmt(pGui_label_noise, "%ddB", res_data.noise);
		
		lv_bar_set_value(pGui_bar_noise, res_data.noise+1, LV_ANIM_OFF);
		
		time_num++;
		if(time_num > 10)
		{
			iot_upload();//更新云端数据		
			time_num = 0;
		}
		
		aos_msleep(200);
	}
}

整个工程编译好后下载、运行,从云端就能看到数据更新了。如下图。

8、上传成功

通过设备管理界面的在线调试功能,还可以控制指示灯开关,如下图。

9、在线调试

本次作品单片机端的预期功能基本都实现完成,接下来在云平台设计一个web应用,用于展示采集数据,就大功告成了。

最新回复

要完成一个项目真的是细节化比较多,没有基础知识根本学不来   详情 回复 发表于 2022-4-25 23:22
点赞 关注
 
 

回复
举报

7608

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

阿里这个平台要钱吗?

点评

做演示,不要钱  详情 回复 发表于 2022-4-25 09:47
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

281

帖子

7

TA的资源

一粒金砂(高级)

板凳
 
freebsder 发表于 2022-4-25 09:36 阿里这个平台要钱吗?

做演示,不要钱

 
 
 

回复

2万

帖子

74

TA的资源

管理员

4
 

哈哈 加油:)

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 
 

回复

4854

帖子

3

TA的资源

版主

5
 

要完成一个项目真的是细节化比较多,没有基础知识根本学不来

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表