ESP32物联网实战:5分钟搞定HTTP-POST请求发送传感器数据

在智能家居和工业物联网项目中,ESP32凭借其双核处理器和内置Wi-Fi模块成为硬件开发者的首选。但许多初学者往往卡在数据上传环节——如何用最简单的代码实现传感器数据稳定传输?本文将手把手带你完成从Wi-Fi配置到服务器响应的全流程,并提供可直接复用的代码模板。

1. 硬件准备与环境搭建

ESP32开发板的价格已降至20元以内,但性能却足以应对大多数物联网场景。推荐使用ESP32-WROOM-32D核心板,其4MB闪存和240MHz主频能流畅运行HTTP通信任务。开发环境选择Arduino IDE或PlatformIO均可,后者对库管理更友好。

安装必要库文件:

platformio lib install "ESP32 HTTP Client"
platformio lib install "ArduinoJson"

硬件连接示意图(以DHT11温湿度传感器为例):

ESP32引脚传感器引脚备注
3.3VVCC电源正极
GNDGND电源地线
GPIO4DATA数据信号线

注意:若使用I2C传感器,需额外配置SCL/SDA引脚。模拟传感器需注意ADC输入范围(ESP32最大3.3V)

2. Wi-Fi连接的稳健性优化

传统Wi-Fi连接代码存在超时无反馈的问题,改进后的方案包含自动重连和信号强度检测:

#include <WiFi.h>

const char* ssid = "Your_SSID";
const char* password = "Your_PASSWORD";

void connectToWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  Serial.print("Connecting");
  int retryCount = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (++retryCount > 30) {
      Serial.println("\nFailed to connect! Restarting...");
      ESP.restart();
    }
  }
  
  Serial.printf("\nConnected! IP: %s\nRSSI: %d dBm\n", 
               WiFi.localIP().toString().c_str(),
               WiFi.RSSI());
}

关键优化点:

  • 增加30秒超时重启机制
  • 显示连接后的信号强度(RSSI)
  • 使用STA模式降低功耗

实测发现,当RSSI低于-75dBm时,数据传输失败率显著上升。建议在代码中添加信号阈值判断:

if (WiFi.RSSI() < -75) {
  Serial.println("Warning: Weak WiFi signal!");
}

3. HTTP-POST请求的进阶实践

3.1 数据格式选择对比

格式类型优点缺点适用场景
URL编码简单通用不支持复杂数据结构基础表单提交
JSON结构化数据需要解析库现代API接口
二进制传输效率高可读性差大规模传感器网络

推荐使用JSON格式传输传感器数据,示例代码:

#include <ArduinoJson.h>

DynamicJsonDocument buildSensorData() {
  DynamicJsonDocument doc(256);
  doc["device_id"] = "ESP32_001";
  doc["temperature"] = 25.6;
  doc["humidity"] = 58.3;
  doc["timestamp"] = millis();
  return doc;
}

String serializeData() {
  DynamicJsonDocument doc = buildSensorData();
  String output;
  serializeJson(doc, output);
  return output;
}

3.2 带重试机制的POST发送

#include <HTTPClient.h>

bool sendPostRequest(const String& url, const String& data) {
  HTTPClient http;
  bool success = false;
  
  for (int i = 0; i < 3; i++) { // 最大重试3次
    http.begin(url);
    http.addHeader("Content-Type", "application/json");
    
    int httpCode = http.POST(data);
    if (httpCode > 0) {
      Serial.printf("HTTP Code: %d\n", httpCode);
      String payload = http.getString();
      Serial.println(payload);
      success = true;
      break;
    } else {
      Serial.printf("POST failed, error: %s\n", http.errorToString(httpCode).c_str());
    }
    delay(1000 * (i + 1)); // 指数退避
  }
  
  http.end();
  return success;
}

4. 服务器响应处理与错误排查

常见HTTP状态码及应对策略:

  • 200 OK:数据处理成功,可解析返回内容
  • 400 Bad Request:检查JSON格式是否符合API文档
  • 401 Unauthorized:验证API密钥或Token
  • 500 Server Error:等待后重试或通知服务端

添加响应日志记录功能:

void logResponse(int code, const String& payload) {
  StaticJsonDocument<512> doc;
  deserializeJson(doc, payload);
  
  File file = SPIFFS.open("/response.log", FILE_APPEND);
  if (file) {
    doc["status_code"] = code;
    doc["timestamp"] = time(nullptr);
    serializeJson(doc, file);
    file.close();
  }
}

调试技巧:

  1. 使用Postman模拟请求验证API可用性
  2. 在代码关键节点添加Serial打印
  3. 用逻辑分析仪抓取HTTP通信时序
  4. 监控ESP32内存使用情况(heap_caps_get_free_size())

5. 低功耗优化方案

对于电池供电的场景,需要优化能耗:

void enterDeepSleep() {
  esp_sleep_enable_timer_wakeup(5 * 60 * 1000000); // 5分钟
  esp_deep_sleep_start();
}

void setup() {
  connectToWiFi();
  sendPostRequest("http://api.example.com/data", serializeData());
  WiFi.disconnect(true);
  enterDeepSleep();
}

void loop() {} // 空实现

实测电流对比:

模式电流消耗唤醒时间
持续运行80mA即时
深度睡眠10μA2秒
轻度睡眠5mA100ms

在最近的一个农业监测项目中,采用深度睡眠方案使CR2032纽扣电池续航从3天延长至6个月。关键点是:

  • 关闭未使用的外设(adc_power_off())
  • 降低CPU频率(setCpuFrequencyMhz(80))
  • 使用WiFi.setSleep(true)启用Wi-Fi节能模式
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐