上次我们讲述了怎么样搭建LAMP,然而怎么样应用到实际领域中呢?有人说搭建博客,没错我的博客也是这么来的,这也是LAMP的一种典型实例,可是这种实例烂大街,都不香了 :huaji: .这次我们利用单片机将传感器数据直接推送到树莓派搭建的LANMP服务器中.在这个项目中,您将构建一个ESP32或ESP8266客户端,树莓派 Pi LAMP服务器(Linux,Apache,MySQL,PHP)发出HTTP POST请求。 树莓派 Pi具有一个PHP脚本,可将数据(传感器读数)插入MySQL数据库。

我们这次做一个网页,显示存储在数据库中的传感器读数,时间戳和其他信息。然后,从网络中的任何浏览器本地查看数据。
举例来说,用连接到ESP上的BME280传感器。您可以这里提供的代码,以从其他传感器发送读数或使用多个开发板。

要构建此项目,您需要的事项:

  • 在树莓派上上运行的LAMP服务器
  • 使用Arduino IDE编程的ESP32或ESP8266(也可以是PlatformIO)
  • PHP脚本将数据插入MySQL并显示在网页上
  • MySQL数据库存储读数

先决条件

在继续本教程之前你需要准备的只是:

  • 熟悉树莓派(不然你都不知道我说啥)
  • 已安装Raspbian或Raspbian Lite操作系统
  • 您还需要以下硬件:
    • Raspberry Pi board – read Best Raspberry Pi Starter Kits
    • MicroSD Card – 16GB Class10
    • Raspberry Pi Power Supply (5V 2.5A)
    • 要在树莓派上准备LAMP服务器,请遵循以下步骤:安装Apache + MySQL + PHP(LAMP服务器)

在使用Raspbian和LAMP服务器准备好树莓派开发板之后,就可以继续往下看了。

托管PHP应用程序和MySQL数据库树莓派

目标是让树莓派运行LAMP服务器,服务器允许您存储来自ESP32或ESP8266的传感器读数。您可以可视化来自本地网络中任何读数。

你还可以通过外网访问,不过这都是后话,新手还是先弄好本地访问再说.

准备MySQL数据库

按照以下步骤创建数据库和SQL表,打开浏览器并输入http//你的树莓派IP/phpmyadmin),您应该会看到phpMyAdmin Web界面的登录页面.

登录后,您应该会看到类似的页面:

创建数据库

  1. 选择顶部的“数据库”菜单,完成“创建数据库”字段:
    • esp_data
    • utf8mb4_general_ci

然后,按创建按钮:

新数据库已成功创建。现在,记住您的数据库名称,因为以后需要,数据库名称:esp_data

创建一个SQL表

创建数据库后,在左侧边栏中选择数据库名称esp_data

重要提示:请确保您已打开esp_data数据库。然后,单击“ SQL”选项卡。如果不遵循这些确切步骤并运行SQL查询,则可能在错误的数据库中创建了一个表。

在以下代码段中复制SQL查询:

CREATE TABLE SensorData (    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,    sensor VARCHAR(30) NOT NULL,    location VARCHAR(30) NOT NULL,    value1 VARCHAR(10),    value2 VARCHAR(10),    value3 VARCHAR(10),    reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)
SQL

打开“ SQL”选项卡,将其粘贴到SQL查询字段中(以红色矩形突出显示),然后按“执行”按钮创建表:

如果成功创建了表,则应显示以下内容:

之后,您应该在esp_data数据库中看到新创建的表SensorData,如下图所示:

PHP脚本HTTP POST-将数据插入MySQL数据库

在本部分中,我们将创建一个PHP脚本,该脚本负责接收来自ESP32或ESP8266的传入请求,并将数据插入MySQL数据库。您可以在设置为台式计算机的树莓派上运行下一个命令,也可以使用SSH连接。

nano /var/www/html/post-esp-data.php

注意:如果您正在阅读本教程,并且对PHP或MySQL不熟悉,建议您创建这些确切的文件。否则,您需要修改随其他网址路径.

将以下PHP脚本复制到新创建的文件(post-esp-data.php):

<?php $servername = "localhost"; $dbname = "REPLACE_WITH_YOUR_DATABASE_NAME"; $username = "REPLACE_WITH_YOUR_USERNAME"; $password = "REPLACE_WITH_YOUR_PASSWORD"; $api_key_value = "tPmAT5Ab3j7F9"; $api_key= $sensor = $location = $value1 = $value2 = $value3 = ""; if ($_SERVER["REQUEST_METHOD"] == "POST") {    $api_key = test_input($_POST["api_key"]);    if($api_key == $api_key_value) {        $sensor = test_input($_POST["sensor"]);        $location = test_input($_POST["location"]);        $value1 = test_input($_POST["value1"]);        $value2 = test_input($_POST["value2"]);        $value3 = test_input($_POST["value3"]);         $conn = new mysqli($servername, $username, $password, $dbname);         if ($conn->connect_error) {            die("Connection failed: " . $conn->connect_error);        }          $sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3)        VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";         if ($conn->query($sql) === TRUE) {            echo "New record created successfully";        }         else {            echo "Error: " . $sql . "<br>" . $conn->error;        }         $conn->close();    }    else {        echo "Wrong API Key provided.";    } }else {    echo "No data posted with HTTP POST.";} function test_input($data) {    $data = trim($data);    $data = stripslashes($data);    $data = htmlspecialchars($data);    return $data;}
PHP

保存文件之前,需要使用唯一的详细信息修改$dbname$username$password变量:

 $dbname = "esp_data"; $username = "root"; $password = "YOUR_USER_PASSWORD";
PHP

添加数据库名称,用户名和密码后,保存文件(Ctrl + X,y和Enter键)并继续本教程。

如果您尝试在下一个URL路径中访问树莓派的IP地址,则会看到以下内容:
http://You-Raspberry-Pi-IP-Address/post-esp-data.php

PHP脚本–显示数据库内容

/var/www/html目录中创建另一个PHP文件,该文件将在网页中显示所有数据库内容。命名您的新文件:esp-data.php

nano /var/www/html/esp-data.php

编辑新创建的文件(esp-data.php)并复制以下PHP脚本:

<!DOCTYPE html><html><body><?php $servername = "localhost"; $dbname = "REPLACE_WITH_YOUR_DATABASE_NAME"; $username = "REPLACE_WITH_YOUR_USERNAME"; $password = "REPLACE_WITH_YOUR_PASSWORD"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) {    die("Connection failed: " . $conn->connect_error);}  $sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData ORDER BY id DESC"; echo '<table cellspacing="5" cellpadding="5">      <tr>         <td>ID</td>         <td>Sensor</td>         <td>Location</td>         <td>Value 1</td>         <td>Value 2</td>        <td>Value 3</td>         <td>Timestamp</td>       </tr>'; if ($result = $conn->query($sql)) {    while ($row = $result->fetch_assoc()) {        $row_id = $row["id"];        $row_sensor = $row["sensor"];        $row_location = $row["location"];        $row_value1 = $row["value1"];        $row_value2 = $row["value2"];         $row_value3 = $row["value3"];         $row_reading_time = $row["reading_time"];         echo '<tr>                 <td>' . $row_id . '</td>                 <td>' . $row_sensor . '</td>                 <td>' . $row_location . '</td>                 <td>' . $row_value1 . '</td>                 <td>' . $row_value2 . '</td>                <td>' . $row_value3 . '</td>                 <td>' . $row_reading_time . '</td>               </tr>';    }    $result->free();} $conn->close();?> </table></body></html>
PHP

保存文件.
如果您尝试通过以下URL路径访问树莓派地址,则会看到以下内容:

5.准备您的ESP32或ESP8266
该项目与ESP32和ESP8266开发板均都兼容。您只需要组装一个简单的电路,实例代码在每30秒将温度,湿度,压力等添加到您的数据库中

所需材料

在此示例中,我们将从BME280传感器获取传感器读数。以下是为该项目构建电路所需的零件清单:

  • ESP32
  • 或者ESP8266
  • BME280传感器模块
  • 面包板

原理图

BME280传感器模块通过I2C通信协议进行通信,因此您需要将其连接到ESP32或ESP8266 I2C引脚。

BME280连线至ESP32

  • GPIO 22: SCL (SCK)
  • GPIO 21: SDA (SDI)

BME280连线至ESP8266

ESP8266 I2C引脚为:

  • GPIO 5 (D1): SCL (SCK)
  • GPIO 4 (D2): SDA (SDI)

ESP32/ESP8266 代码

#ifdef ESP32  #include <WiFi.h>  #include <HTTPClient.h>#else  #include <ESP8266WiFi.h>  #include <ESP8266HTTPClient.h>  #include <WiFiClient.h>#endif #include <Wire.h>#include <Adafruit_Sensor.h>#include <Adafruit_BME280.h> const char* ssid     = "REPLACE_WITH_YOUR_SSID";const char* password = "REPLACE_WITH_YOUR_PASSWORD";const char* serverName = "http://example.com/post-esp-data.php"; String apiKeyValue = "tPmAT5Ab3j7F9";String sensorName = "BME280";String sensorLocation = "Office"; /*#include <SPI.h>#define BME_SCK 18#define BME_MISO 19#define BME_MOSI 23#define BME_CS 5*/ #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme;  // I2C//Adafruit_BME280 bme(BME_CS);  // hardware SPI//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);  // software SPI void setup() {  Serial.begin(115200);   WiFi.begin(ssid, password);  Serial.println("Connecting");  while(WiFi.status() != WL_CONNECTED) {     delay(500);    Serial.print(".");  }  Serial.println("");  Serial.print("Connected to WiFi network with IP Address: ");  Serial.println(WiFi.localIP());   bool status = bme.begin(0x76);  if (!status) {    Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");    while (1);  }} void loop() {   if(WiFi.status()== WL_CONNECTED){    HTTPClient http;     http.begin(serverName);     http.addHeader("Content-Type", "application/x-www-form-urlencoded");     String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName                          + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())                          + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";    Serial.print("httpRequestData: ");    Serial.println(httpRequestData);     int httpResponseCode = http.POST(httpRequestData);     if (httpResponseCode>0) {      Serial.print("HTTP Response code: ");      Serial.println(httpResponseCode);    }    else {      Serial.print("Error code: ");      Serial.println(httpResponseCode);    }    http.end();  }  else {    Serial.println("WiFi Disconnected");  }  delay(30000);  }
C++

设置您的网络凭证

您需要使用网络凭据修改以下行:SSID和密码。该代码很好地注释了您应该在哪里进行更改。

const char* ssid     = "REPLACE_WITH_YOUR_SSID";const char* password = "REPLACE_WITH_YOUR_PASSWORD";
C++

设置您的服务器名

const char* serverName = "http://你的树莓派IP/post-esp-data.php";

将代码上传到板上。它应立即在ESP32或ESP8266板上运行了

代码解析

项目已经很长了,因此我们不会详细介绍代码的工作原理,但是这里有一个简短的摘要:

  • 设置您可能想要更改的变量(apiKeyValuesensorNamesensorLocation
  • apiKeyValue只是可以修改的随机字符串。出于安全原因使用它,因此只有知道您的API密钥的任何人才能将数据发布到您的数据库
  • 初始化串行通信以进行调试
  • 与路由器建立Wi-Fi连接
  • 初始化BME280以获取读数

然后,在loop()函数中,您实际上是每30秒发出一次HTTP POST请求,并获取最新的BME280读数:

// 你的域名或者IP地址http.begin(serverName); // 指定内容类型标题http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // 准备您的HTTP POST请求数据String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName                      + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())                      + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + ""; int httpResponseCode = http.POST(httpRequestData);
C++

您可以注释上面连接所有BME280读数的httpRequestData变量,并使用下面的httpRequestData变量进行测试:

String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

示范

如果一切正确,那么您应该在Arduino IDE串行监视器中看到以下内容:

如果您在此URL路径/esp-data.php中打开树莓派的IP地址:

http://你的树莓派IP/esp-data.php

您应该看到数据库中存储的所有读数。刷新网页以查看最新读数:

您也可以转到phpMyAdmin来管理存储在SensorData表中的数据。您可以删除,编辑等等.

总括

传感器数据发布到您自己的本地树莓派LAMP服务器中的数据库中.这里写的示例代码尽可能简单,只是为了以便您了解所有基本工作原理。你可以用不同的传感器,让读书从多个ESP板发布数据.在理解了此示例后,您可以更改表格的外观之类,如下图:



一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。