基于STM32与Android的物联网环境监测APP开发实战
1. 项目背景与整体架构设计
在智能家居和工业物联网快速发展的今天,环境监测系统已经成为许多应用场景的标配。我最近完成了一个基于STM32和Android的物联网环境监测项目,实测效果非常稳定,今天就把这个实战经验完整分享给大家。
这个系统的核心架构分为三部分:
- 数据采集端:使用STM32F103C8T6作为主控芯片,搭配DHT11温湿度传感器和光敏电阻,通过ESP8266 WiFi模块实现网络连接
- 云端服务:采用百度云物联网平台作为MQTT Broker,负责设备间消息转发
- 移动端:Android APP实时接收并可视化环境数据
整个系统的工作流程是这样的:STM32每5秒采集一次环境数据,通过ESP8266以MQTT协议上传到云端,Android APP订阅相关主题后就能实时接收并显示这些数据。我实测在家庭WiFi环境下,从传感器采集到手机显示延迟可以控制在800ms以内。
2. STM32端开发实战
2.1 硬件选型与电路设计
硬件部分我选择了这些核心器件:
- 主控芯片:STM32F103C8T6(性价比高,资源足够)
- WiFi模块:ESP8266-01S(支持AT指令,开发简单)
- 温湿度传感器:DHT11(精度±2℃,响应快)
- 光照传感器:GL5528光敏电阻(成本低,线性度好)
电路连接特别注意三点:
- ESP8266的TX/RX要接STM32的USART2(PA2/PA3)
- DHT11的数据线要加上拉电阻(4.7KΩ)
- 光敏电阻需要配合10KΩ电阻组成分压电路
// 典型的光照值读取代码 void ReadLightSensor(void) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = 1; HAL_ADC_ConfigChannel(&hadc1, &sConfig); HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 10); lightValue = HAL_ADC_GetValue(&hadc1); }2.2 MQTT通信实现
STM32端使用AT指令控制ESP8266连接MQTT服务器,这里有几个关键点:
- 每次上电后要先发送ATE0关闭回显
- 连接WiFi时要设置正确的加密方式(WPA2)
- MQTT连接需要clientID、username、password三要素
我封装了一个MQTT发送函数,实测非常稳定:
void MQTT_Publish(char *topic, char *msg) { char cmd[128]; sprintf(cmd, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n", topic, msg); HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), 1000); }3. Android端开发全流程
3.1 开发环境搭建
Android Studio中需要添加这些关键依赖:
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'还要在AndroidManifest.xml中添加这些权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" />3.2 MQTT客户端实现
我封装了一个MQTT管理类,核心功能包括:
- 自动重连机制
- 消息到达回调
- 连接状态监听
这里分享一个连接服务器的代码片段:
public void connect() { try { MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); options.setUserName(username); options.setPassword(password.toCharArray()); options.setAutomaticReconnect(true); client.connect(options, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { subscribeToTopic(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.e(TAG, "连接失败", exception); } }); } catch (MqttException e) { e.printStackTrace(); } }3.3 数据解析与UI更新
数据格式约定为JSON字符串:
{ "temp": 26.5, "humi": 65, "light": 1200, "time": "2023-07-20 14:30:00" }使用Gson解析数据后,通过Handler更新UI:
private Handler dataHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { EnvData data = (EnvData) msg.obj; tempTextView.setText(String.format("%.1f℃", data.getTemp())); humiTextView.setText(String.format("%d%%", data.getHumi())); lightProgress.setProgress(data.getLight() / 10); } };4. 云端配置与调试技巧
4.1 百度云物联网平台配置
在百度云物联网平台需要完成这些配置:
- 创建产品(选择MQTT协议)
- 添加设备(生成三元组)
- 设置规则引擎(实现消息转发)
特别注意ACL权限设置,要确保:
- 设备有发布权限
- APP有订阅权限
- 主题匹配规则正确
4.2 调试中遇到的典型问题
在开发过程中我踩过这些坑:
MQTT连接频繁断开解决方法:调整keepalive时间为60秒,开启自动重连
Android后台服务被杀死解决方法:使用前台服务,添加Notification
数据更新不及时解决方法:在MQTT QoS设置为1,确保消息可达
STM32内存泄漏解决方法:定期清理AT指令缓冲区
5. 功能扩展与优化建议
这个基础框架还可以进一步扩展:
- 历史数据存储:添加SQLite数据库支持
- 异常报警:设置阈值触发通知
- 多设备管理:实现设备列表动态加载
- 数据导出:支持CSV格式导出
性能优化方面我建议:
- 使用Protocol Buffers替代JSON减小数据量
- 实现数据压缩传输(如gzip)
- 添加本地缓存机制应对网络中断
- 使用WorkManager处理后台任务
在界面设计上,可以引入MPAndroidChart实现数据可视化:
LineChart chart = findViewById(R.id.chart); List<Entry> entries = new ArrayList<>(); entries.add(new Entry(0, 25f)); entries.add(new Entry(1, 26f)); LineDataSet dataSet = new LineDataSet(entries, "温度"); LineData lineData = new LineData(dataSet); chart.setData(lineData); chart.invalidate();这个项目我从硬件选型到APP上线总共用了3周时间,期间最大的收获是理解了物联网系统的完整链路。特别是在MQTT协议调试过程中,通过Wireshark抓包分析解决了不少疑难问题。建议初学者可以先使用MQTT.fx工具模拟设备行为,等协议调通后再着手编码,这样可以节省大量调试时间。
