手把手stm32与Onenet联网配置步骤

本文附件

联网附件:

https://wwz.lanzoul.com/iCQ3P1y5yx7a

本工程全部文件:

https://ww0.lanzoul.com/imskP25ct2de

注意事项:

(1) 设备不在线, 是 容量不达标, 启动配置文件配置成 800即可

(2) 服务器在线, 但是上传属性undefine,

调试:核实变量标识符是否对应, 还有上传变量类型是否对应(调试方法,单个下发,逐个调试)

(3) 下发信息不成功,

调试:核实下发信息时,cjson拆包变量是否对应,是否赋值本地变量 (调试方法,单个下发,逐个调试)

(4)在了解完整个流程后, 可以通过修改服务器和key值,以及服务器变量,进行快速使用示例工程. 无需重复构建

引言目录

本文分为三部分

(1)stm32工程创建

(2)服务器配置对应变量

(3)单片机打包(上传变量):

(4)单片机拆包(解析下发变量):

一. stm32工程创建

(1)stm32工程创建:

1.打开keil5软件,

点击 project-> New Uvison project

image-20240511090508419

2.然后桌面随便建立一个文件夹, 随便起一个名字,不要有空格

image-20240511092119796

3.选择芯片 ,这里用的是 stm32f103c8t6 ,点击确定

image-20240511092241692

4.选择启动文件(后续用到那个选哪个),先只选最基本的

image-20240511092447248 image-20240511092506710

5.点击ok , 然后修改一下启动文件的缓冲区大小(onenet会用到),(如果是只读,去文件夹修改其权限属性)

image-20240511092709193

5.工程创建

(1)在keil的工程目录下, 新建文件夹

Source_code (代表源码存放位置)

image-20240511093452338

(2)在Source_code 下新建 User (代表main函数存放位置)

新建Net代表 网络配置存放位置

然后把 网络配置文件,全黏贴到 Net里面

image-20240511093736285 image-20240511094249365

(3)把文件夹加入工程

image-20240511094706358 image-20240511094801865 image-20240511094856587

接着加入, 把联网的五个文件夹路径,分别加入

image-20240511094940040 image-20240511095045420

(4)这时候发现工程,没有User等文件夹, 是因为我们没有添加文件,

image-20240511095555869

(5)可以看到工程已经有了User, 后续再,以此类推,

现在逐步进行

image-20240511095704898

(6)编译器选择 version 5

image-20240511103820008

(2)stm32上传变量确认

示例程序, 上传一个可以修改的

int temp_th (温度阈值)

_Bool led (台灯)

main.c

#include "stm32f10x.h"                  // Device header

int temp_th; //(温度阈值)

_Bool led;	//(台灯)
int main()
{
	temp_th = 1;
	led = 1;
	while(1)
	{
		
		
	}
	return 0;
}	

二. 服务器配置对应变量

(1)登录onenet官网:产品开发 - OneNET物联网平台 (10086.cn)

(2)产品开发 ->创建产品

image-20240511104100540

(3)其他行业

image-20240511104124838

(4)设备接入等信息

image-20240511104223905

(5)创建产品属性:产品开发->设置物模型->添加自定义功能节点

image-20240511104308851

image-20240511104351293

(6)根据上传变量进行填写

温度阈值:

image-20240511104448661

台灯:

image-20240511104529217

(7)保存

(8)创建产品

image-20240511104656266 image-20240511104735792

服务器信息

image-20240511104924072

(1)产品id:EeFC4dZQBP

(2)设备名称:d1

(3)设备秘钥:(设备管理->设备->详情->设备秘钥)

YzN6UlBJTXg0MndmbTRQUlBCZ0F0U1A3RnA2aEJ3bkk=

image-20240511105018863

跳转单片机配置代码

三. 单片机打包(上传变量):

(1) 配置 Uart串口工具

1.添加文件

image-20240511105247631

2.增加库函数

image-20240511105415502

3.引入uart.h

image-20240511105632380

初始化:

image-20240511105734354

(2)初始化wifi:ESP32-01s

1.引入wifi文件,

image-20240511105838773

2.导入

image-20240511105912160

定义

#define ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883\r\n"
image-20240511145638433

3.wifi串口初始化

	Delay_Init();//滴答定时器初始化
	uart1_init(115200);//串口1,调试用
	uart2_Init(115200);	//串口2,驱动ESP8266用
	ESP8266_Init();//wifi初始化
image-20240511130347622

4.wifi配置

回去

image-20240511130504013

5.发现文件里都有delay.c

user里面添加delay.c delay.h

image-20240511110008065

delay.h

#ifndef _DELAY_H_
#define _DELAY_H_



#include "stm32f10x.h"



void Delay_Init(void);

void DelayUs(unsigned short us);

void DelayXms(unsigned short ms);

void DelayMs(unsigned short ms);
void delay(uint32_t t);

void delay_us(u32 us);
void delay_ms(u32 ms);
#endif

delay.c

/**
	************************************************************
	************************************************************
	************************************************************
	*	文件名: 	delay.c
	*
	*	作者: 		张继瑞
	*
	*	日期: 		2016-11-23
	*
	*	版本: 		V1.0
	*
	*	说明: 		利用systick做阻塞式延时
	*
	*	修改记录:	
	************************************************************
	************************************************************
	************************************************************
**/

//单片机头文件
#include "stm32f10x.h"

//delay头文件
#include "delay.h"


//延时系数
unsigned char UsCount = 0;
unsigned short MsCount = 0;


/*
************************************************************
*	函数名称:	Delay_Init
*
*	函数功能:	systick初始化
*
*	入口参数:	无
*
*	返回参数:	无
*
*	说明:		
************************************************************
*/
void Delay_Init(void)
{

	SysTick->CTRL &= ~(1 << 2);		//选择时钟为HCLK(72MHz)/8		103--9MHz
	
	UsCount = 9;					//微秒级延时系数
	
	MsCount = UsCount * 1000;		//毫秒级延时系数

}

/*
************************************************************
*	函数名称:	DelayUs
*
*	函数功能:	微秒级延时
*
*	入口参数:	us:延时的时长
*
*	返回参数:	无
*
*	说明:		此时钟(21MHz)最大延时798915us
************************************************************
*/
void DelayUs(unsigned short us)
{

	unsigned int ctrlResult = 0;
	
	us &= 0x00FFFFFF;											//取低24位
	
	SysTick->LOAD = us * UsCount;								//装载数据
	SysTick->VAL = 0;
	SysTick->CTRL = 1;											//使能倒计数器
	
	do
	{
		ctrlResult = SysTick->CTRL;
	}
	while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16)));	//保证在运行、检查是否倒计数到0
	
	SysTick->CTRL = 0;											//关闭倒计数器
	SysTick->VAL = 0;

}

/*
************************************************************
*	函数名称:	DelayXms
*
*	函数功能:	毫秒级延时
*
*	入口参数:	ms:延时的时长
*
*	返回参数:	无
*
*	说明:		
************************************************************
*/
void DelayXms(unsigned short ms)
{

	unsigned int ctrlResult = 0;
	
	if(ms == 0)
		return;
	
	ms &= 0x00FFFFFF;											//取低24位
	
	SysTick->LOAD = ms * MsCount;								//装载数据
	SysTick->VAL = 0;
	SysTick->CTRL = 1;											//使能倒计数器
	
	do
	{
		ctrlResult = SysTick->CTRL;
	}
	while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16)));	//保证在运行、检查是否倒计数到0
	
	SysTick->CTRL = 0;											//关闭倒计数器
	SysTick->VAL = 0;

}

/*
************************************************************
*	函数名称:	DelayMs
*
*	函数功能:	微秒级长延时
*
*	入口参数:	ms:延时的时长
*
*	返回参数:	无
*
*	说明:		多次调用DelayXms,做到长延时
************************************************************
*/
void DelayMs(unsigned short ms)
{

	unsigned char repeat = 0;
	unsigned short remain = 0;
	
	repeat = ms / 500;
	remain = ms % 500;
	
	while(repeat)
	{
		DelayXms(500);
		repeat--;
	}
	
	if(remain)
		DelayXms(remain);

}

void delay(uint32_t t)
{
	while(t--);
}	

void delay_us(u32 us)//微秒
{
	SysTick_Config(72);
	while(us-->0)
	{
		while(!((SysTick->CTRL)&(1<<16)));
	}
	SysTick ->CTRL&=~SysTick_CTRL_ENABLE_Msk;
}

void delay_ms(u32 ms)//毫秒
{
	SysTick_Config(72000);
  while(ms-->0)
	{
		while(!((SysTick->CTRL)&(1<<16)));
	}
	SysTick ->CTRL&=~SysTick_CTRL_ENABLE_Msk;
}

  1. 发现delay.c里面有中断, 加入中断的库函数

    image-20240511110257371

(3)配置onenet联网文件

wifi已经配置成功,下面配置链接onenet服务器

1.导入onenet配置文件

image-20240511130932868 image-20240511131040411 image-20240511131145551
  1. main.c主函数里面, 链接onetnet
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
		DelayXms(500);
	
	while(OneNet_DevLink())			//接入OneNET
		DelayXms(500);	
	
	OneNET_Subscribe();				//解析onenet下发指令	
image-20240511130722902
  1. 要想链接成功, onenet里面的服务器配置也要对应

  2. 进入onenet.c, 定义的属性, 进行替换

    服务器信息(ctrl 加鼠标左键,快速跳转)

image-20240511131405025

回来

4.回到主函数, 进行上传变量

定义发送间隔

unsigned short timeCount = 0; //发送间隔变量

image-20240511145150447

main.c主函数, 定时上传, 延时10ms, 100次就是1s

72Mhz = 7200,0000次,(1s)

10ms,就是 7200,00次, 换算十六进制为 0xAFC80

		//打包上传
		if(++timeCount >= 100)
		{
			
			OneNet_SendData();	
			timeCount = 0;
			ESP8266_Clear();
		}
		delay(0xAFC80);//延时10ms
image-20240511145007907

5.先编译运行,鼠标按下f12, 跳转OneNet_SendData();

image-20240511150432185

image-20240511150405663

6.就会来到上传变量的位置

image-20240511150533786

7.引入上传变量

image-20240511150947170

8.严格按照下面格式进行填写:

image-20240511151358103

9.强调:

最后一项,后面没逗号, 之前都有逗号

image-20240511151503105

代码摘录:

extern int temp_th;

extern _Bool led;			


unsigned char OneNet_FillBuf(char *buf)
{

	char text[48];

	memset(text, 0, sizeof(text));

	strcpy(buf, "{\"id\":\"123\",\"params\":{");

	memset(text, 0, sizeof(text));
	sprintf(text, "\"temp_th\":{\"value\":%d},", temp_th);
	strcat(buf, text);

	memset(text, 0, sizeof(text));
	sprintf(text, "\"led\":{\"value\":%s}", led ? "true" : "false");
	strcat(buf, text);



	strcat(buf, "}}");

	return strlen(buf);

}

四. 单片机拆包(解析下发变量):

(1)检测是否有下发信息

定义接受判断变量

image-20240511170513969
unsigned char *dataPtr = NULL;	//标志位, 是否接受到onenet发送的数据
image-20240511170548441

代码摘录:

//检测是否有下发信息
dataPtr = ESP8266_GetIPD(0);
if(dataPtr != NULL)
{
	OneNet_RevPro(dataPtr);
  //UsartPrintf(USART_DEBUG, "6666666666\r\n");
}

(2)配置CJSON拆包

1.编译,运行 ,然后f12跳转OneNet_RevPro(dataPtr);

2.这里就是接受数据包的函数

我们在这里利用cjson拆包

image-20240511170909169

3.在此函数内,定义拆包所需要的cjson变量

image-20240511171707354

4.①接下来解析原始字符串数据到raw_jason

raw_jason = cJSON_Parse(req_payload);//解析原始字符串数据到raw_jason

② 从处理的cjson数据中,从raw_jason中提取params字符段到params_jason

params_jason=cJSON_GetObjectItem(raw_jason,"params");
image-20240511171922249

5.然后再从params_jason中提取要操作的器件,

image-20240511172121158
temp_th_jason = cJSON_GetObjectItem(params_jason,"temp_th");
				
led_jason =cJSON_GetObjectItem(params_jason,"led");

6.判断对应cjson 标识符变量 是否为空, 不空,则代表有对应的下发信息

image-20240511172421748

布尔类型, 需要对照其变量

image-20240511172618263
//判断对应cjson 标识符变量 是否为空, 不空,则代表有对应的下发信息

if(temp_th_jason != NULL)
{
	temp_th = temp_th_jason->valueint;
}

if(led_jason != NULL)
{
	if(led_jason->type == cJSON_True) 
	{
		led = 1;
	}
	else
	{
		led = 0;
	}
}

7.末尾释放解析字符串空间

cJSON_Delete(raw_jason);
image-20240511172846712

此函数代码备份:

void OneNet_RevPro(unsigned char *cmd)
{
	
	char *req_payload = NULL;
	char *cmdid_topic = NULL;
	
	unsigned short topic_len = 0;
	unsigned short req_len = 0;
	
	unsigned char qos = 0;
	static unsigned short pkt_id = 0;
	
	unsigned char type = 0;
	
	short result = 0;
	
	//原始数据 -> cjson数据
	cJSON *raw_jason;
	// cjson中摘出标识符变量
	cJSON *params_jason;

	//这里定义 cjson格式的变量名,例如 *led_jason
	cJSON *led_jason,*temp_th_jason;
	
	type = MQTT_UnPacketRecv(cmd);
	//UsartPrintf(USART_DEBUG, "688\r\n");
	switch(type)
	{
		case MQTT_PKT_PUBLISH:																//接收的Publish消息
//			UsartPrintf(USART_DEBUG, "689\r\n");
			result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
			
			if(result == 0)
			{

				
				UsartPrintf(USART_DEBUG, "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",
																	cmdid_topic, topic_len, req_payload, req_len);
				
				//将原始字符串信息,转化成cjson格式
				raw_jason = cJSON_Parse(req_payload);//解析原始字符串数据到raw_jason
				//从raw_jason中提取params字符段到params_jason
				params_jason = cJSON_GetObjectItem(raw_jason,"params");
				//然后再从params_jason中提取要操作的器件,

				temp_th_jason = cJSON_GetObjectItem(params_jason,"temp_th");
				
				led_jason = cJSON_GetObjectItem(params_jason,"led");
				
				//判断对应cjson 标识符变量 是否为空, 不空,则代表有对应的下发信息

				if(temp_th_jason != NULL)
				{
					temp_th = temp_th_jason->valueint;
				}

				if(led_jason != NULL)
				{
					if(led_jason->type == cJSON_True) 
					{
						led = 1;
					}
					else
					{
						led = 0;
					}
				}
				
				
				
				cJSON_Delete(raw_jason);
				
			}
			
		case MQTT_PKT_PUBACK:														//发送Publish消息,平台回复的Ack
//			UsartPrintf(USART_DEBUG, "111\r\n");
			if(MQTT_UnPacketPublishAck(cmd) == 0)
//				UsartPrintf(USART_DEBUG, "Tips:	MQTT Publish Send OK\r\n");
			
		break;
		
		case MQTT_PKT_SUBACK:																//发送Subscribe消息的Ack
//			UsartPrintf(USART_DEBUG, "222\r\n");
			if(MQTT_UnPacketSubscribe(cmd) == 0)
				UsartPrintf(USART_DEBUG, "Tips:	MQTT Subscribe OK\r\n");
			else
				UsartPrintf(USART_DEBUG, "Tips:	MQTT Subscribe Err\r\n");
		
		break;
		
		default:
//			UsartPrintf(USART_DEBUG, "333\r\n");
			result = -1;
		break;
	}
	
	ESP8266_Clear();									//清空缓存
	
	if(result == -1)
		return;
	

	
	if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH)
	{
		MQTT_FreeBuffer(cmdid_topic);
		MQTT_FreeBuffer(req_payload);
	}

}

五.测试

1.发现10个错误, 原来是mqtt的文件没有加入, 在品字设置里面, 把mqtt的所有文件加入,再次编译

2.编译运行, 没错, 烧录设置为st-link

image-20240511173631901

3.按照下图勾选

image-20240511173712073

4.确定, 然后烧录stm32最小系统板子

image-20240511173809084

5.esp32连线方法 , esp32上 RX 链接 PA2 ,TX链接PA3

GND–单片机gnd, vcc–单片机3.3v

6.手机wifi热点设置为 配置的

跳转单片机wifi设置(ctrl+鼠标左键跳转)

回来l

7.观察服务器设备在线情况

image-20240511175605991

8.模拟下发设备信息,再次观察属性是否被修改,并上传

image-20240511175640490

9.观察到, 台灯 0, 代表上传下发成功

image-20240511175740883

10.至此, 已经全部演示完毕, 后续的文件,是关于此过程的详细解析 和对应 app的开发及其思路

基于STM32OneNet智能养殖系统的设计是一种利用物联网技术实现智能养殖控制的解决方案。STM32是一款低功耗、高性能的微控制器芯片,而OneNet是一个云平台,可以实现设备之间的数据传输和远程控制。 智能养殖系统利用STM32进行数据采集和控制,例如温度、湿度、光照等环境参数的监测,以及喂食、补光、通风等动作的控制。传感器通过STM32进行数据采集,并将数据上传到OneNet云平台。用户可以通过手机APP或者电脑端的网页实时监测养殖环境的参数,并进行远程控制。比如,通过手机App可以实现远程调整喂食量、控制灯光亮度等。 OneNet平台提供了数据存储、分析和可视化的功能。用户可以通过OneNet平台存储已采集的养殖数据,进行数据分析和监测。同时,OneNet平台支持数据的可视化展示,用户可以通过直观的图表和报表了解养殖环境的变化和趋势,以便采取相应的措施。 基于STM32OneNet智能养殖系统可以提高养殖效率和降低养殖成本。通过实时监测和远程控制,可以及时发现和解决问题,减少人工干预的需求。同时,通过数据分析和可视化展示,可以对养殖过程进行优化和改进,提高养殖的效益。 总而言之,基于STM32OneNet智能养殖系统利用物联网技术实现养殖环境的自动化控制和数据管理,提高了养殖效率和可操作性。拥有智能养殖系统,养殖人员可以更加方便地管理和监控养殖过程,提高养殖环境的稳定性和产量,从而实现养殖产业的可持续发展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值