Визуализация показаний датчиков ESP32/ESP8266 из любой точки мира (MySQL + PHP)

В этом проекте вы создадите веб-страницу, которая отображает показания датчиков на графике, к которому можно получить доступ из любой точки мира. Вкратце, вы создадите ESP32 или ESP8266 клиент, который отправляет запрос к PHP-скрипту для публикации показаний датчиков в базу данных MySQL.

ESP32 ESP8266 Insert Data into MySQL Database using PHP and Arduino IDE - Визуализация показаний датчиков из любой точки мира

В качестве примера мы будем использовать датчик BME280, подключённый к плате ESP. Вы можете модифицировать предоставленный код для отправки показаний с другого датчика или использовать несколько плат.

Для создания этого проекта вам понадобятся следующие технологии:

  • ESP32 или ESP8266, программируемые через Arduino IDE

  • Хостинг-сервер и доменное имя

  • PHP-скрипт для вставки данных в базу данных MySQL и их отображения на веб-странице

  • База данных MySQL для хранения показаний

  • PHP-скрипт для построения графиков по данным из базы

Вам также могут пригодиться следующие проекты:

Проект разделён на следующие основные разделы:

  1. Хостинг вашего PHP-приложения и базы данных MySQL

  2. Подготовка базы данных MySQL

  3. PHP-скрипт HTTP POST — Вставка данных в базу MySQL

  4. PHP-скрипт — Визуализация содержимого базы данных на графике

  5. Настройка ESP32 или ESP8266

Смотрите видео-демонстрацию

Чтобы увидеть, как работает проект, вы можете посмотреть следующую видео-демонстрацию:

1. Хостинг вашего PHP-приложения и базы данных MySQL

Цель этого проекта — иметь собственное доменное имя и хостинг-аккаунт, который позволяет хранить показания датчиков с ESP32 или ESP8266. Вы сможете просматривать показания из любой точки мира, обращаясь к своему серверу. Вот общая схема проекта:

Hosting PHP Application и MySQL Database для публикации показаний ESP32 или ESP8266

Я рекомендую использовать один из следующих хостинг-сервисов, которые удовлетворяют всем требованиям проекта:

  • Bluehost (удобный с cPanel): бесплатное доменное имя при подписке на 3-летний план. Рекомендую выбрать опцию с неограниченным количеством сайтов;

  • Digital Ocean: Linux-сервер, которым вы управляете через командную строку. Рекомендую только для продвинутых пользователей.

Эти два сервиса я использую лично и рекомендую, но вы можете использовать любой другой хостинг. Любой хостинг, предлагающий PHP и MySQL, подойдёт для этого руководства. Если у вас нет хостинг-аккаунта, рекомендую зарегистрироваться на Bluehost.

При покупке хостинг-аккаунта вам также потребуется приобрести доменное имя. Именно это делает проект интересным: вы сможете перейти по своему доменному имени (http://example.com) и увидеть показания ESP.

Примечание

Вы также можете запустить LAMP-сервер (Linux, Apache, MySQL, PHP) на Raspberry Pi для доступа к данным в локальной сети. Однако цель этого руководства — публикация показаний на собственном доменном имени, к которому можно получить доступ из любой точки мира. Это позволяет легко получить доступ к показаниям ESP без зависимости от сторонних IoT-платформ.

2. Подготовка базы данных MySQL

После регистрации на хостинге и настройки доменного имени, вы можете войти в cPanel или аналогичную панель управления. После этого выполните следующие шаги для создания базы данных, имени пользователя, пароля и SQL-таблицы.

Создание базы данных и пользователя

Откройте вкладку «Advanced»:

Bluehost Advanced tab

1. Введите «database» в строку поиска и выберите «MySQL Database Wizard».

CPanel select MySQL database wizard to create db

2. Введите желаемое имя базы данных. В моём случае имя базы данных — esp_data. Затем нажмите кнопку «Next Step»:

ESP32 ESP8266 CPanel Create MySQL Database

Примечание

Позже вам нужно будет использовать имя базы данных с префиксом, который даёт ваш хост (мой префикс базы данных на скриншоте выше скрыт). Далее я буду называть его example_esp_data.

3. Введите имя пользователя базы данных и установите пароль. Вы должны сохранить все эти данные, так как они понадобятся позже для установки соединения с базой данных в PHP-коде.

ESP32 ESP8266 CPanel Create MySQL Database User and Password

Вот и всё! Ваша новая база данных и пользователь успешно созданы. Теперь сохраните все ваши данные, они понадобятся позже:

  • Имя базы данных: example_esp_data

  • Имя пользователя: example_esp_board

  • Пароль: ваш пароль

Создание SQL-таблицы

После создания базы данных и пользователя вернитесь в панель управления cPanel и найдите «phpMyAdmin».

ESP32 ESP8266 CPanel Open PHPMyAdmin

В левой боковой панели выберите имя вашей базы данных example_esp_data и откройте вкладку «SQL».

ESP32 ESP8266 PHPMyAdmin Open Database

Важно: убедитесь, что вы открыли именно базу данных example_esp_data. Затем нажмите вкладку SQL. Если вы не выполните эти точные шаги и запустите SQL-запрос, вы можете создать таблицу в неправильной базе данных.

Скопируйте SQL-запрос из следующего фрагмента:

CREATE TABLE Sensor (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    value1 VARCHAR(10),
    value2 VARCHAR(10),
    value3 VARCHAR(10),
    reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)

Просмотреть исходный код

Вставьте его в поле SQL-запроса (выделено красным прямоугольником) и нажмите кнопку «Go», чтобы создать таблицу:

ESP32 ESP8266 PHPMyAdmin Create SQL Sensor Table

После этого вы должны увидеть вашу только что созданную таблицу Sensor в базе данных example_esp_data, как показано на рисунке ниже:

ESP32 ESP8266 PHPMyAdmin View SQL Database

3. PHP-скрипт HTTP POST — Вставка данных в базу MySQL

В этом разделе мы создадим PHP-скрипт, который принимает входящие запросы от ESP32 или ESP8266 и вставляет данные в базу данных MySQL.

Если вы используете хостинг-провайдера с cPanel, найдите «File Manager»:

ESP32 ESP8266 CPanel Open Edit PHP Files with File Manager

Затем выберите опцию public_html и нажмите кнопку «+ File», чтобы создать новый файл .php.

ESP32 ESP8266 CPanel Create New PHP File using File Manager

Примечание

Если вы следуете этому руководству и не знакомы с PHP или MySQL, рекомендую создавать файлы с точно такими же именами. Иначе вам придётся модифицировать скетч ESP с другими путями URL.

Создайте новый файл в /public_html с таким именем и расширением: post-data.php

PHP Create New file post data .php

Отредактируйте только что созданный файл (post-data.php) и скопируйте следующий фрагмент:

<?php
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

$servername = "localhost";

// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";

// Keep this API Key value to be compatible with the ESP32 code provided in the project page. If you change this value, the ESP32 sketch needs to match
$api_key_value = "tPmAT5Ab3j7F9";

$api_key = $value1 = $value2 = $value3 = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $api_key = test_input($_POST["api_key"]);
    if($api_key == $api_key_value) {
        $value1 = test_input($_POST["value1"]);
        $value2 = test_input($_POST["value2"]);
        $value3 = test_input($_POST["value3"]);

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "INSERT INTO Sensor (value1, value2, value3)
        VALUES ('" . $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 на свои уникальные данные:

// Your Database name
$dbname = "example_esp_data";
// Your Database user
$username = "example_esp_board";
// Your Database user password
$password = "YOUR_USER_PASSWORD";

После добавления имени базы данных, имени пользователя и пароля сохраните файл и продолжите это руководство. Если вы попытаетесь обратиться к вашему доменному имени по следующему URL-пути, вы увидите сообщение:

http://example.com/post-data.php
ESP32 ESP8266 Test POST Data PHP URL

4. PHP-скрипт — Визуализация содержимого базы данных на графике

Создайте ещё один PHP-файл в директории /public_html, который будет отображать содержимое базы данных на графике на веб-странице. Назовите ваш новый файл: esp-chart.php

PHP Create New file esp chart data .php

Отредактируйте только что созданный файл (esp-chart.php) и скопируйте следующий код:

<!--
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

-->
<?php

$servername = "localhost";

// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT id, value1, value2, value3, reading_time FROM Sensor order by reading_time desc limit 40";

$result = $conn->query($sql);

while ($data = $result->fetch_assoc()){
    $sensor_data[] = $data;
}

$readings_time = array_column($sensor_data, 'reading_time');

// ******* Uncomment to convert readings time array to your timezone ********
/*$i = 0;
foreach ($readings_time as $reading){
    // Uncomment to set timezone to - 1 hour (you can change 1 to any number)
    $readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading - 1 hours"));
    // Uncomment to set timezone to + 4 hours (you can change 4 to any number)
    //$readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading + 4 hours"));
    $i += 1;
}*/

$value1 = json_encode(array_reverse(array_column($sensor_data, 'value1')), JSON_NUMERIC_CHECK);
$value2 = json_encode(array_reverse(array_column($sensor_data, 'value2')), JSON_NUMERIC_CHECK);
$value3 = json_encode(array_reverse(array_column($sensor_data, 'value3')), JSON_NUMERIC_CHECK);
$reading_time = json_encode(array_reverse($readings_time), JSON_NUMERIC_CHECK);

/*echo $value1;
echo $value2;
echo $value3;
echo $reading_time;*/

$result->free();
$conn->close();
?>

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <style>
    body {
      min-width: 310px;
      max-width: 1280px;
      height: 500px;
      margin: 0 auto;
    }
    h2 {
      font-family: Arial;
      font-size: 2.5rem;
      text-align: center;
    }
  </style>
  <body>
    <h2>ESP Weather Station</h2>
    <div id="chart-temperature" class="container"></div>
    <div id="chart-humidity" class="container"></div>
    <div id="chart-pressure" class="container"></div>
<script>

var value1 = <?php echo $value1; ?>;
var value2 = <?php echo $value2; ?>;
var value3 = <?php echo $value3; ?>;
var reading_time = <?php echo $reading_time; ?>;

var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: 'BME280 Temperature' },
  series: [{
    showInLegend: false,
    data: value1
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#059e8a' }
  },
  xAxis: {
    type: 'datetime',
    categories: reading_time
  },
  yAxis: {
    title: { text: 'Temperature (Celsius)' }
    //title: { text: 'Temperature (Fahrenheit)' }
  },
  credits: { enabled: false }
});

var chartH = new Highcharts.Chart({
  chart:{ renderTo:'chart-humidity' },
  title: { text: 'BME280 Humidity' },
  series: [{
    showInLegend: false,
    data: value2
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    }
  },
  xAxis: {
    type: 'datetime',
    //dateTimeLabelFormats: { second: '%H:%M:%S' },
    categories: reading_time
  },
  yAxis: {
    title: { text: 'Humidity (%)' }
  },
  credits: { enabled: false }
});

var chartP = new Highcharts.Chart({
  chart:{ renderTo:'chart-pressure' },
  title: { text: 'BME280 Pressure' },
  series: [{
    showInLegend: false,
    data: value3
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#18009c' }
  },
  xAxis: {
    type: 'datetime',
    categories: reading_time
  },
  yAxis: {
    title: { text: 'Pressure (hPa)' }
  },
  credits: { enabled: false }
});

</script>
</body>
</html>

Просмотреть исходный код

После добавления $dbname, $username и $password сохраните файл и продолжите проект.

// Your Database name
$dbname = "example_esp_data";
// Your Database user
$username = "example_esp_board";
// Your Database user password
$password = "YOUR_USER_PASSWORD";

Если вы попытаетесь обратиться к вашему доменному имени по следующему URL-пути, вы увидите следующее:

https://example.com/esp-chart.php
ESP32 ESP8266 Test ESP Data PHP URL — пустые графики

Вот и всё! Если вы видите три пустых графика в браузере, значит всё готово. В следующем разделе вы узнаете, как публиковать показания ESP32 или ESP8266.

Для построения графиков мы используем библиотеку Highcharts. Мы создадим три графика: температура, влажность и давление по времени. Графики отображают максимум 40 точек данных, и новое показание добавляется каждые 30 секунд, но вы можете изменить эти значения в коде.

5. Настройка ESP32 или ESP8266

Этот проект совместим с платами ESP32 и ESP8266. Вам нужно просто собрать простую схему и загрузить предоставленный скетч для вставки показаний температуры, влажности, давления и других данных в базу каждые 30 секунд. Скетч немного отличается для каждой платы.

ESP32 vs ESP8266 Development Boards

Необходимые компоненты

Для этого примера мы получим показания от датчика BME280. Вот список компонентов, необходимых для сборки схемы этого проекта:

Схемы подключения

Модуль датчика BME280, который мы используем, обменивается данными по протоколу I2C, поэтому его нужно подключить к пинам I2C платы ESP32 или ESP8266.

BME280 подключение к ESP32

Пины I2C ESP32:

  • GPIO 22: SCL (SCK)

  • GPIO 21: SDA (SDI)

Соберите схему, как показано на следующей схеме (читайте полное руководство по ESP32 с BME280).

BME280 I2C wiring to ESP32 - circuit schematic diagram SDA SCL

Рекомендуем прочитать: Справочник по распиновке ESP32

BME280 подключение к ESP8266

Пины I2C ESP8266:

  • GPIO 5 (D1): SCL (SCK)

  • GPIO 4 (D2): SDA (SDI)

Соберите схему, как показано на следующей диаграмме, если вы используете плату ESP8266 (читайте полное руководство по ESP8266 с BME280).

BME280 I2C wiring to ESP8266 - circuit schematic diagram SDA SCL

Рекомендуем прочитать: Справочник по распиновке ESP8266

Установка библиотек

Мы будем программировать ESP32/ESP8266 через Arduino IDE, поэтому у вас должен быть установлен дополнительный модуль ESP32/ESP8266 в Arduino IDE. Следуйте одному из следующих руководств в зависимости от используемой платы:

Код для ESP32

Следуйте этому разделу, если вы используете ESP32. Для ESP8266 нажмите здесь.

После установки необходимых дополнений скопируйте следующий код в Arduino IDE, но пока не загружайте его. Вам нужно внести некоторые изменения, чтобы он работал.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

*/

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE with your Domain name and URL path or IP address with path
//const char* serverName = "https://example.com/post-data.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "tPmAT5Ab3j7F9";

/*#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());

  // (you can also pass in a Wire library object like &Wire2)
  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() {
  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    WiFiClientSecure *client = new WiFiClientSecure;
    client->setInsecure(); //don't use SSL certificate
    HTTPClient https;

    // Your Domain name with URL path or IP address with path
    https.begin(*client, serverName);

    // Specify content-type header
    https.addHeader("Content-Type", "application/x-www-form-urlencoded");

    // Prepare your HTTP POST request data

    String httpRequestData = "api_key=" + apiKeyValue + "&value1=" + String(bme.readTemperature())
                           + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";

    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);

    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = https.POST(httpRequestData);

    // If you need an HTTP request with a content type: text/plain
    //https.addHeader("Content-Type", "text/plain");
    //int httpResponseCode = https.POST("Hello, World!");

    // If you need an HTTP request with a content type: application/json, use the following:
    //https.addHeader("Content-Type", "application/json");
    //int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");

    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    https.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);
}

Просмотреть исходный код

Настройка сетевых учётных данных (ESP32)

Вам нужно изменить следующие строки, указав свои сетевые данные: SSID и пароль. В коде есть комментарии, указывающие, где именно нужно внести изменения.

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Настройка serverName (ESP32)

Вам также нужно указать ваше доменное имя, чтобы ESP публиковал показания на ваш собственный сервер.

const char* serverName = "https://example.com/post-data.php";

Теперь вы можете загрузить код на плату.

Примечание

Большинство серверов требуют HTTPS-запросов. Приведённый выше код выполняет HTTPS-запросы для совместимости с требованиями большинства современных облачных серверов.

Ваш сервер не поддерживает HTTPS? Используйте этот код вместо него.

Как работает код (ESP32)

Этот проект и так достаточно объёмный, поэтому мы не будем подробно разбирать работу кода, но вот краткое описание:

  • Импорт всех библиотек для работы;

  • Установка переменных, которые вы можете изменить (apiKeyValue);

  • apiKeyValue — это просто случайная строка, которую вы можете изменить. Она используется для безопасности, чтобы только тот, кто знает ваш API-ключ, мог публиковать данные в вашу базу;

  • Инициализация последовательного соединения для отладки;

  • Установка Wi-Fi соединения с маршрутизатором;

  • Инициализация BME280 для получения показаний;

  • Инициализация защищённого WiFi-клиента.

Затем в loop() выполняется HTTP POST запрос каждые 30 секунд с последними показаниями BME280:

// Your Domain name with URL path or IP address with path
http.begin(serverName);

// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&value1="
                       + String(bme.readTemperature())
                       + "&value2=" + String(bme.readHumidity())
                       + "&value3=" + String(bme.readPressure()/100.0F) + "";

int httpResponseCode = http.POST(httpRequestData);

Вы можете закомментировать переменную httpRequestData выше, которая объединяет все показания BME280, и использовать переменную httpRequestData ниже для целей тестирования:

String httpRequestData = "api_key=tPmAT5Ab3j7F9&value1=24.75&value2=49.54&value3=1005.14";

Подробнее о HTTPS-запросах с ESP32: ESP32 HTTPS Requests (Arduino IDE).

Код для ESP8266

Следуйте этому разделу, если вы используете ESP8266. Для ESP32 смотрите раздел выше.

После установки необходимых дополнений и библиотек скопируйте следующий код в Arduino IDE, но пока не загружайте его. Вам нужно внести некоторые изменения, чтобы он работал.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "https://example.com/post-data.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "tPmAT5Ab3j7F9";

/*#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());

  // (you can also pass in a Wire library object like &Wire2)
  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() {
  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){

    std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);

    // Ignore SSL certificate validation
    client->setInsecure();

    //create an HTTPClient instance
    HTTPClient https;

    // Your Domain name with URL path or IP address with path
    https.begin(*client, serverName);

    // Specify content-type header
    https.addHeader("Content-Type", "application/x-www-form-urlencoded");

    // Prepare your HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&value1=" + String(bme.readTemperature())
                           + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);

    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = https.POST(httpRequestData);

    // If you need an HTTP request with a content type: text/plain
    //http.addHeader("Content-Type", "text/plain");
    //int httpResponseCode = https.POST("Hello, World!");

    // If you need an HTTP request with a content type: application/json, use the following:
    //http.addHeader("Content-Type", "application/json");
    //int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");

    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    https.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);
}

Просмотреть исходный код

Настройка сетевых учётных данных (ESP8266)

Вам нужно изменить следующие строки, указав свои сетевые данные: SSID и пароль. В коде есть комментарии, указывающие, где именно нужно внести изменения.

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Настройка serverName (ESP8266)

Вам также нужно указать ваше доменное имя, чтобы ESP публиковал показания на ваш собственный сервер.

const char* serverName = "https://example.com/post-data.php";

Теперь вы можете загрузить код на плату.

Примечание

Большинство серверов требуют HTTPS-запросов. Приведённый выше код выполняет HTTPS-запросы для совместимости с требованиями большинства современных облачных серверов.

Ваш сервер не поддерживает HTTPS? Используйте этот код вместо него.

Подробнее о HTTPS-запросах с ESP8266: ESP8266 NodeMCU HTTPS Requests (Arduino IDE).

Демонстрация

После выполнения всех шагов позвольте плате ESP собрать несколько показаний и опубликовать их на ваш сервер.

ESP32 BME280 Temperature Humidity and Pressure sensor publishing readings using Arduino IDE, MySQL, and PHP

Если всё правильно, вот что вы должны увидеть в Serial Monitor Arduino IDE:

ESP32 ESP8266 BME280 Readings Arduino IDE Serial Monitor

Если вы откроете ваше доменное имя по следующему URL-пути:

https://example.com/esp-chart.php

Вы должны увидеть все показания, сохранённые в базе данных. Обновите веб-страницу, чтобы увидеть последние показания:

ESP32 ESP8266 View BME280 Sensor Readings (Temperature, Humidity, and Pressure) — графики с данными

Вы также можете зайти в phpMyAdmin для управления данными, хранящимися в таблице Sensor. Вы можете удалять, редактировать данные и т.д.

ESP32 ESP8266 View Sensor Readings PHPMyAdmin SQL Database

Заключение

В этом руководстве вы узнали, как публиковать данные датчиков в базу данных на собственном серверном домене, к которому можно получить доступ из любой точки мира. Для этого необходимо иметь собственный сервер и доменное имя (вы также можете использовать Raspberry Pi для локального доступа).

С такой настройкой вы контролируете свой сервер и можете перейти к другому хосту при необходимости. Существует множество облачных решений, как бесплатных, так и платных, которые вы можете использовать для публикации показаний, но эти сервисы могут иметь ряд недостатков: ограничения на количество публикуемых показаний, количество подключённых устройств, кто может видеть ваши данные и т.д. Кроме того, облачный сервис может быть прекращён или изменён в любое время.

Предоставленный пример максимально прост, чтобы вы поняли, как всё работает. После понимания этого примера вы можете изменить внешний вид веб-страницы, публиковать показания других датчиков, публиковать данные с нескольких плат ESP и многое другое.

Вам также может быть интересно:

Узнайте больше об ESP32 с нашими ресурсами:

Источник: :doc:`Visualize Your Sensor Readings from Anywhere in the World (ESP32/ESP8266 + MySQL + PHP) <../visualize-esp32-esp8266-sensor-readings-from-anywhere/index>` — Random Nerd Tutorials