ESP32将DHT11温湿度传感器采集的数据上传到XAMPP的MySQL数据库

数据流向

  • ESP32 采集温湿度数据后,通过 HTTP POST 请求将数据发送到服务器上的 PHP 文件

  • PHP 文件save_data_improved.php接收数据并将其插入到 MySQL 数据库(esp32_data)的 sensor_data表中

  • 可以通过 phpMyAdmin 查看和管理数据库中的 sensor_data 表数据

文件准备

PHP与MySQL交互

ino(esp32程序文件)

ESP32将DHT11温湿度传感器采集的数据上传到XAMPP的MySQL数据库

先打开XAMPP

服务器端配置

1. 使用phpMyAdmin(查看MySQL)

phpMyAdmin是一个流行的Web界面工具,用于管理MySQL数据库。它通常随XAMPP一起安装。

  • 打开浏览器,输入 http://localhost/phpmyadminhttp://127.0.0.1/phpmyadmin

  • 输入你的MySQL用户名和密码(默认情况下,XAMPP的MySQL用户名是root,没有密码)。

  • 登录后,你可以看到所有的数据库和表,并进行各种操作。

    在XAMPP中,网站的根目录通常是 htdocs 文件夹。在你的例子中,你已经在 htdocs 目录下创建了一个名为 esp32_data 的文件夹,并在其中创建了一个 save_data_improved.php 文件。

    这是一个很好的做法,因为它可以帮助你组织和管理你的项目文件。当你在浏览器的地址栏中输入 http://localhost/esp32_data/save_data_improved.php 时,Apache 服务器会加载并执行这个 PHP 文件

创建MySQL数据库

在 XAMPP 环境下,MySQL 的数据库文件默认存储在 D:\XAMPP\mysql\data 目录下。当你创建一个名为 esp32_data 的数据库时,MySQL 会在该目录下自动创建一个同名的文件夹(即 esp32_data),用于存放该数据库的所有表文件。

  • 在MySQL中创建一个数据库,例如esp32_data

  • 创建一个表用于存储温湿度数据:

    sql 复制代码
         CREATE TABLE sensor_data (
           id INT AUTO_INCREMENT PRIMARY KEY,
           temperature FLOAT,
           humidity FLOAT,
           timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
         );

D:\XAMPP\mysql\data 目录下看到 esp32_data 文件夹

2. 自定义PHP脚本

你也可以编写自己的PHP脚本来连接MySQL数据库,并在浏览器中显示数据。(save_data_improved.php)

步骤:
  1. 创建PHP文件

    • 在XAMPP的htdocs文件夹中创建一个新的PHP文件。
  1. 编写PHP代码

    php 复制代码
    <?php
    // 数据库配置
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "esp32_data";
    
    // 设置JSON响应头
    header('Content-Type: application/json');
    
    // 创建数据库连接
    $conn = new mysqli($servername, $username, $password, $dbname);
    
    // 检查连接
    if ($conn->connect_error) {
        // 记录错误日志(实际应用中)
        // error_log("数据库连接失败: " . $conn->connect_error);
        die(json_encode(array('status' => 'error', 'message' => '数据库连接失败: ' . $conn->connect_error)));
    }
    
    // 检查是否接收到POST数据
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // 检查温度和湿度参数是否存在
        if (isset($_POST['temperature']) && isset($_POST['humidity'])) {
            // 验证是否为有效数字
            if (is_numeric($_POST['temperature']) && is_numeric($_POST['humidity'])) {
                $temperature = floatval($_POST['temperature']);
                $humidity = floatval($_POST['humidity']);
    
                // 验证数据范围
                if ($temperature >= -50 && $temperature <= 150 && $humidity >= 0 && $humidity <= 100) {
                    // 准备参数化查询
                    $stmt = $conn->prepare("INSERT INTO sensor_data (temperature, humidity, timestamp) VALUES (?, ?, CURRENT_TIMESTAMP)");
                    if (!$stmt) {
                        echo json_encode(array('status' => 'error', 'message' => '预处理语句失败: ' . $conn->error));
                        $conn->close();
                        exit;
                    }
    
                    // 绑定参数
                    $stmt->bind_param("dd", $temperature, $humidity); // 'dd'表示两个double类型参数
    
                    // 执行查询
                    if ($stmt->execute() === TRUE) {
                        echo json_encode(array('status' => 'success', 'message' => '新记录插入成功', 'data' => array('temperature' => $temperature, 'humidity' => $humidity)));
                    } else {
                        echo json_encode(array('status' => 'error', 'message' => '插入记录失败: ' . $stmt->error));
                    }
    
                    $stmt->close();
                } else {
                    echo json_encode(array('status' => 'error', 'message' => '数据超出合理范围: 温度应在-50到150之间,湿度应在0到100之间'));
                }
            } else {
                echo json_encode(array('status' => 'error', 'message' => '温度和湿度必须是数字'));
            }
        } else {
            echo json_encode(array('status' => 'error', 'message' => '缺少必要的POST参数: temperature或humidity'));
        }
    } else {
        echo json_encode(array('status' => 'error', 'message' => '请使用POST方法发送数据'));
    }
    
    // 关闭连接
    $conn->close();
  2. 保存并测试

编写Arduino代码

将DHT11温湿度传感器采集的数据上传到MySQL数据库。以下是具体实现步骤:

一、硬件连接

  1. DHT11传感器连接
    • DHT11的VCC引脚连接到ESP32的3.3V引脚。
    • DHT11的GND引脚连接到ESP32的GND引脚。
    • DHT11的DATA引脚连接到ESP32的数字引脚(例如GPIO4)。

二、安装必要的库

在Arduino IDE中,需要安装以下库:

  1. DHT sensor library

    • 打开Arduino IDE,点击"工具" > "管理库",搜索并安装"DHT sensor library"。
  2. WiFi.h

    • ESP32自带的库,无需额外安装。
  3. HTTPClient.h

    • ESP32自带的库,用于发送HTTP请求。

三、编写代码

以下是完整的代码示例,用于读取DHT11温湿度数据并通过HTTP POST请求上传到服务器:

cpp 复制代码
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>

// WiFi配置
const char* ssid = "******";     // 替换为你的WiFi名称
const char* password = "*****";     // 替换为你的WiFi密码
const char* serverUrl = "http://192.168.2.232/esp32_data/save_data_improved.php"; // 本地XAMPP服务器地址 (使用改进版PHP文件)

// DHT传感器配置
#define DHTPIN 4          // DHT11传感器连接到GPIO4
#define DHTTYPE DHT11     // 使用DHT11传感器
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  
  // 连接WiFi
  WiFi.begin(ssid, password);
  unsigned long startTime = millis();
  int connectionTimeout = 10000; // 10秒超时

  while (WiFi.status() != WL_CONNECTED) {
    if (millis() - startTime > connectionTimeout) {
      Serial.println("WiFi连接超时!");
      return;
    }
    delay(500);
    Serial.print(".");
  }

  Serial.println("WiFi连接成功");
  Serial.print("IP地址: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // 读取传感器数据
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // 检查传感器读取是否成功
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("无法读取传感器数据!");
    delay(2000);
    return;
  }

  // 打印传感器数据
  Serial.print("湿度: ");
  Serial.print(humidity);
  Serial.println("%");
  Serial.print("温度: ");
  Serial.print(temperature);
  Serial.println("°C");

  // 发送数据到服务器
        if (WiFi.status() == WL_CONNECTED) {
            HTTPClient http;
            int maxRetries = 3;
            int retryCount = 0;
            int httpResponseCode = 0;

            while (retryCount < maxRetries) {
              Serial.print("尝试连接到服务器: ");
              Serial.println(serverUrl);
              if (http.begin(serverUrl)) {
                Serial.println("HTTP连接初始化成功");
                // 确保正确设置Content-Type头
                http.addHeader("Content-Type", "application/x-www-form-urlencoded");
                Serial.println("Content-Type头已设置");

                // 构造POST请求的数据
                // 注意:不要对=和&字符进行编码,它们是URL参数的必要分隔符
                String postData = "temperature=" + String(temperature) + "&humidity=" + String(humidity);
                // 只对空格和+号进行编码
                postData.replace(" ", "%20");
                postData.replace("+", "%2B");

                Serial.print("发送的POST数据: ");
                Serial.println(postData);
                Serial.print("数据长度: ");
                Serial.println(postData.length());

                httpResponseCode = http.POST(postData);
                Serial.print("发送POST请求后,响应代码: ");
                Serial.println(httpResponseCode);

        if (httpResponseCode > 0) {
          Serial.print("HTTP响应代码: ");
          Serial.println(httpResponseCode);
          if (httpResponseCode == HTTP_CODE_OK) {
            Serial.println("数据发送成功!");
            // 输出服务器响应内容
            String response = http.getString();
            Serial.print("服务器响应: ");
            Serial.println(response);
          } else {
            Serial.print("服务器返回非200响应: ");
            Serial.println(httpResponseCode);
          }
          break; // 成功,退出重试循环
        } else {
          Serial.print("请求失败,错误代码: ");
          Serial.println(http.errorToString(httpResponseCode).c_str());
          retryCount++;
          if (retryCount < maxRetries) {
            Serial.print("正在重试 (" + String(retryCount) + "/" + String(maxRetries) + ")...");
            delay(2000); // 等待2秒后重试
          }
        }
        http.end();
      } else {
        Serial.println("无法连接到服务器");
        retryCount++;
        if (retryCount < maxRetries) {
          Serial.print("正在重试 (" + String(retryCount) + "/" + String(maxRetries) + ")...");
          delay(2000); // 等待2秒后重试
        }
      }
    }
    if (retryCount >= maxRetries) {
      Serial.println("超过最大重试次数,请求失败");
    }
  } else {
    Serial.println("WiFi未连接,无法发送数据");
  }

  delay(60000); // 每1分钟发送一次数据
}

四、代码说明

  1. 初始化 ESP32 开发板
  2. 连接到指定的 WiFi 网络
  3. 读取 DHT11 传感器的温湿度数据
  4. 将采集到的数据通过 HTTP POST 请求发送到本地 XAMPP 服务器
  5. 每 1 分钟发送一次数据
  6. 包含连接重试机制和错误处理

五、注意事项

  1. Wi-Fi设置

    • 确保ESP32连接的Wi-Fi网络与服务器在同一局域网内,或者服务器有公网IP地址。
  2. 服务器地址

    • 如果服务器在本地运行,可以使用"http://192.168.2.232/esp32_data/save_data_improved.php";如果服务器在其他设备上,需替换为对应的IP地址或域名。(因为服务器在电脑本地,esp32和电脑连在同一个局域网,不能使用localhost,要用电脑的IP地址)
  1. 安全性

    • 在生产环境中,建议使用HTTPS加密通信,避免数据传输被窃听。
  2. 调试

    • 通过串口监视器查看ESP32的输出日志,确保数据读取和发送正常。

六、总结

通过以上步骤,你可以实现ESP32通过Arduino程序读取DHT11温湿度数据,并将其上传到MySQL数据库。如果遇到问题,可以检查硬件连接、Wi-Fi设置或服务器端代码。

要删除表中的所有行,可以使用以下SQL语句:

sql 复制代码
DELETE FROM sensor_data;

这条命令会删除sensor_data表中的所有数据,但不会删除表本身。如果你确实希望执行这个操作,请确保已经备份了重要数据,并且理解此操作的后果。

注意事项

  • 确保你的MySQL服务正在运行。你可以通过XAMPP控制面板启动或停止MySQL服务。
  • 根据你的实际数据库和表结构调整PHP代码中的变量和SQL查询。
  • 为了安全起见,避免在公共网络上使用默认的用户名和密码。最好为你的MySQL用户设置强密码。
    通过以上方法,你可以在浏览器中管理和访问MySQL数据库。
相关推荐
TDengine (老段)2 小时前
TDengine IDMP 快速体验(方式二 通过 docker)
大数据·数据库·docker·ai·时序数据库·tdengine·涛思数据
来来走走5 小时前
Flutter SharedPreferences存储数据基本使用
android·flutter
tanxiaomi5 小时前
学习分库分表的前置知识:高可用系统架构理论与实践
java·mysql·spring cloud·系统架构·springboot
安卓开发者6 小时前
Android模块化架构深度解析:从设计到实践
android·架构
雨白6 小时前
HTTP协议详解(二):深入理解Header与Body
android·http
阿豪元代码7 小时前
深入理解 SurfaceFlinger —— 如何调试 SurfaceFlinger
android
阿豪元代码7 小时前
深入理解 SurfaceFlinger —— 概述
android
国王不在家7 小时前
3.5-非关系型数据库-反规范化-sql语言
数据库·nosql
CV资深专家8 小时前
Launcher3启动
android