0 卖盘信息
BOM询价
您现在的位置: 首页 > 技术方案 >工业控制 > 基于32位微控制器STM32F103C8T6+华为云+ESP8266的智能称重系统硬件设计方案

基于32位微控制器STM32F103C8T6+华为云+ESP8266的智能称重系统硬件设计方案

来源: eet-china
2022-08-02
类别:工业控制
eye 6
文章创建人 拍明芯城

原标题:基于STM32+华为云的智能称重系统硬件设计方案

  伴随着网络技术,各种通讯技术,传感器技术的飞速发展,物联网技术成为了当今技术领域发展为迅速的技术。而物联网技术的核心仍然是以互联网技术为基础的,物联网是新一代信息技术的重要组成部分,也是信息化时代的重要发展阶段。物联网通过智能感知、识别技术与普适计算等通信感知技术,广泛应用于网络的融合中,也因此被称为继计算机、互联网之后世界信息产业发展的第三次浪潮。

  本设计的模型来源于物流、矿山、高速公路等场合,车辆称重地螃的智能化升级要求,设计基于物联网的智能在线称重方案,开发智能称重控制器,合理选择部署多个重量传感器和必要的算法、通过 WIFF 通信模块、GPS 定位模块,采集车辆重数据一地理位置信息,并通过网络发送至云平台,设计图形化 UI 界面展示称重、地图位置等重要信息,实现对称重系统的远程监测。

  随着物联网技术的逐步发展和日趋成熟,物联网技术是一个大而广的应用技术,并非仅仅局限于延伸应用。相信对地磅来说必然会有更多创新的应用实践。总的来说,地磅现代化、信息化、智能化一定紧随物联网技术的发展,而物联网技术的发展也必将促使地磅兴起新的技术革命。

  1. 设计的技术与硬件选项总结:

  (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 设计一个页面显示并设置当前的报警上限。通过按键进行加减

  当称重的阀值超出了设置阀值,蜂鸣器报警。

  

1.jpg


  

image.png


  

image.png


  

image.png


  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

  这个模型数据就是设备要上传的数据。

  


  


  


  


  


  {

  "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/

  


  


  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 主题订阅与发布

  //订阅主题: 平台下发消息给设备

  $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/

  

image.png


  4. STM32 设备端开发

  4.1 程序下载

  


  4.2 原理图

  


  4.3 硬件接线

  (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 连接代码

  #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请稍等. ");

  if(ESP8266_Init())

  {

  USART1_Printf("ESP8266硬件检测错误. ");

  }

  else

  {

  //非加密端口

  USART1_Printf("WIFI:%d ",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("服务器连接失败,正在重试... ");

  delay_ms(500);

  }

  USART1_Printf("服务器连接成功. ");

  //3. 订阅主题

  if(MQTT_SubscribeTopic(SET_TOPIC,0,1))

  {

  USART1_Printf("主题订阅失败. ");

  }

  else

  {

  USART1_Printf("主题订阅成功. ");

  }

  .........

  4.5 ESP8266 代码

  #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]='';

  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 ");

  }

  /*

  函数功能: 一键配置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 "))return 1;

  /*2. 关闭回显*/

  if(ESP8266_SendCmd("ATE0 "))return 2;

  /*3. 设置WIFI模式*/

  if(ESP8266_SendCmd("AT+CWMODE=2 "))return 3;

  /*4. 复位*/

  ESP8266_SendCmd("AT+RST ");

  delay_ms(1000);

  delay_ms(1000);

  delay_ms(1000);

  /*5. 关闭回显*/

  if(ESP8266_SendCmd("ATE0 "))return 5;

  /*6. 设置WIFI的AP模式参数*/

  sprintf(ESP8266_SendCMD,"AT+CWSAP="%s","%s",1,4 ",ssid,pass);

  if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;

  /*7. 开启多连接*/

  if(ESP8266_SendCmd("AT+CIPMUX=1 "))return 7;

  /*8. 设置服务器端口号*/

  sprintf(ESP8266_SendCMD,"AT+CIPSERVER=1,%d ",port);

  if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;

  /*9. 查询本地IP地址*/

  if(ESP8266_SendCmd("AT+CIFSR "))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]='';

  }

  //提取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]='';

  }

  //打印总体信息

  USART1_Printf("当前WIFI模式:AP+TCP服务器 ");

  USART1_Printf("当前WIFI热点名称:%s ",ssid);

  USART1_Printf("当前WIFI热点密码:%s ",pass);

  USART1_Printf("当前TCP服务器端口号:%d ",port);

  USART1_Printf("当前TCP服务器IP地址:%s ",ESP8266_IP_ADDR);

  USART1_Printf("当前TCP服务器MAC地址:%s ",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 ",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]='';

  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]='';

  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 "))return 1;

  /*2. 关闭回显*/

  if(ESP8266_SendCmd("ATE0 "))return 2;

  /*3. 设置WIFI模式*/

  if(ESP8266_SendCmd("AT+CWMODE=1 "))return 3;

  /*4. 复位*/

  ESP8266_SendCmd("AT+RST ");

  delay_ms(1000);

  delay_ms(1000);

  delay_ms(1000);

  /*5. 关闭回显*/

  if(ESP8266_SendCmd("ATE0 "))return 5;

  /*6. 配置将要连接的WIFI热点信息*/

  sprintf(ESP8266_SendCMD,"AT+CWJAP="%s","%s" ",ssid,pass);

  if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;

  /*7. 设置单连接*/

  if(ESP8266_SendCmd("AT+CIPMUX=0 "))return 7;

  /*8. 配置要连接的TCP服务器信息*/

  sprintf(ESP8266_SendCMD,"AT+CIPSTART="TCP","%s",%d ",ip,port);

  if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;

  /*9. 开启透传模式*/

  if(flag)

  {

  if(ESP8266_SendCmd("AT+CIPMODE=1 "))return 9; //开启

  if(ESP8266_SendCmd("AT+CIPSEND "))return 10; //开始透传

  if(!(strstr((char*)USART3_RX_BUFFER,">")))

  {

  return 11;

  }

  //如果想要退出发送: "+++"

  }

  //打印总体信息

  USART1_Printf("当前WIFI模式:STA+TCP客户端 ");

  USART1_Printf("当前连接的WIFI热点名称:%s ",ssid);

  USART1_Printf("当前连接的WIFI热点密码:%s ",pass);

  USART1_Printf("当前连接的TCP服务器端口号:%d ",port);

  USART1_Printf("当前连接的TCP服务器IP地址:%s ",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 ",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]='';

  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]='';

  USART3_RX_FLAG=0;

  USART3_RX_CNT=0;

  if(strstr((char*)USART3_RX_BUFFER,"SEND OK"))

  {

  return 0;

  }

  }

  }

  }

  }

  }

  }

  return 1;

  }


责任编辑:David

【免责声明】

1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。

2、本文的引用仅供读者交流学习使用,不涉及商业目的。

3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。

4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。

拍明芯城拥有对此声明的最终解释权。

相关资讯