上次我们讲述了怎么样搭建LAMP,然而怎么样应用到实际领域中呢?有人说搭建博客,没错我的博客也是这么来的,这也是LAMP的一种典型实例,可是这种实例烂大街,都不香了 .这次我们利用单片机将传感器数据直接推送到树莓派搭建的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界面的登录页面.
登录后,您应该会看到类似的页面:
创建数据库
- 选择顶部的“数据库”菜单,完成“创建数据库”字段:
- 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查询字段中(以红色矩形突出显示),然后按“执行”按钮创建表:
如果成功创建了表,则应显示以下内容:
之后,您应该在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;
}
保存文件之前,需要使用唯一的详细信息修改$dbname
,$username
和$password
变量:
$dbname = "esp_data";
$username = "root";
$password = "YOUR_USER_PASSWORD";
添加数据库名称,用户名和密码后,保存文件(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>
保存文件.
如果您尝试通过以下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);
}
设置您的网络凭证
您需要使用网络凭据修改以下行:SSID和密码。该代码很好地注释了您应该在哪里进行更改。
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
设置您的服务器名
const char* serverName = "http://你的树莓派IP/post-esp-data.php";
将代码上传到板上。它应立即在ESP32或ESP8266板上运行了
代码解析
项目已经很长了,因此我们不会详细介绍代码的工作原理,但是这里有一个简短的摘要:
- 设置您可能想要更改的变量(
apiKeyValue
,sensorName
,sensorLocation
) 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);
您可以注释上面连接所有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板发布数据.在理解了此示例后,您可以更改表格的外观之类,如下图: