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, ...)会导致内存访问错误,写入非法地址,最终导致上报数据异常。
土壤湿度数据看似正常只是巧合(内存溢出未触发崩溃),但本质上代码同样存在错误。
解决步骤
- 修正全局变量定义:将指针数组改为字符数组,分配足够存储传感器数据字符串的空间:
// 替换原指针数组定义 char tempSensor[10]; // 足够存储整数转字符串的内容(含终止符) char moistureSensor[4]; // 同理适配土壤湿度数据长度
- 简化温度采集任务中的变量:
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); }
- 验证字符拼接逻辑:修正后
tempSensor和moistureSensor均为合法的字符串缓冲区,strcat(post_data, tempSensor)可以正确拼接温度数据到POST请求体中,确保数据能正常上报至数据库。
内容的提问来源于stack exchange,提问作者Jorge Lopez
相关产品推荐
相关产品推荐

