Onenet变量调试注意事项
原因
Onenet物联网平台, 是中国移动的物联网平台,因为免费, 受广大电子爱好者青睐。提供通用领域服务和行业业务建模基础模型,帮助开发者在线快速构建云上应用和进行应用托管;提供和物APP,用户不必关注底层实现,只需通过配置专属交互控制界面,即可完成智能家居场景APP应用开发,提高应用开发效率。
最近的一套stm32f103c8t6的联网调试工程, 因为配置问题, 遇到了种种的错误, 但是这些都是小细节.一步错步步错, 所以我用完善的步骤记录下来。 以后严格按照此步骤进行,杜绝错误。
创建变量
我们要提取项目的属性, 需要提前想好要定义的变量, 最好建立一个记事本

温度: temp
int temp (0~100℃)
湿度: humi
int humi (0~100%)
烟雾浓度: mq2
float mq2 (0~100%)
小灯: led
bool led (true or false)
云平台创建产品注意事项
上面就是创建产品的详细步骤, 我不过多赘述, 主要是看, 创建产品属性时候的细节
变量名贴合变量属性
(1)名称起名 和 变量 要有相关性, 最好使用 中文翻译过来的英文名字

标识符加数据类型的命名方式
(2)变量类型, 一般常用的就是(后续有拓展使用后, 本博客同步更新)
int32
float
bool
最容易失误的就是 float , 如果我们想传入小数点, 那么就会用float,但是如果我们传入的是整数值, 那么所有的变量就上传不成功
bool也一样, 我们需要上传的是 “true” 和 “false” 这两个字符串 , 配置失误也会整体上传不上
所以我想到了远古时期, 大家为了避免变量传入失误, 利用变量名加类型的命名方式, 顾名思义就是, 我们起了变量名之后, 后面再加上这个变量的类型, 从而避免上传失误
温度: temp
int temp (0~100℃)
标识符: i_temp
湿度: humi
int humi (0~100%)
标识符: i_humi
烟雾浓度: mq2
float mq2 (0~100%) (float 我们需要指定步长, 那就是小数点后几位,0.1 就是小数点后一位我们上传的时候, 也要格式化字符 0.1f , 严格按照格式, 不然就会出错)
标识符: f_mq2
小灯: led
bool led (true or false)
标识符: b_led
从而来提醒用户, 你传入的数值记得按照格式来
再次核对标识符和数据类型是否一致
经过上一步的命名方式, 我们就可以很轻松的识别到, 我们所需要的变量名的类型, 避免在配置的时候就配置错误
i – int32 , f – float , b – bool

创建设备,保存关键信息
记录设备名称
根据产品创建设备 ,
设备名称:Sky

记录产品id
产品id: 6b2szWl8IC
记录设备秘钥
设备秘钥:dEUwTElZYzluaTVQSVNZTnBhTlh3b1hYMHhoUGRvcFk=

keil本地工程快速配置
本文主要是弥补上文保姆级开发后, 后面再次开发直接复制黏贴, 所可能导致的错误, 所以我们来逐步掌控细节
服务器配置信息
设备信息
设备名称:Sky
产品id: 6b2szWl8IC
设备秘钥:dEUwTElZYzluaTVQSVNZTnBhTlh3b1hYMHhoUGRvcFk=
设备属性信息()回去(ctrl 加鼠标左键,快速跳转)
温度: temp
int temp (0~100℃)
标识符: i_temp
湿度: humi
int humi (0~100%)
标识符: i_humi
烟雾浓度: mq2
float mq2 (0~100%)
标识符: f_mq2
小灯: led
bool led (true or false)
标识符: b_led
打开示例项目
(1)进入main.c的main函数, 然后找到
OneNet_SendData();

(2)接着找到 OneNet_FillBuf(buf);

(3)然后就锁定到了上传 变量标识符的位置

(4)到这里了, 我们就要严格注意, 及其容易范错误, 接下来, 我们严格按照如下步骤进行调试
① 在main函数里面, 定义所需变量
int temp;
int humi;
float mq2;(float 我们需要指定步长, 那就是小数点后几位,0.1 就是小数点后一位我们上传的时候, 也要格式化字符 0.1f , 严格按照格式, 不然就会出错)
_Bool led; //注意keil里面bool类型是_Bool
② 然后复制这些变量, 按照刚才的方式跳转(ctrl 加鼠标左键,快速跳转), 去到 unsigned char OneNet_FillBuf(char *buf); 函数,
然后我们在上面 引入刚才定义的main.c的变量作为onenet.c的外部变量

③ 接下来就是重点
没错, 不要犹豫, 犹豫就会败北, 我们需要逐个调试, 所以建议直接从我这里复制代码, 破釜沉舟

调试重点
(1)先选中一个变量, 然后修改, 然后服务器测试上传是否成功
① 服务器对应 , 最后一项没有逗号 , 直接填符合类型和范围的数字
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, "\"i_temp\":{\"value\":%d}", 55);//只有一项, 所以这里没逗号
strcat(buf, text);
//********************变量填充区************************************
strcat(buf, "}}");
return strlen(buf);
}
② 这里变量调试成功了, 然后去配置Onenet配置信息

③ 配置手机wifi和esp8266.c
配置wifi的名称和密码
注意事项: 2.4g, 关闭wifi6协议
④ 然后我们保存,烧录(具体的连线过程, 请看手把手stm32与Onenet联网配置步骤,我们这里是快速复制黏贴)
我们这里烧录, 然后观察现象
发现, 工程有报错, 是之前测试的变量, 我们把它先注释了


⑤发现烧录没反应, 是stlink配置失误, 设置完, 重新烧录
(2)如果发现变量上传成功, 那么我们再次加入第二个变量
① 直接注释版本1 , 复制出版本2
② 然后修改, 复制成两个, 强调!强调!强调! 最后一项没逗号, 前面都有逗号, 所以我们加入新变量, 每次都是加入到开头, 减少错误, 所以第二步要手动加入逗号(后面就不要复制最后一项了, 复制前面的, 前面的带逗号, 直接加入开头即可,减少逗号错误)
截止目前, 说明你硬件没问题, 其他配置都没问题, 所有问题都局限在变量类型是否对应上
unsigned char OneNet_FillBuf(char *buf)
{
char text[48];
memset(text, 0, sizeof(text));
strcpy(buf, "{\"id\":\"123\",\"params\":{");
//********************变量填充区************************************
// /* 版本1 i_temp */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"i_temp\":{\"value\":%d}", 55);
// strcat(buf, text);
/* 版本2 i_temp + i_humi*/
memset(text, 0, sizeof(text));
sprintf(text, "\"i_humi\":{\"value\":%d},", 55);//这里有逗号, 后面都从这里复制
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"i_temp\":{\"value\":%d}", 55);//强调最后一项没逗号
strcat(buf, text);
//********************变量填充区************************************
strcat(buf, "}}");
return strlen(buf);
}
(3)后面是同理, 接着加入版本3, 如果没上传成功,就检查服务器属性的类型 和 上传的类型是否一致
%d 对应 int
%s 对应 "true" "false"
%f 对应 float
注意: _Bool 类型上传的是 %s 对应 "true" "false"
示例(三目运算符):
memset(text, 0, sizeof(text));
sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
strcat(buf, text);
(4)逐个更新版本, 下面是我写的示例,逐个添加变量, 逐个调试
extern int water_temp; //水温
extern int heat_temp_th; //加热阈值
extern int KeepWarm_th; //保温阈值
extern int heat_mode; //加热模式
uint16_t OneNet_FillBuf(char *buf)
{
char text[48];
memset(text, 0, sizeof(text));
strcpy(buf, "{\"id\":\"123\",\"params\":{");
///* 版本1 (只上传水温, 成功) */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
// strcat(buf, text);
///* 版本2 (水温 加 保温开关 成功) */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
//
// memset(text, 0, sizeof(text));
// sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
// strcat(buf, text);
///* 版本3 (水温 加 保温开关 加 保温阈值 成功) */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_th\":{\"value\":%d},", 50);
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
//
// memset(text, 0, sizeof(text));
// sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
// strcat(buf, text);
///* 版本4 (水温 加 保温开关 加 保温阈值 加热开关 成功) */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"heat_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_th\":{\"value\":%d},", 50);
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
//
// memset(text, 0, sizeof(text));
// sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
// strcat(buf, text);
///* 版本5 (水温 加 保温开关 加 保温阈值 加热开关 加热模式成功) */
// memset(text, 0, sizeof(text));
// sprintf(text, "\"heat_mode\":{\"value\":%d},", 1);
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"heat_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_th\":{\"value\":%d},", 50);
// strcat(buf, text);
// memset(text, 0, sizeof(text));
// sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
// strcat(buf, text);
//
// memset(text, 0, sizeof(text));
// sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
// strcat(buf, text);
/* 版本6 (水温 加 保温开关 加 保温阈值 加热开关 加热模式 加热阈值 成功) */
memset(text, 0, sizeof(text));
sprintf(text, "\"heat_temp_th\":{\"value\":%d},", 88);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"heat_mode\":{\"value\":%d},", 1);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"heat_button\":{\"value\":%s},", 1 ? "true" : "false");
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"KeepWarm_th\":{\"value\":%d},", 50);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"KeepWarm_button\":{\"value\":%s},", 1 ? "true" : "false");
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"water_temp\":{\"value\":%d}", 66);
strcat(buf, text);
strcat(buf, "}}");
return strlen(buf);
}
float上传失败问题
Onenet对变量上传严格控制, 我也是按照上面的一步一步的来调试发现的
如图
比如烟雾浓度,

我们这里设置了步长后, 就是小数点后一位, 那么上传就应该变为
memset(text, 0, sizeof(text));
sprintf(text, "\"mq2\":{\"value\":%0.1f},", mq2);
strcat(buf, text);
这里 %0.1f 就把我们输入的数据, 格式化成了0.1小数点后一位, 不然我们就成功不了, 注意!
期待结果
只要上面的变量上传成功, 就说明你配置没问题, 以后如果出现问题,就是线松了, 或者你传入的变量类型不对, 你直接去找就行了。
后续如果变量上传太多, 造成溢出, 请查看下面博客, 修改 数组大小