[作品提交] 【平头哥RVB2601创意应用开发】作品提交

lugl4313820   2022-5-10 21:32 楼主

 

基于CH2601的冷链智能管理系统

作者:刘建华

  • 项目背景

作者长期从事免疫规划工作,免疫规划的重中之重,是疫苗的冷链管理,疫苗从生产到运输,最终接种到受接者身体,都有严格的储存要求。《中华人民共和国疫苗管理法》颁布以后,对疫苗储存以法律的方式规定,我们免疫规划人经常开玩笑说,一不小心就会违法。以往对温度监测都用人工的方式进行,这样疫苗管理人员没有休息,没有上班下班,都在担心疫苗保管会出什么问题。虽然现在也出现了很多疫苗的温度监测系统,但是一来产品卖得极其的贵,一个温度监测点动则几千。管理软件也不是很规范。作者从一个没有单片机的知识的医师,从零开始学习单片机知识,从原来的stm8L、到ESP8266,到现在的平头哥RVB2601,为这个领域提供廉价的解决方案。而且现在的温度监测系统没有对冷链设备的工作状况进行监测,有些报警功能,也是在温度超过报警条件下才有报警动作。我这次的作品考虑温度监测+冷链设备的电源电压、电流、功耗的连续监测。在服务器端分析出设备的运行状态,提前做出预警。

  • 作品简介

这次的作品设计是采集冷链设备的温度,冷链设备的工作电压、电流、功耗、温度。并通过互相网上传给服务器。服务器同时推送给用户APP。

RVB2601效果图:

image-20220510211117-1.png  

温度计:

image-20220510211117-2.png  

电源监控:

image-20220510211117-3.jpeg  

APP效果图:

image-20220510211117-4.jpeg  

  • 系统框图

image-20220510211117-5.png  

  • 各部分功能说明和解析(图文结合)
  1. 设备信息采集部分:由电能采集模块+无线串口模块组成,RVB向模块发送采集数据信号,采集模块返回实时信息。
  2. 温度采集部分:由GD32F310G、NTC热敏电阻、无线串口透传模块。每1秒钟采集一次数据,上传给RVB2601.
  3. 数据接收、显示、上传部分:RVB2601从无线串口模块接收到温度、电压、电流、功耗信息后,通过无线wifiW800上传给阿里云IOT平台。
  4. 阿里云IOT平台部分:负责接收RVB2601上传的数据,并且实时分发给用户APP。
  5. 用户APP部分:由阿里云提供的公共面板APP(云智能),向用户实时提供数据查询、历史数据浏览。接收异常信息。
  • 作品源码
/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */

#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include "oled.h"
#include "aos/hal/uart.h"
#include "drv/rtc.h"
#include "http.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);

#define UART_BUF_SIZE   40
#define UART_TX_TIMEOUT 100
#define UART_RX_TIMEOUT 500

extern uart_dev_t uart1;
u8g2_t u8g2;
char disp_buff[40];

void w800_data_receive_callback(int linkid, void *data, size_t len, char remote_ip[16], uint16_t remote_ports);

static csi_rtc_t g_rtc;
static aos_task_t app_task1_handle;
static aos_task_t app_task2_handle;

char disp_Vrms[10]; //显示电压值
char disp_Irms[10]; //显示电流值
char disp_PActive[10]; //显示功耗值
char disp_Frequency[10]; //显示频率值
char disp_Temper[10];//显示温度
/* data buffer */

char uart_data_buf[UART_BUF_SIZE];

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;
    }
}
/*
 * 功能:创建串口1接收任务,接收数据并把数据解析出来,存放在buff中,由U8g2显示函数定时刷新。上传服务器
 * 
 * 
 */
static void application_task1_entry(void *arg)
{
	int ret = -1;
	uint32_t rx_size = 0;
	float Irms=0;       //电流有效值
	float Vrms=0;       //电压有效值
	float Frequency=0;  //频率
	float PowerFactor=1;//功率因数
	float PActive=0;    //有功功率
	double W_KWH=0;     //累积功耗
	int n=0;
	const char *dev_id = "0";
	int pkt_id = 0;
	char report_buf[128];
    while (1) {
		ret = hal_uart_recv_II(&uart1, uart_data_buf, 24,
                               &rx_size, UART_RX_TIMEOUT);
	   // LOGD(TAG, "RECV len:%d data:%x",rx_size,uart_data_buf[0]);
        if (rx_size ==  24) 
		{
			if((uart_data_buf[0] == 0x55) && (uart_data_buf[1] == 0x55))
			{
				Vrms=(double)(((uint32_t)uart_data_buf[6]<<24)|((uint32_t)uart_data_buf[7]<<16)|((uint32_t)uart_data_buf[8]<<8)|((uint32_t)uart_data_buf[9]<<0))/1000.0;
				Irms=(double)(((uint32_t)uart_data_buf[10]<<24)|((uint32_t)uart_data_buf[11]<<16)|((uint32_t)uart_data_buf[12]<<8)|((uint32_t)uart_data_buf[13]<<0))/1000.0;
				PActive=(double)(((uint32_t)uart_data_buf[14]<<24)|((uint32_t)uart_data_buf[15]<<16)|((uint32_t)uart_data_buf[16]<<8)|((uint32_t)uart_data_buf[17]<<0))/1000.0;
				Frequency=(double)(((uint32_t)uart_data_buf[18]<<24)|((uint32_t)uart_data_buf[19]<<16)|((uint32_t)uart_data_buf[n++]<<8)|((uint32_t)uart_data_buf[20]<<0))/1000.0;
				sprintf(disp_Vrms,"%.1fV",Vrms);
				sprintf(disp_Irms,"%.2fA",Irms);
				sprintf(disp_PActive,"%.2fW",PActive);
				sprintf(disp_Frequency,"%.2fHz",Frequency);
				snprintf(report_buf,128,"{\\\"LightVolt\\\":%.1f,\\\"ActivePower\\\":%.2f,\\\"LightCurrent\\\":%.2f}",Vrms,PActive,Irms);
				w800_living_idmpp(dev_id, report_buf, &pkt_id);
				memset(uart_data_buf,0,24);			
			}
		
			else if((uart_data_buf[0] == 0x66) && (uart_data_buf[1] == 0x66))
			{
				if(uart_data_buf[2] == 0x01)
				{
					sprintf(disp_Temper,"-%d.%d C",uart_data_buf[3],uart_data_buf[4]);
					snprintf(report_buf,60,"\\\"temperature\\\":-%d.%d}",uart_data_buf[3],uart_data_buf[4]);
				}
				else
				{
					sprintf(disp_Temper,"%d.%d C",uart_data_buf[3],uart_data_buf[4]);
					snprintf(report_buf,60,"{\\\"temperature\\\":%d.%d}",uart_data_buf[3],uart_data_buf[4]);
				}
				
				w800_living_idmpp(dev_id, report_buf, &pkt_id);	
			}
		}
        aos_msleep(50);
		
    }

    aos_task_exit(0);
}


/*
 * 功能:创建串口1发送任务,向电源监控模块发送获取监控数据的命令
 * 
 * 
 * 
 */
static void application_task2_entry(void *arg)
{
	int ret = -1;
	uint8_t uart_tx_buf[] = {0x55,0x55,0x01,0x02,0x00,0x00,0xAD};
    while (1) {
		ret = hal_uart_send(&uart1, uart_tx_buf, sizeof(uart_tx_buf), UART_TX_TIMEOUT);
		if (ret == 0) {
			//printf("uart1 data send succeed !\n");
		}
        aos_msleep(1000);
    }
    aos_task_exit(0);
}


void test_getIP_task()
{
	char ssid[32];
	int bssid[6];
	int channel;
	int rssi;
	char disp[40];
	//先获取AP信息,判断是否联网
	//偿试连接到服务器
	//发送数据
	char ip[16];
	char gw[16];
	char mask[16];
	csi_rtc_time_t this_time;
	csi_error_t ret;
	int ipinfo = -1;
	
	while(1){

		
		//获取时间
		u8g2_ClearBuffer(&u8g2);
		u8g2_SetFont(&u8g2,u8g2_font_7x13_tr);
		u8g2_DrawStr(&u8g2,12,12,"Cold Manage SYS");//字符显示
		//u8g2_SendBuffer(&u8g2);
		u8g2_SetFont(&u8g2,u8g2_font_7x13_tr);
		u8g2_DrawStr(&u8g2,4,30,disp_Vrms);//显示电压值
		u8g2_DrawStr(&u8g2,80,30,disp_Irms);//显示电压值
		u8g2_DrawStr(&u8g2,4,50,disp_PActive);//显示功率值
		u8g2_DrawStr(&u8g2,80,50,disp_Temper);//显示频率值
		u8g2_SendBuffer(&u8g2);
		aos_msleep(500);
	}
}

void w800_data_receive_callback(int linkid, void *data, size_t len, char remote_ip[16], uint16_t remote_ports)
{
	
	uint8_t *buf;
	buf = (uint8_t *)data;
	if(len == 0)
	{
		return;
	}
	printf("receive data len: %d\r\n",len);
	printf("receive data:");
	for(uint16_t i = 0; i < len; i++)
	{
		printf("%c ",buf);
		
	}	
	printf("\r\n");
}


int main(void)
{

    board_yoc_init();
	
    LOGD(TAG, "%s\n", aos_get_app_version());
	u8g2Init(&u8g2);
	u8g2_SetFontMode(&u8g2, 1);
	u8g2_SetFont(&u8g2, u8g2_font_unifont_t_symbols);
	u8g2_ClearBuffer(&u8g2);
	u8g2_DrawStr(&u8g2,0,12,"RVB2601");//字符显示
	u8g2_SendBuffer(&u8g2);
	 sleep(5);
	aos_task_new("test_get ip", test_getIP_task,NULL, 1024);
	aos_task_new_ext(&app_task1_handle, "app_task1", application_task1_entry,
                     NULL, 4096, AOS_DEFAULT_APP_PRI);

    aos_task_new_ext(&app_task2_handle, "app_task2", application_task2_entry,
                     NULL, 4096, AOS_DEFAULT_APP_PRI);
					 
	iot_connect_dome();

    while (1) {
		
        aos_msleep(1000);
		
    }

    return 0;
}

 

七、项目总结

经过两个多月的对RVB2601的学习了解到了平头哥的操作系统、wifi联网、阿里IOT云平台的操作等等,对平头哥RVB2601的各项性能都有所了解。这是一款很有前途的芯片。

  • 其他

虽然用这个平台实现了基本的功能,但是还是跟我当时的设想有一定的差距,因为我本来就有现实的项目在运行。这里要说说这一系列的短板,希望对阿里云平台在今后发展有所帮助。

1、工单系统:遇到问题后,有工单系统是非常好的,但是这工单系统着实让人郁闷,发一个工单,半天没有回,回一下就是一连串什么什么的,一直在质疑提工单自己是不是有问题(我没问题找你干嘛、咱十几年的老工程师,没事会找你玩吗?)。效率极其低,我中途也想把板子退回去,中断评测,但是工作人员劝说下继续完成项目。我提了好些工单,基本是一个星期后才能完成,后面我要了即时联系的钉钉系统,处理效果才好一些。这里说阿里的技术支持确实需要加强。

2、W800这款wifi芯片其他的地方早就有MQTT协议开放了,但是平头哥这次结合没有把AT的协议做好,相比http,MQTT要轻量化,用户自己使用起来也方便一些。

3、我原来设计要走自己的服务器的,但是平头哥也没有给出https协议解决方法,所以跟我原来的设计也大有出入。

4、NTP这个是个大坑。我花了好几天也没整明白。

5、CDK也是坑了我好多的时间。里面的版本特别的多,让人一下子难以适应,目前的工程师都得用好几种IDE,但是这个CDK是最让我郁闷的一款IDE。举例:明明文件在那里,也include进来了,他就是说没有存在。还有刚刚使用时,CDK启动要十多分钟者能进去,动不动卡死。等等,希望平头哥以后的版本里需要改进。

6、还有博文系统,发一个博文来来回回让你修改十几次才通过,我们评测人员又不是拿你家的工资,这样要求是不是太严,让人想起就心烦!

7、APP的更新问题,面板修改后,需要一个小时到一天不等才能在手机端实时更新。发个工单,技术支持竞然说我操不正确,那为什么什么都没动,第二天,或者半天后自己更新了。看来阿里工单的技术支持也得自己去学习一下业务知识。让开发者白瞎了好多的宝贵时间。

总的来说,有过20年编程经验,6年单片机开发,有过十几款芯片的成功开发案例,虽然我说不编程的高手,但是也不是小白,这次使用平头哥,是让人最不爽的一次。纯粹为了当时提交申请时的承诺,花了很多无用功,交了一把作业。

最后,要感谢这次试用RVB2601的小伙伴们,在你们优秀的作品中,让我学习了很多知识,谢谢!

 

PS:演示视频

 

WeChat_20220622123148

 

 

 

 

 

 

 

回复评论 (11)

不错,将2款开发板的特点都集合到一起了。

点赞  2022-5-10 22:51

总结的身有同感!!!

点赞  2022-5-10 23:02
jinglixixi 发表于 2022-5-10 23:02 总结的身有同感!!!

是呀,感觉平头哥的东西太臃肿,一进去,满头雾水。

本帖最后由 lugl4313820 于 2022-5-11 07:07 编辑
点赞  2022-5-10 23:34

楼主已经做的很好啦

 

针对发帖,提供一个小窍门,先把博文在wps里编辑好格式,留出图片位置,然后发帖时直接粘贴过来就好,最后插入图片,你会发现发帖子不那么费事了。

点赞 (1) 2022-5-11 09:01

平头哥的平台还是用不习惯,希望他们能慢慢改进吧!

点赞  2022-5-11 09:10

请问楼主在文中说到“冷链设备”是集生产、储存、运输中用到设备的总和吗?

点赞  2022-5-11 10:23

请问这里电流监测是怎么做的呀?

点赞  2022-5-11 10:25
梦溪开物 发表于 2022-5-11 10:23 请问楼主在文中说到“冷链设备”是集生产、储存、运输中用到设备的总和吗?

冷链设备是从供应链的角度来定义的。各类产品有其独特性,产品的供应链也具有独特性;冷冻类产品,由于产品要求所处的环境通常为低温或低湿共同特性,所以称为冷冻产品,冷冻产品的供应链称为冷链;用于制造低温、低湿环境的设备,称为冷链设备。

具体的冷链设备有:低温冷库、常温冷库、低温冰箱、普通冰箱、冷藏车、冷藏箱、疫苗运输车、备用冰排等。

点赞  2022-5-11 18:42
引用: 梦溪开物 发表于 2022-5-11 10:25 请问这里电流监测是怎么做的呀?

某鱼上淘来的10块钱一个的模块。好象是个单相计量模块,还可以采集电流频率,累计功耗等等的东西。

点赞  2022-5-11 18:43

同感,CDK确实用的非常不爽

点赞  2022-5-13 13:41

顶顶,总结非常有共鸣,开发难度确实不小,为了完成项目坚持到最后就是成功!

点赞  2022-5-13 15:51
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复