STM32+ESP8266+ONENET+微信小程序上传数据下发指令避坑指南

之前只做过类似的但是以为这种烂大街的功能应该不难结果还是踩了不少坑,记录几个需要注意的点

1、创建产品的时候选择onejson,自定义方案。这样选择的就是物模型,之后可以去使用物模型的API调试。

2、设置物模型

大概有以下几种比较常用的,int32,float,enum。enum设置的属性都是到时候用来做指令下发的,其余是上传传感器数据的。要注意onenet平台接受的是json格式数据,而且上传的数据格式必须与你设置的对应上。下面给了个OneNet_FillBuf示例。id不用改,主要是temper标识符和value后面的格式 %d 需要和你设置的物模型对应上

cpp 复制代码
unsigned char OneNet_FillBuf(char *buf)
{
	
	char text[48];
	
	strcpy(buf,"{\"id\":\"1124\",\"params\":{");

	memset(text,0,sizeof(text));
	sprintf(text,"\"temper\":{\"value\":%d},",sensorData.temp);
	strcat(buf,text);
	
	memset(text,0,sizeof(text));
	sprintf(text,"\"humidity\":{\"value\":%.2f},",sensorData.humidity);
	strcat(buf,text);
	
	memset(text,0,sizeof(text));
	sprintf(text,"\"tvoc\":{\"value\":%d},",sensorData.tvoc);
	strcat(buf,text);
	
	memset(text,0,sizeof(text));
	sprintf(text,"\"light\":{\"value\":%d},",sensorData.light);
	strcat(buf,text);
	
	memset(text,0,sizeof(text));
	sprintf(text,"\"water_level\":{\"value\":%.2f}",sensorData.water_level);
	strcat(buf,text);

	strcat(buf,"}}");

	return strlen(buf);

}

//==========================================================
//	函数名称:	OneNet_SendData
//
//	函数功能:	上传数据到平台
//
//	入口参数:	type:发送数据的格式
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void OneNet_SendData(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};												//协议包
	
	char buf[256];
	
	short body_len = 0, i = 0;
	memset(buf, 0, sizeof(buf));//清空数组内容
	
	body_len = OneNet_FillBuf(buf);	//获取当前需要发送的数据流的总长度
	//printf("%s\r\n",buf);
	if(body_len)
	{
		if(MQTT_PacketSaveData(DEVICE_NAME, body_len, NULL, 5, &mqttPacket) == 0)							//封包
		{
			for(; i < body_len; i++){
				mqttPacket._data[mqttPacket._len++] = buf[i];
			}
			ESP8266_SendData(mqttPacket._data, mqttPacket._len);									//上传数据到平台
			MQTT_DeleteBuffer(&mqttPacket);															//删包
		}
		else;
//			//printf(  "WARN:EDP_NewBuffer Failed\r\n");
	}
	
}

3、微信小程序实现传感器数据的同步显示和指令下发

这里主要用了这两个API,可以现在onenet云平台上调试一下,看正确的返回格式是什么样。

设备属性最新数据查询示例代码如下:

javascript 复制代码
//OneNet接入信息配置
const MQTT_Product_Id = "";
const MQTT_Device_Name = "";

// MQTT API配置
const MQTT_GET_URL = "https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=" + MQTT_Product_Id + "&device_name=" + MQTT_Device_Name;

const MQTT_POST_URL = "https://iot-api.heclouds.com/thingmodel/set-device-desired-property";

//使用token工具生成
const MQTT_Authorization = "";


onLoad: function() {
        // 页面加载时立即获取一次数据
        this.getinfo();
        // 设置定时器,每5秒获取一次数据
        this.setData({
            timer: setInterval(() => {
                this.getinfo();
            }, 5000)
        });
    },

getinfo: function() {
        var that = this;
        wx.request({
            url: MQTT_GET_URL,
            header: {
                "authorization": MQTT_Authorization
            },
            method: "GET",
            success: function(res) {
                console.log("获取成功", res);
                if (res.data && res.data.code === 0) {
                    // 解析设备数据
                    const deviceData = {};
                    res.data.data.forEach(item => {
                        if (item && item.identifier) {
                            deviceData[item.identifier] = item.value;
                        }
                    });
                    
                    // 更新页面数据
                    that.setData({
                        soilHumidity: deviceData['humidity'] + '%',
                        waterLevel: deviceData['water_level'] + 'm',
                        lightIntensity: deviceData['light'] + 'lux',
                        airQuality: deviceData['tvoc'],
                        envTemper: deviceData['temper'] + '℃',
                        lastUpdateTime: new Date().toLocaleTimeString()
                    });
                }
            },
            fail: function(err) {
                console.error('获取数据失败:', err);
            }
        });
    }

指令下发的示例代码如下:

javascript 复制代码
toggleMode() {
        const newMode = !this.data.autoMode;
        const modeValue = newMode ? 0 : 2;
        
        wx.request({
            url: MQTT_POST_URL,
            method: 'POST',
            header: {
                "authorization": MQTT_Authorization
            },
            data: {
                "product_id": MQTT_Product_Id,
                "device_name": MQTT_Device_Name,
                "params": {
                    "mode": modeValue
                }
            },
            success: res => {
                console.log("模式切换成功:", res);
                this.setData({
                    autoMode: newMode
                });
            },
            fail: err => {
                console.error("模式切换失败:", err);
                wx.showToast({
                    title: '模式切换失败',
                    icon: 'none'
                });
            }
        });
    },

4、微信小程序指令下发之后,单片机那边进行数据解析

单片机收到的数据是json格式的,所以只需要去寻找目标字段,然后读取后面的数值即可

cpp 复制代码
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;
	
	type = MQTT_UnPacketRecv(cmd);
	switch(type)
	{
		case MQTT_PKT_PUBLISH:																//接收的Publish消息
		
			result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
			if(result == 0)
			{
				
//				printf(  "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",
//																	cmdid_topic, topic_len, req_payload, req_len);				
			}
			
		case MQTT_PKT_PUBACK:														//发送Publish消息,平台回复的Ack
		
			if(MQTT_UnPacketPublishAck(cmd) == 0)
			{
				//printf(  "Tips:	MQTT Publish Send OK\r\n");
			}
			
		break;
		
		case MQTT_PKT_SUBACK:																//发送Subscribe消息的Ack
		
			if(MQTT_UnPacketSubscribe(cmd) == 0)
			{
				//printf(  "Tips:	MQTT Subscribe OK\r\n");
			}
			else
			{
				//printf(  "Tips:	MQTT Subscribe Err\r\n");
			}
		
		break;
		
		default:
			result = -1;
		break;
	}
	
	ESP8266_Clear();									//清空缓存
	
	if(result == -1)
		return;
	
	//解析req_payload数组中的值即可
	char *pump_ptr = strstr(req_payload, "\"pump\":");
	if (pump_ptr != NULL) {
		
	}
	

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

}
相关推荐
金色光环1 小时前
【Modbus学习笔记】stm32实现Modbus
笔记·stm32·学习
Ronin-Lotus4 小时前
嵌入式硬件与应用篇---寄存器GPIO控制
stm32·单片机·嵌入式硬件·微处理器原理与应用
HERR_QQ4 小时前
【unify】unify的微信小程序开发学习 (to be continued)
学习·微信小程序·小程序
星辰pid12 小时前
STM32控制四自由度机械臂(SG90舵机)(硬件篇)(简单易复刻)
stm32·单片机·嵌入式硬件·机械臂
mg66813 小时前
微信小程序入门实例_____快速搭建一个快递查询小程序
微信小程序·小程序
威桑13 小时前
STM32 专有名词缩写整合
stm32·单片机·嵌入式硬件
程序员柳14 小时前
基于微信小程序的校园二手交易平台、微信小程序校园二手商城源代码+数据库+使用说明,layui+微信小程序+Spring Boot
数据库·微信小程序·layui
SKYDROID云卓小助手15 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
所念皆星海91115 小时前
图灵完备之路(数电学习三分钟)----数据选择器与总线
嵌入式硬件·通信·数电
智者知已应修善业16 小时前
【51单片机节日彩灯控制器设计】2022-6-11
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机