基于onenet物联网平台---宠物智能喂食监测系统

前言:最近在做一个小项目,这个东西也是我在寒假的时候刷到视频,有那种跑腿平台让人上门照顾宠物的,还比较火爆,我也从这里灵感触发,想着做个这个东西,正好参加一个比赛,一举两得,做这个还是学到了许多东西,我在网上查找,确实已经有这个玩意的落地,但是仅限于智能喂食,而我在此基础上进行创新,进行了一些扩展与延伸。

1.主板选用stm32mini,因为我这个其实不用太考虑占不占地方。

2.模块部分

(1)温湿度模块 :DHT11

0011 0101 0000 0000 0001 1000 0000 0100 0101 0001
湿度高 8 位 湿度低 8 位 温度高 8 位 温度低 8 位 校验位

校验位为“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据” 8bit 校验位等于所得结果的末 8 位

初始化:

u8 DHT11_Init(void)
{	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PG端口时钟
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				 //PG11端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);				 //初始化IO口
 	GPIO_SetBits(GPIOB,GPIO_Pin_1);						 //PG11 输出高
			    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
}

 结构体里设置所需变量

typedef struct
{
	uint8_t  humi_int;		//湿度的整数部分
	uint8_t  humi_deci;	 	//湿度的小数部分
	uint8_t  temp_int;	 	//温度的整数部分
	uint8_t  temp_deci;	 	//温度的小数部分
	uint8_t  check_sum;	 	//校验和
		                 
}DHT11_Data_TypeDef;

 将数据输入到对应的变量里面

uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
{  
	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			DHT11_Data->humi_int=buf[0];
			DHT11_Data->humi_deci=buf[1];
			DHT11_Data->temp_int=buf[2];
			DHT11_Data->temp_deci=buf[3];
			DHT11_Data->check_sum=buf[4];
		}
	}else return 1;
	 /*检查读取的数据是否正确*/
	if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
		 return SUCCESS;
	else 
		return ERROR;	    
}

 (2)MQ-2烟雾传感器

借助ADC将当前获取的24位数据转换为当前电压的模拟信号,然后借助公式转换为当前的室内CH4浓度。

初始化:

void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	  //使能ADC1通道时钟
 

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

  
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
//	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}	

 计算当前的CH4

float MQ7_PPM_Calibration(void)
{
	float RS = 0;
	float R0 = 0;
	RS = (3.3f - Get_Adc_Average(ADC_Channel_1,30)) / Get_Adc_Average(ADC_Channel_1,30) * RL;
	R0 = RS / pow(CAL_PPM / 98.322, 1 / -1.458f);//CAL_PPM  10  // 校准环境中PPM值
	return R0;
}
 
 //计算Smog_ppm
float Smog_GetPPM(void)
{
	float RS = (3.3f - Get_Adc_Average(ADC_Channel_1,30)) / Get_Adc_Average(ADC_Channel_1,30) * RL;
	float ppm = 98.322f * pow(RS/R0, -1.458f);
	return  ppm;
}

注: RL:每个传感器的数值不一样,需要查看对应的数据手册

算Ro的时候,注销到Smog_GetPPM(void)代码,算出标准的RO后注销掉MQ7代码,然后使用Smog_GetPPM(void)。然后更改define值。

 (3)舵机控制[PWM控制]

初始化:

void TIM2_PWM_Init(u16 arr, u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; //定义一个定时中断的结构体	
	TIM_OCInitTypeDef TIM_OCInitTypeStrue; //定义一个PWM输出的结构体
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟,在STM32中使用IO口前都要使能对应时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能通用定时器2时钟,A0引脚对应TIM2CHN1
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//引脚0
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出模式,定时器功能为A0引脚复用功能
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //定义该引脚输出速度为50MHZ
  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化引脚GPIOA0
	 
	TIM_TimeBaseInitStrue.TIM_Period=arr; //计数模式为向上计数时,定时器从0开始计数,计数超过到arr时触发定时中断服务函数
	TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数,决定每一个计数的时长
	TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数模式:向上计数
	TIM_TimeBaseInitStrue.TIM_ClockDivision=0; //一般不使用,默认TIM_CKD_DIV1
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStrue); //根据TIM_TimeBaseInitStrue的参数初始化定时器TIM2
	
	TIM_OCInitTypeStrue.TIM_OCMode=TIM_OCMode_PWM1; //PWM模式1,当定时器计数小于TIM_Pulse时,定时器对应IO输出有效电平
	TIM_OCInitTypeStrue.TIM_OCPolarity=TIM_OCNPolarity_High; //输出有效电平为高电平
	TIM_OCInitTypeStrue.TIM_OutputState=TIM_OutputState_Enable; //使能PWM输出
	TIM_OCInitTypeStrue.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OC1Init(TIM2, &TIM_OCInitTypeStrue); //根TIM_OCInitTypeStrue参数初始化定时器2通道1

	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); //CH1预装载使能
	
	TIM_ARRPreloadConfig(TIM2, ENABLE); //CH1预装载使能
	
	TIM_Cmd(TIM2, ENABLE); //使能定时器TIM2
}

然后通过TIM_SetCompare1(TIM2, PWM)和 TIM_SetCompare1(TIM2, PWM)来设置舵机的角度,实现食物的释放。

(4)HX711模块称重+压力传感器

初始化:

有一个地方困扰了我一个礼拜,害我白白又买了一个,我的IO口初始化,才开始是PB3和PB4,使得传感器传回来的数值一直都是最大值,也就是一直都是错误的。

后来发现这两个是特殊的IO口【手动哭泣】,具体可以看看这篇文章

STM32F1系列PB3,PB4,PA13,PA14,PA15用作普通IO口的特殊配置_stm32 pa14_qhw5279的博客-CSDN博客

void Init_HX711pin(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PF端口时钟

	//HX711_SCK
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;				 // 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB
	
	//HX711_DOUT
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
    GPIO_Init(GPIOB, &GPIO_InitStructure);  
	
	//GPIO_SetBits(GPIOB,GPIO_Pin_0);					//初始化设置为0
}

 测量的时候,需要有个起始重量,俗称毛重,任何变化都是基于毛重进行计算的。

所以在程序烧录进去的时候,大家需要保持上面无重量,这样毛重就是0,方便接下来的操作

void Get_Weight(void)
{
	HX711_Buffer = HX711_Read();
	if(HX711_Buffer > Weight_Maopi)			
	{
		Weight_Shiwu = HX711_Buffer;
		Weight_Shiwu = Weight_Shiwu - Weight_Maopi;				//获取实物的AD采样数值。
	
		Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue); 	//计算实物的实际重量
																		//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
																		//当发现测试出来的重量偏大时,增加该数值。
																		//如果测试出来的重量偏小时,减小改数值。
	}
	else
		Weight_Shiwu = 1;
}

 

 (5)定时器计时

void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(  //使能或者失能指定的TIM中断
		TIM3, //TIM3
		TIM_IT_Update ,
		ENABLE  //使能
		);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
							 
}

在定时器的中断里面,到设定的时间到了就进行定时喂食操作,所以在中断里面上传的是类似于flag的标志位,然后传入到主函数进行对应的操作。

(6)蜂鸣器【提醒这个程序开始了】

void Beep_init(void)
{
	GPIO_InitTypeDef GPIO_INITstrcture;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_INITstrcture.GPIO_Pin = GPIO_Pin_11;
	GPIO_INITstrcture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_INITstrcture.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_INITstrcture);
	GPIO_ResetBits(GPIOB,GPIO_Pin_11);
}
void fengmingqi()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_11);
	delay_us(100);
	GPIO_ResetBits(GPIOB,GPIO_Pin_11);
}

(7)esp8266使用MQTT协议连接到onenet平台

因为后续还需要数据的发送,所以需要使用MQTT协议,如果不需要则可以使用HTTP协议

设置AT模式,初始化当前wifi模块

AT+CWMODE == 设置为STA模式

AP模式下,WiFi模块产生热点,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。该模式对应TCP传输协议中的服务端(TCP Server)。
STA模式下,WiFi模块为连接到无线网络的终端(站点),可以连接到AP,一般无线网卡工作在STA模式下。该模式对应TCP传输协议中的客户端(TCP Client)。

AT+CWDHCP=x,y     dhcp,y=0关闭,1开启;x为0时是ap,1是station, 2是二者同时。

AT+CWJAP="SSID","PWD"    当作为station模式时,加入WIFI热点SSID,PWD是热点密码【这里注意当前的所连接的热点必须为2.4GHZ的频段】

AT+CIPSTART : 建立tcp连接

void ESP8266_Init(void)
{
	
	GPIO_InitTypeDef GPIO_Initure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	//ESP8266复位引脚
	GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Initure.GPIO_Pin = GPIO_Pin_13;					//GPIOC13-复位
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_Initure);
	
	GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);
	delay_ms(250);
	GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
	delay_ms(500);
	
	ESP8266_Clear();
	
// 	UsartPrintf(USART_DEBUG, "1. AT\r\n");
	printf("1. AT\r\n");
	while(ESP8266_SendCmd("AT\r\n", "OK"))
		delay_ms(500);
	
	printf("2. CWMODE\r\n");
	while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))
		delay_ms(500);
	
	printf( "3. AT+CWDHCP\r\n");
	while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))
		delay_ms(500);
	
	printf("4. CWJAP\r\n");
	while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))
		delay_ms(500);
	
	printf( "5. CIPSTART\r\n");
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
		delay_ms(500);
	
	printf("6. ESP8266 Init OK\r\n");

}

然后将esp8266连接当前的在onenet创建的设备

_Bool OneNet_DevLink(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};					//协议包

	unsigned char *dataPtr;
	
	_Bool status = 1;
	//打印一下信息产品id,鉴权信息,设备ID
   printf("OneNet_DevLink\r\nPROID: %s,	AUIF: %s,	DEVID:%s\r\n", PROID, AUTH_INFO, DEVID);
	
	if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 0, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0)
	{
		ESP8266_SendData(mqttPacket._data, mqttPacket._len);			//上传平台
		
		dataPtr = ESP8266_GetIPD(250);									//等待平台响应
		printf("\r\ndataPtr=%s\r\n",dataPtr);
		
		if(dataPtr != NULL)//如果平台返回数据不为空则
		{
			if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK)//	MQTT数据接收类型判断(connack报文)2
			{
				switch(MQTT_UnPacketConnectAck(dataPtr))//打印是否连接成功及连接失败的原因
				{
					case 0:printf( "Tips:	连接成功\r\n");status = 0;break;
					
					case 1:printf(  "WARN:	连接失败:协议错误\r\n");break;
					case 2:printf(  "WARN:	连接失败:非法的clientid\r\n");break;
					case 3:printf(  "WARN:	连接失败:服务器失败\r\n");break;
					case 4:printf(  "WARN:	连接失败:用户名或密码错误\r\n");break;
					case 5:printf(  "WARN:	连接失败:非法链接(比如token非法)\r\n");break;
					
					default:printf(  "ERR:	连接失败:未知错误\r\n");break;
				}
			}
		}
		
		MQTT_DeleteBuffer(&mqttPacket);								//删包
	}
	else
		printf( "WARN:	MQTT_PacketConnect Failed\r\n");
	
	return status;
	
}

对应的鉴权信息,设备ID,以及用户ID,需要可以自行在onenet平台查询。连接之后便可以在发送数据流给平台了。

发送数据给onenet

void OneNet_SendData(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};												//协议包
	
	char buf[128];
	
	short body_len = 0, i = 0;
	
	printf( "Tips:	OneNet_SendData-MQTT\r\n");
	
	memset(buf, 0, sizeof(buf));//清空数组内容
	
	body_len = OneNet_FillBuf(buf);																	//获取当前需要发送的数据流的总长度
	
	if(body_len)
	{
		if(MQTT_PacketSaveData(DEVID, body_len, NULL, 5, &mqttPacket) == 0)							//封包
		{
			for(; i < body_len; i++)
				mqttPacket._data[mqttPacket._len++] = buf[i];
			
			ESP8266_SendData(mqttPacket._data, mqttPacket._len);									//上传数据到平台
			printf( "Send %d Bytes\r\n", mqttPacket._len);
			
			MQTT_DeleteBuffer(&mqttPacket);															//删包
		}
		else
			printf(  "WARN:	EDP_NewBuffer Failed\r\n");
	}
	
}

 将OneNet_FillBuf(buf)获取的需要发送给onenet平台数据的数组长度计算出来,传入到ESP8266_SendData(mqttPacket._data, mqttPacket._len)

nsigned char OneNet_FillBuf(char *buf)
{
	
	char text[64];
	
	//LED0_FLAG=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5);//读取LED的开关状态(即对应引脚的)
	//LED1_FLAG=GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_5);
	
	//printf("LED0_FLAG_TYPE=%d\n",sizeof(LED0_FLAG));
	
	memset(text, 0, sizeof(text));
	
	strcpy(buf, ",;");
	
	memset(text, 0, sizeof(text));
	sprintf(text, "Tempreture,%d.%d;",temperatureH,temperatureL);
	strcat(buf, text);
	
	memset(text, 0, sizeof(text));
	sprintf(text, "Humidity,%d.%d;", humidityH,humidityH);
	strcat(buf, text);
	
//	memset(text, 0, sizeof(text));
//	sprintf(text, "now_weight;", LED0_FLAG);
//	strcat(buf, text);
//	
//	memset(text, 0, sizeof(text));
//	sprintf(text, "LED1,%d;", LED1_FLAG);
//	strcat(buf, text);
  memset(text, 0, sizeof(text));
	sprintf(text, "P_M,%f;",pm);
	strcat(buf, text);
	memset(text, 0, sizeof(text));
	sprintf(text, "W_S,%d;",Weight_Shiwu);
	strcat(buf, text);
	printf("buf_mqtt=%s\r\n",buf);
	return strlen(buf);

}

然后将“发送命令”发送给esp8266,随后当esp8266在串口接收到了“>”的字符,则可以开始发送数据了。如果不使用这个发送命令的指令,当数据比较多的时候以及次数多的时候,这样会比较麻烦,但是这样,只需要一次,就可以一直发送指令和数据,减少了不必要的麻烦。

void ESP8266_SendData(unsigned char *data, unsigned short len)
{

	char cmdBuf[32];
	
	ESP8266_Clear();								//清空接收缓存
	
	//先发送要发送数据的指令做准备
	sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);		//发送命令
	if(!ESP8266_SendCmd(cmdBuf, ">"))				//收到‘>’时可以发送数据
	{
		//既然准备完毕即可开始发送数据
		Usart_SendString(USART2, data, len);		//发送设备连接请求数据
	}

}

(8)onenet发送json命令,32设备进行接收

 设置一个data的数据包,里面存放需要发送的变量的数值,这样可以实现一次性发送多个数据流。而且进行了判错,当用户未发送重量的时候,我也可以根据我设定的初始值传入设备,防止程序卡死。

object=cJSON_GetObjectItem(root,"data");
					
					item=cJSON_GetObjectItem(object,"time");          //客户端定时下发的定时时间
					times_ing=item->valueint;
					
					item=cJSON_GetObjectItem(object,"weight1");        //自主喂养的重量
					if(item->valueint<-66666666)
					{
						weight1 = 300;                                   //防止用户没有设置重量
					}
					else
					{
						weight1=item->valueint;
					}
					item=cJSON_GetObjectItem(object,"weight2");        //定时喂养的重量
					if(item->valueint<-66666666)
					{
						weight2 = 300;                                    //防止用户没有设置重量
					}
					else
					{
						weight2=item->valueint;
					}
					item=cJSON_GetObjectItem(object,"flag");        	 //是否定时
					weishi_flag=item->valueint;
					//printf("weishi_flag = %d,weight2 = %d\r\n",weishi_flag,weight2);
					delay_ms(10);
					printf("\r\ntime=%d,weight1=%d\r\n,weight2=%d\r\n,flag = %d",times_ing,weight1,weight2,weishi_flag);
				}

onenet发送数据的格式为:

{"data":{"flag":1,"weight1":300,"weight2":288......}}

 后续我还会增加功能【未完待续!!!】

猜你喜欢

转载自blog.csdn.net/weixin_63032791/article/details/129961976