伴随着网络技术,各种通讯技术,传感器技术的飞速发展,物联网技术成为了当今技术领域发展为迅速的技术。而物联网技术的核心仍然是以互联网技术为基础的,物联网是新一代信息技术的重要组成部分,也是信息化时代的重要发展阶段。物联网通过智能感知、识别技术与普适计算等通信感知技术,广泛应用于网络的融合中,也因此被称为继计算机、互联网之后世界信息产业发展的第三次浪潮。
本设计的模型来源于物流、矿山、高速公路等场合,车辆称重地螃的智能化升级要求,设计基于物联网的智能在线称重方案,开发智能称重控制器,合理选择部署多个重量传感器和必要的算法、通过wiff通信模块、gps定位模块,采集车辆重数据一地理位置信息,并通过网络发送至云平台,设计图形化ui界面展示称重、地图位置等重要信息,实现对称重系统的远程监测。
随着物联网技术的逐步发展和日趋成熟,物联网技术是一个大而广的应用技术,并非仅仅局限于延伸应用。相信对地磅来说必然会有更多创新的应用实践。总的来说,地磅现代化、信息化、智能化一定紧随物联网技术的发展,而物联网技术的发展也必将促使地磅兴起新的技术革命。
**设计的技术与硬件选项总结:**
(1)云端通信模块采用esp8266-wifi
(2)联网通信模块采用:esp8266
(3)gps模块:采用atgm336h双模gps模块
(4)电子秤模块:用于称重
(5)物联网云平台:采用华为云物联网平台
**设计总结:**
(1)采用esp8266连接onenet上传称重数据和gps数据到云端(采用http协议)
云端上显示2个数据:gps定位数据--地图显示,称重传感器的数据值
(2)3个称重传感器接一个秤面称重计算平均值
(3)本地oled显示屏显示gps经纬度数据、称重传感器的数据值。
(4)oled设计一个页面显示并设置当前的报警上限。通过按键进行加减
当称重的阀值超出了设置阀值,蜂鸣器报警。




## 2. 硬件选型
### 2.1 stm32f103c8t6
stm32f103c8t6是一款基于arm cortex-m 内核stm32系列的32位的微控制器,程序存储器容量是64kb,需要电压2v~3.6v,工作温度为-40°c ~ 85°c。

### 2.2 电子秤传感器

hx711 是一款专为高精度称重传感器而设计的24位a/d 转换器芯片。
### 2.3 esp8266-wifi

### 2.4 gps模块

### 2.5 蜂鸣器

## 3. 创建云端产品与设备
### 3.1 创建产品
地址:https://www.huaweicloud.com/?locale=zh-cn




### 3.2 创建设备
地址: https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/device/all-device


### 3.3 自定义模型数据
链接:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product/7211833377cf435c8c0580de390eedbe/product-detail/6277d70223aaf461a0f72a56
这个模型数据就是设备要上传的数据。





```cpp
{
"device_id": "6277d70223aaf461a0f72a56_weigh",
"secret": "12345678"
}
服务id: weigh
属性名称 数据类型 访问方式 描述
weigh int(整型) 可读 重量
gps string(字符串) 可读 gps定位信息
```
### 3.4 mqtt密匙生成
创建完产品、设备之后,接下来就需要知道如何通过mqtt协议登陆华为云服务器。
官方的详细介绍在这里:
https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#zh-cn_topic_0240834853__zh-cn_topic_0251997880_li365284516112
属性上报格式:
https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html


mqtt设备登陆密匙生成地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/


```cpp
deviceid 6277d70223aaf461a0f72a56_weigh
devicesecret 12345678
clientid 6277d70223aaf461a0f72a56_weigh_0_0_2022050814
username 6277d70223aaf461a0f72a56_weigh
password 0a3d097c6449b8526a562006a74c8c5e61ce63d6c831ea291560736a3332cf77
```
华为云物联网平台的域名是: `161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com`
华为云物联网平台的ip地址是:`121.36.42.100`
在软件里参数填充正确之后,就看到设备已经连接成功了。
接下来打开设备页面,可以看到设备已经在线了。


### 3.5 主题订阅与发布
```cpp
//订阅主题: 平台下发消息给设备
$oc/devices/6277d70223aaf461a0f72a56_weigh/sys/messages/down
//设备上报数据
$oc/devices/6277d70223aaf461a0f72a56_weigh/sys/properties/report
//上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
{"services": [{"service_id": "weigh","properties":{"gps":"lat:12.345,lng:45.678"}}]}
```
通过mqtt客户端软件模拟上报测试:

查看控制台页面,数据已经上传成功了。

### 3.6 应用侧开发
为了更方便的展示设备数据,与设备完成交互,还需要开发一个配套的上位机,官方提供了应用侧开发的api接口、sdk接口,为了方便通用一点,我这里采用了api接口完成数据交互,上位机软件采用qt开发。
帮助文档地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html
设备属性就是设备上传的传感器状态数据信息,应用侧提供了api接口,可以主动向设备端下发请求指令;设备端收到指令之后需要按照约定的数据格式上报数据;所以,要实现应用层与设备端的数据交互,需要应用层与设备端配合才能完成。


在使用接口时,最好先使用华为自己的调试接口测试。
https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=iotda&api=listproperties

上位机软件采用qt框架设计,qt是一个跨平台的c 图形用户界面应用程序框架。qt是一个1991年由qt company开发的跨平台c 图形用户界面应用程序开发框架。它既可以开发gui程序,也可用于开发非gui程序,比如控制台工具和服务器。简单来说,qt可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。
**qt星辰平台官网:** https://www.qt.io/

## 4. stm32设备端开发
### 4.1 程序下载

### 4.2 原理图

### 4.3 硬件接线
```cpp
(1)oled显示屏接线:
d0----(sck)------------------->>pb14
d1----(mosi)------------------>>pb13
res—(复位脚低电平有效)-------->>pb12
dc--(数据和命令控制管脚)------>>pb1
cs--(片选引脚)---------------->>pa7
gnd--------------------------->>gnd
vcc--------------------------->>3.3v或者5v
(2)atk-esp8266 wifi接线
pa2(tx)--rxd 模块接收脚
pa3(rx)--txd 模块发送脚
gnd---gnd 地
vcc---vcc 电源(3.3v~5.0v)
(3)外接蜂鸣器模块: 高电平响
beep----->pb8
(4)外接按键:
key1 -pb3 按下是低电平 清零
key2 -pb2 按下是低电平 翻页
key3 -pb6 按下是低电平 加
key4 -pb7 按下是低电平 减
(5)外接led灯模块:
led1-pb4 低电平亮
led2-pb5 低电平亮
(6)称重传感器1
vcc--->5v
sck--->pa4 时序控制脚--对stm32--输出模式
dt---->pa5 输出输出脚-对stm32--输入模式
gnd--->gnd
(7)称重传感器2
vcc--->5v
sck--->pa11 时序控制脚--对stm32--输出模式
dt---->pa12 输出输出脚-对stm32--输入模式
gnd--->gnd
(8)称重传感器3
vcc--->5v
sck--->pa6 时序控制脚--对stm32--输出模式
dt---->pa8 输出输出脚-对stm32--输入模式
gnd--->gnd
(9)gps模块接线说明
gnd----gnd
vcc---3.3v
pb11----gps_tx
pb10----gps_rx
(--)板载led灯:低电平亮
led1--pc13
beep2--pc14
(--)板载按键:
key1--pa0 按下为高电平
```
### 4.4 mqtt连接代码
```cpp
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include
#include "timer.h"
#include "bluetooth.h"
#include "esp8266.h"
#include "mqtt.h"
//华为物联网服务器的设备信息
#define mqtt_clientid "61b9ba3a2b2aa20288c1e7f1_qq1126626497_0_0_2021121510"
#define mqtt_username "61b9ba3a2b2aa20288c1e7f1_qq1126626497"
#define mqtt_password "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242"
//订阅与发布的主题
#define set_topic "$oc/devices/61b9ba3a2b2aa20288c1e7f1_qq1126626497_0_0_2021121510/sys/messages/down" //订阅
#define post_topic "$oc/devices/61b9ba3a2b2aa20288c1e7f1_qq1126626497_0_0_2021121510/sys/properties/report" //发布
char mqtt_message[200];//上报数据缓存区
int main()
{
u32 time_cnt=0;
u32 i;
u8 key;
led_init();
beep_init();
key_init();
usart1_init(115200);
timer1_init(72,20000); //超时时间20ms
usart2_init(9600);//串口-蓝牙
timer2_init(72,20000); //超时时间20ms
usart3_init(115200);//串口-wifi
timer3_init(72,20000); //超时时间20ms
usart1_printf("正在初始化wifi请稍等.\n");
if(esp8266_init())
{
usart1_printf("esp8266硬件检测错误.\n");
}
else
{
//非加密端口
usart1_printf("wifi:%d\n",esp8266_sta_tcp_client_mode("cmcc-cqvn","99pu58cb","121.36.42.100",1883,1));
}
//2. mqtt协议初始化
mqtt_init();
//3. 连接华为服务器
while(mqtt_connect(mqtt_clientid,mqtt_username,mqtt_password))
{
usart1_printf("服务器连接失败,正在重试...\n");
delay_ms(500);
}
usart1_printf("服务器连接成功.\n");
//3. 订阅主题
if(mqtt_subscribetopic(set_topic,0,1))
{
usart1_printf("主题订阅失败.\n");
}
else
{
usart1_printf("主题订阅成功.\n");
}
.........
```
### 4.5 esp8266代码
```cpp
#include "esp8266.h"
u8 esp8266_ip_addr[16]; //255.255.255.255
u8 esp8266_mac_addr[18]; //硬件地址
/*
函数功能: esp8266命令发送函数
函数返回值:0表示成功 1表示失败
*/
u8 esp8266_sendcmd(char *cmd)
{
u8 i,j;
for(i=0;i<10;i ) //检测的次数--发送指令的次数
{
usartx_stringsend(usart3,cmd);
for(j=0;j<100;j ) //等待的时间
{
delay_ms(50);
if(usart3_rx_flag)
{
usart3_rx_buffer[usart3_rx_cnt]='\0';
usart3_rx_flag=0;
usart3_rx_cnt=0;
if(strstr((char*)usart3_rx_buffer,"ok"))
{
return 0;
}
}
}
}
return 1;
}
/*
函数功能: esp8266硬件初始化检测函数
函数返回值:0表示成功 1表示失败
*/
u8 esp8266_init(void)
{
//退出透传模式
usartx_stringsend(usart3," ");
delay_ms(50);
return esp8266_sendcmd("at\r\n");
}
/*
函数功能: 一键配置wifi为ap tcp服务器模式
函数参数:
char *ssid 创建的热点名称
char *pass 创建的热点密码 (最少8位)
u16 port 创建的服务器端口号
函数返回值: 0表示成功 其他值表示对应错误值
*/
u8 esp8266_ap_tcp_server_mode(char *ssid,char *pass,u16 port)
{
char *p;
u8 i;
char esp8266_sendcmd[100]; //组合发送过程中的命令
/*1. 测试硬件*/
if(esp8266_sendcmd("at\r\n"))return 1;
/*2. 关闭回显*/
if(esp8266_sendcmd("ate0\r\n"))return 2;
/*3. 设置wifi模式*/
if(esp8266_sendcmd("at cwmode=2\r\n"))return 3;
/*4. 复位*/
esp8266_sendcmd("at rst\r\n");
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
/*5. 关闭回显*/
if(esp8266_sendcmd("ate0\r\n"))return 5;
/*6. 设置wifi的ap模式参数*/
sprintf(esp8266_sendcmd,"at cwsap=\"%s\",\"%s\",1,4\r\n",ssid,pass);
if(esp8266_sendcmd(esp8266_sendcmd))return 6;
/*7. 开启多连接*/
if(esp8266_sendcmd("at cipmux=1\r\n"))return 7;
/*8. 设置服务器端口号*/
sprintf(esp8266_sendcmd,"at cipserver=1,%d\r\n",port);
if(esp8266_sendcmd(esp8266_sendcmd))return 8;
/*9. 查询本地ip地址*/
if(esp8266_sendcmd("at cifsr\r\n"))return 9;
//提取ip地址
p=strstr((char*)usart3_rx_buffer,"apip");
if(p)
{
p =6;
for(i=0;*p!='"';i )
{
esp8266_ip_addr[i]=*p ;
}
esp8266_ip_addr[i]='\0';
}
//提取mac地址
p=strstr((char*)usart3_rx_buffer,"apmac");
if(p)
{
p =7;
for(i=0;*p!='"';i )
{
esp8266_mac_addr[i]=*p ;
}
esp8266_mac_addr[i]='\0';
}
//打印总体信息
usart1_printf("当前wifi模式:ap tcp服务器\n");
usart1_printf("当前wifi热点名称:%s\n",ssid);
usart1_printf("当前wifi热点密码:%s\n",pass);
usart1_printf("当前tcp服务器端口号:%d\n",port);
usart1_printf("当前tcp服务器ip地址:%s\n",esp8266_ip_addr);
usart1_printf("当前tcp服务器mac地址:%s\n",esp8266_mac_addr);
return 0;
}
/*
函数功能: tcp服务器模式下的发送函数
发送指令:
*/
u8 esp8266_serversenddata(u8 id,u8 *data,u16 len)
{
u8 i,j,n;
char esp8266_sendcmd[100]; //组合发送过程中的命令
for(i=0;i<10;i )
{
sprintf(esp8266_sendcmd,"at cipsend=%d,%d\r\n",id,len);
usartx_stringsend(usart3,esp8266_sendcmd);
for(j=0;j<10;j )
{
delay_ms(50);
if(usart3_rx_flag)
{
usart3_rx_buffer[usart3_rx_cnt]='\0';
usart3_rx_flag=0;
usart3_rx_cnt=0;
if(strstr((char*)usart3_rx_buffer,">"))
{
//继续发送数据
usartx_datasend(usart3,data,len);
//等待数据发送成功
for(n=0;n<200;n )
{
delay_ms(50);
if(usart3_rx_flag)
{
usart3_rx_buffer[usart3_rx_cnt]='\0';
usart3_rx_flag=0;
usart3_rx_cnt=0;
if(strstr((char*)usart3_rx_buffer,"send ok"))
{
return 0;
}
}
}
}
}
}
}
return 1;
}
/*
函数功能: 配置wifi为sta模式 tcp客户端模式
函数参数:
char *ssid 创建的热点名称
char *pass 创建的热点密码 (最少8位)
char *p 将要连接的服务器ip地址
u16 port 将要连接的服务器端口号
u8 flag 1表示开启透传模式 0表示关闭透传模式
函数返回值:0表示成功 其他值表示对应的错误
*/
u8 esp8266_sta_tcp_client_mode(char *ssid,char *pass,char *ip,u16 port,u8 flag)
{
char esp8266_sendcmd[100]; //组合发送过程中的命令
//退出透传模式
//usartx_stringsend(usart3," ");
//delay_ms(50);
/*1. 测试硬件*/
if(esp8266_sendcmd("at\r\n"))return 1;
/*2. 关闭回显*/
if(esp8266_sendcmd("ate0\r\n"))return 2;
/*3. 设置wifi模式*/
if(esp8266_sendcmd("at cwmode=1\r\n"))return 3;
/*4. 复位*/
esp8266_sendcmd("at rst\r\n");
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
/*5. 关闭回显*/
if(esp8266_sendcmd("ate0\r\n"))return 5;
/*6. 配置将要连接的wifi热点信息*/
sprintf(esp8266_sendcmd,"at cwjap=\"%s\",\"%s\"\r\n",ssid,pass);
if(esp8266_sendcmd(esp8266_sendcmd))return 6;
/*7. 设置单连接*/
if(esp8266_sendcmd("at cipmux=0\r\n"))return 7;
/*8. 配置要连接的tcp服务器信息*/
sprintf(esp8266_sendcmd,"at cipstart=\"tcp\",\"%s\",%d\r\n",ip,port);
if(esp8266_sendcmd(esp8266_sendcmd))return 8;
/*9. 开启透传模式*/
if(flag)
{
if(esp8266_sendcmd("at cipmode=1\r\n"))return 9; //开启
if(esp8266_sendcmd("at cipsend\r\n"))return 10; //开始透传
if(!(strstr((char*)usart3_rx_buffer,">")))
{
return 11;
}
//如果想要退出发送: " "
}
//打印总体信息
usart1_printf("当前wifi模式:sta tcp客户端\n");
usart1_printf("当前连接的wifi热点名称:%s\n",ssid);
usart1_printf("当前连接的wifi热点密码:%s\n",pass);
usart1_printf("当前连接的tcp服务器端口号:%d\n",port);
usart1_printf("当前连接的tcp服务器ip地址:%s\n",ip);
return 0;
}
/*
函数功能: tcp客户端模式下的发送函数
发送指令:
*/
u8 esp8266_clientsenddata(u8 *data,u16 len)
{
u8 i,j,n;
char esp8266_sendcmd[100]; //组合发送过程中的命令
for(i=0;i<10;i )
{
sprintf(esp8266_sendcmd,"at cipsend=%d\r\n",len);
usartx_stringsend(usart3,esp8266_sendcmd);
for(j=0;j<10;j )
{
delay_ms(50);
if(usart3_rx_flag)
{
usart3_rx_buffer[usart3_rx_cnt]='\0';
usart3_rx_flag=0;
usart3_rx_cnt=0;
if(strstr((char*)usart3_rx_buffer,">"))
{
//继续发送数据
usartx_datasend(usart3,data,len);
//等待数据发送成功
for(n=0;n<200;n )
{
delay_ms(50);
if(usart3_rx_flag)
{
usart3_rx_buffer[usart3_rx_cnt]='\0';
usart3_rx_flag=0;
usart3_rx_cnt=0;
if(strstr((char*)usart3_rx_buffer,"send ok"))
{
return 0;
}
}
}
}
}
}
}
return 1;
}
```
技术贴,学习一下
谢谢分享
学习了,感谢分享
感谢分享,改天尝试一下
2022-5-29 17:20
2022-5-30 16:47
谢谢分享
感谢分享
华为的iot确实很不错
感谢分享
谢谢分享