1. 项目背景与硬件选型第一次接触物联网项目时我被各种专业术语和复杂的协议搞得晕头转向。直到真正动手做了一个温湿度监测项目才发现从硬件到云端的完整链路并没有想象中那么难。这次我们就用最常见的STM32开发板和4G Cat.1模块带大家走通数据上云的完整流程。为什么选择4G Cat.1模块实测下来相比传统的2G模块它的网络覆盖和稳定性更好相比Cat.4模块功耗和成本又低不少特别适合这种低频次、小数据量的物联网场景。我用的是移远EC200S市面上类似的还有中移物联ML302价格都在百元以内性价比很高。STM32的选择就更加灵活了F103系列完全够用。我手头正好有块STM32F103C8T6最小系统板内存64KBFlash 128KB跑MQTT客户端绰绰有余。温湿度传感器选了经典的DHT11虽然精度一般湿度±5%温度±2℃但胜在便宜好用5块钱就能买到。2. 硬件连接与初始化拿到硬件后先要搞定物理连接。这里有个坑要注意4G模块的供电需求比较高峰值电流可能达到2A直接接开发板的3.3V输出肯定会出问题。我的解决方案是用一个AMS1117-3.3稳压芯片单独给模块供电输入接5V电源这样最稳。具体接线如下EC200S的VCC接AMS1117输出GND与STM32共地TXD接STM32的PA3USART2_RXRXD接PA2USART2_TXDHT11的数据线接PA1上电后模块的NET灯会开始闪烁等变成常亮就说明注册到4G网络了。如果一直闪烁可能是SIM卡没插好或者APN设置有问题。我用的是移动物联网卡APN要设成CMIOT不同运营商可能不一样。初始化代码很简单void USART2_Init(void) { // 波特率115200,8位数据,无校验,1位停止位 huart2.Instance USART2; huart2.Init.BaudRate 115200; huart2.Init.WordLength UART_WORDLENGTH_8B; huart2.Init.StopBits UART_STOPBITS_1; huart2.Init.Parity UART_PARITY_NONE; HAL_UART_Init(huart2); }3. MQTT协议栈实现虽然EC200S自带MQTT AT指令集但就像原始文章提到的为了更好的可移植性我们选择在MCU端实现MQTT协议。这里我用的是开源的Paho MQTT嵌入式客户端经过裁剪后不到10KB非常适合资源受限的MCU。关键是要实现以下几个功能连接建立发送CONNECT报文包含ClientID、用户名和密码心跳维持定时发送PINGREQ主题订阅SUBSCRIBE报文消息发布PUBLISH报文OneNET的鉴权比较特殊用户名是产品ID密码要用Token算法生成。我封装了一个函数来处理void generate_onenet_token(char* buffer, const char* product_id, const char* device_name, const char* access_key) { // 计算过期时间当前时间1小时 uint32_t expiry HAL_GetTick()/1000 3600; // 构造待签名字符串 char temp[256]; sprintf(temp, products/%s/devices/%s, product_id, device_name); // HMAC-SHA1加密 uint8_t digest[20]; hmac_sha1((uint8_t*)temp, strlen(temp), (uint8_t*)access_key, strlen(access_key), digest); // Base64编码 base64_encode(digest, 20, buffer); }4. OneNET平台配置很多新手卡在平台配置这一步其实按照流程走并不复杂。首先在OneNET官网注册账号进入多协议接入选择MQTT创建一个新产品。关键参数这样填协议类型MQTT联网方式蜂窝运营商根据SIM卡选择数据格式JSON创建完产品后添加设备记下这三个关键信息产品ID在产品详情页查看设备名称创建时自己定义API Key在设备详情页的密钥管理中平台端的Topic有固定格式发布主题$sys/{产品ID}/{设备名称}/dp/post/json订阅主题$sys/{产品ID}/{设备名称}/cmd/request/5. 数据上传与调试一切就绪后就可以上传温湿度数据了。我定义了一个简单的JSON格式{ id: 123, dp: { temperature: [{v: 25.5}], humidity: [{v: 60.2}] } }对应的C代码实现void publish_sensor_data(float temp, float humi) { char payload[128]; sprintf(payload, {\id\:%d,\dp\:{\temperature\:[{\v\:%.1f}],\humidity\:[{\v\:%.1f}]}}, device_id, temp, humi); mqtt_publish($sys/123456/my_device/dp/post/json, payload, strlen(payload), QOS0); }调试时最容易遇到三个问题数据格式不对一定要严格按平台要求的JSON格式Token过期生成的Token默认1小时有效需要定期刷新网络抖动建议加入重连机制当PING超时后重新建立连接6. 数据可视化与应用数据上传成功后在OneNET的设备管理页面能看到设备状态变成在线。进入数据流标签页可以创建可视化图表。比如我添加了两个数据流温度单位℃, 范围-20~50湿度单位%, 范围0~100平台支持设置告警规则比如当温度超过30℃时发送邮件通知。更高级的应用可以通过HTTP API获取数据接入自己的Web应用或小程序。我在一个农业大棚项目中就用这种方式实现了远程监控效果很稳定。7. 优化与扩展实际部署时还需要考虑几个优化点低功耗设计采用定时唤醒策略比如每5分钟采集一次数据数据缓存网络不可用时先存到Flash恢复后补传固件升级通过OneNET的OTA服务远程更新程序如果想扩展更多功能可以考虑加入GPS模块实现定位对接第三方通知服务如短信、微信推送使用规则引擎实现简单的自动控制这个项目的完整代码我已经放在GitHub上包含STM32工程文件和手机端Demo APP。遇到问题可以查看Wiki页面的常见问题解答或者提交Issue讨论。