You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP8266传感器数据HTTP POST至MySQL异常:温度数据无法上报求助

问题:ESP8266温度传感器数据无法通过HTTP POST上报至MySQL数据库

使用ESP8266连接WiFi并接入多类传感器,向MySQL数据库发送HTTP POST请求时,土壤湿度传感器数据可正常上报,但温度传感器数据无法上报,两者代码逻辑基本一致,怀疑是字符拼接操作有误。

相关代码及信息

全局变量定义

typechar *URL = "http://localHost/post-sensor-readings.php";
char *postHeader = "api_key";
char *tempEntry = "&temphumSensor=";
char *soilEntry = "&soilmoistSensor=";
char *npkEntry = "&npkSensor=";
char *tempSensor[10];
char *humiditySensor;
char *moistureSensor[4]; 

数据库更新代码

char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
esp_http_client_config_t config = {
    .url = "http://httpbin.org/get", 
};

esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_open(client, 0);

char post_data[151];
char *post_header ="api_key=tPmAT5Ab3j7F9";
strcpy(post_data, post_header);

strcat(post_data, tempEntry);
strcat(post_data, tempSensor);

strcat(post_data, soilEntry);
strcat(post_data, moistureSensor);

esp_http_client_set_url(client, "http://localHost/post-sensor-readings.php");
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");

温度采集任务(无法正常上报)

void temperature_task(void *arg)
{
    ESP_ERROR_CHECK(dht_init(DHT_GPIO, false));
    vTaskDelay(2000 / portTICK_PERIOD_MS);

    int temperature[100];
    int humidity;
    while (1)
    {
        if (dht_read_data(DHT_TYPE_DHT22, DHT_GPIO, &humidity, &temperature[0]) == ESP_OK) {
            // e.g. in dht22, 604 = 60.4%, 252 = 25.2 C
            // If you want to print float data, you should run `make menuconfig`
            // to enable full newlib and call dht_read_float_data() here instead
            printf("Humidity: %d Temperature: %d\n", humidity, temperature[0]);
            sprintf(tempSensor, "%d", temperature[0]);
            // fprintf( stderr, "%s", tempSensor);
            // itoa(temperature,tempSensor,10);
        }
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

土壤湿度采集任务(可正常上报)

void soilHumidity_task(void *arg){
    static const char *TAG = "READING HUMIDITY";
    adc_config_t config1 ={.mode = 0, .clk_div =8};
    ESP_ERROR_CHECK(adc_init(&config1));

    uint16_t adc_data[100];
    while (1) {
        if (ESP_OK == adc_read(&adc_data[0])) {
            ESP_LOGI(TAG, "ADC read: %d\r\n", adc_data[0]);
            printf("%d", adc_data[0]);

            sprintf(moistureSensor, "%d", adc_data[0]);

            vTaskDelay(1000 / portTICK_RATE_MS);
        }
    }
    vTaskDelete(NULL);
}

数据库情况

数据库中土壤湿度数据正常入库,但温度字段为空。


问题原因及解决方法

核心问题:指针数组误用为字符数组

全局变量中char *tempSensor[10];和char *moistureSensor[4];是指针数组,而非用于存储字符串的字符数组。sprintf需要将格式化后的字符串写入一块已分配的内存区域,但指针数组本身只是存储指针的容器,未分配实际的字符串存储空间,直接调用sprintf(tempSensor, ...)会导致内存访问错误,写入非法地址,最终导致上报数据异常。

土壤湿度数据看似正常只是巧合(内存溢出未触发崩溃),但本质上代码同样存在错误。

解决步骤

  1. 修正全局变量定义:将指针数组改为字符数组,分配足够存储传感器数据字符串的空间:
// 替换原指针数组定义
char tempSensor[10];    // 足够存储整数转字符串的内容(含终止符)
char moistureSensor[4]; // 同理适配土壤湿度数据长度
  1. 简化温度采集任务中的变量:temperature无需定义为数组,单个int即可满足需求:
void temperature_task(void *arg)
{
    ESP_ERROR_CHECK(dht_init(DHT_GPIO, false));
    vTaskDelay(2000 / portTICK_PERIOD_MS);

    int temperature; // 改为单个int变量
    int humidity;
    while (1)
    {
        // 传递temperature的地址给dht_read_data
        if (dht_read_data(DHT_TYPE_DHT22, DHT_GPIO, &humidity, &temperature) == ESP_OK) {
            printf("Humidity: %d Temperature: %d\n", humidity, temperature);
            // 写入字符数组
            sprintf(tempSensor, "%d", temperature);
        }
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}
  1. 验证字符拼接逻辑:修正后tempSensor和moistureSensor均为合法的字符串缓冲区,strcat(post_data, tempSensor)可以正确拼接温度数据到POST请求体中,确保数据能正常上报至数据库。

内容的提问来源于stack exchange,提问作者Jorge Lopez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 23:31:24