├── project-image.jpg
├── code
├── SensorData_Table.sql
├── post-esp-data.php
├── esp-data.php
├── ESP32_ESP8266_MySQL_Database_PHP.ino
├── HTTPS_ESP32_MySQL_Database_PHP.ino
└── HTTPS_ESP8266_MySQL_Database_PHP.ino
└── README.md
/project-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RuiSantosdotme/ESP32-ESP8266-PHP-MySQL/HEAD/project-image.jpg
--------------------------------------------------------------------------------
/code/SensorData_Table.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE SensorData (
2 | id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
3 | sensor VARCHAR(30) NOT NULL,
4 | location VARCHAR(30) NOT NULL,
5 | value1 VARCHAR(10),
6 | value2 VARCHAR(10),
7 | value3 VARCHAR(10),
8 | reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
9 | )
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ESP32/ESP8266 Insert Data into MySQL Database using PHP and Arduino IDE
2 |
3 | In this project you’ll build an ESP32 or ESP8266 client that makes an HTTP POST request to a PHP script to insert data (sensor readings) into a MySQL database.
4 |
5 | Complete project details: https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
6 |
7 | [](https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/)
8 |
--------------------------------------------------------------------------------
/code/post-esp-data.php:
--------------------------------------------------------------------------------
1 | connect_error) {
42 | die("Connection failed: " . $conn->connect_error);
43 | }
44 |
45 | $sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3)
46 | VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";
47 |
48 | if ($conn->query($sql) === TRUE) {
49 | echo "New record created successfully";
50 | }
51 | else {
52 | echo "Error: " . $sql . "
" . $conn->error;
53 | }
54 |
55 | $conn->close();
56 | }
57 | else {
58 | echo "Wrong API Key provided.";
59 | }
60 |
61 | }
62 | else {
63 | echo "No data posted with HTTP POST.";
64 | }
65 |
66 | function test_input($data) {
67 | $data = trim($data);
68 | $data = stripslashes($data);
69 | $data = htmlspecialchars($data);
70 | return $data;
71 | }
72 |
--------------------------------------------------------------------------------
/code/esp-data.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | connect_error) {
28 | die("Connection failed: " . $conn->connect_error);
29 | }
30 |
31 | $sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData ORDER BY id DESC";
32 |
33 | echo '
34 |
35 | | ID |
36 | Sensor |
37 | Location |
38 | Value 1 |
39 | Value 2 |
40 | Value 3 |
41 | Timestamp |
42 |
';
43 |
44 | if ($result = $conn->query($sql)) {
45 | while ($row = $result->fetch_assoc()) {
46 | $row_id = $row["id"];
47 | $row_sensor = $row["sensor"];
48 | $row_location = $row["location"];
49 | $row_value1 = $row["value1"];
50 | $row_value2 = $row["value2"];
51 | $row_value3 = $row["value3"];
52 | $row_reading_time = $row["reading_time"];
53 | // Uncomment to set timezone to - 1 hour (you can change 1 to any number)
54 | //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time - 1 hours"));
55 |
56 | // Uncomment to set timezone to + 4 hours (you can change 4 to any number)
57 | //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time + 4 hours"));
58 |
59 | echo '
60 | | ' . $row_id . ' |
61 | ' . $row_sensor . ' |
62 | ' . $row_location . ' |
63 | ' . $row_value1 . ' |
64 | ' . $row_value2 . ' |
65 | ' . $row_value3 . ' |
66 | ' . $row_reading_time . ' |
67 |
';
68 | }
69 | $result->free();
70 | }
71 |
72 | $conn->close();
73 | ?>
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/code/ESP32_ESP8266_MySQL_Database_PHP.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Rui Santos
3 | Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files.
7 |
8 | The above copyright notice and this permission notice shall be included in all
9 | copies or substantial portions of the Software.
10 |
11 | */
12 |
13 | #ifdef ESP32
14 | #include
15 | #include
16 | #else
17 | #include
18 | #include
19 | #include
20 | #endif
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | // Replace with your network credentials
27 | const char* ssid = "REPLACE_WITH_YOUR_SSID";
28 | const char* password = "REPLACE_WITH_YOUR_PASSWORD";
29 |
30 | // REPLACE with your Domain name and URL path or IP address with path
31 | const char* serverName = "http://example.com/post-esp-data.php";
32 |
33 | // Keep this API Key value to be compatible with the PHP code provided in the project page.
34 | // If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
35 | String apiKeyValue = "tPmAT5Ab3j7F9";
36 |
37 | String sensorName = "BME280";
38 | String sensorLocation = "Office";
39 |
40 | /*#include
41 | #define BME_SCK 18
42 | #define BME_MISO 19
43 | #define BME_MOSI 23
44 | #define BME_CS 5*/
45 |
46 | #define SEALEVELPRESSURE_HPA (1013.25)
47 |
48 | Adafruit_BME280 bme; // I2C
49 | //Adafruit_BME280 bme(BME_CS); // hardware SPI
50 | //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
51 |
52 | void setup() {
53 | Serial.begin(115200);
54 |
55 | WiFi.begin(ssid, password);
56 | Serial.println("Connecting");
57 | while(WiFi.status() != WL_CONNECTED) {
58 | delay(500);
59 | Serial.print(".");
60 | }
61 | Serial.println("");
62 | Serial.print("Connected to WiFi network with IP Address: ");
63 | Serial.println(WiFi.localIP());
64 |
65 | // (you can also pass in a Wire library object like &Wire2)
66 | bool status = bme.begin(0x76);
67 | if (!status) {
68 | Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
69 | while (1);
70 | }
71 | }
72 |
73 | void loop() {
74 | //Check WiFi connection status
75 | if(WiFi.status()== WL_CONNECTED){
76 | WiFiClient client;
77 | HTTPClient http;
78 |
79 | // Your Domain name with URL path or IP address with path
80 | http.begin(client, serverName);
81 |
82 | // Specify content-type header
83 | http.addHeader("Content-Type", "application/x-www-form-urlencoded");
84 |
85 | // Prepare your HTTP POST request data
86 | String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
87 | + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
88 | + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
89 | Serial.print("httpRequestData: ");
90 | Serial.println(httpRequestData);
91 |
92 | // You can comment the httpRequestData variable above
93 | // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
94 | //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
95 |
96 | // Send HTTP POST request
97 | int httpResponseCode = http.POST(httpRequestData);
98 |
99 | // If you need an HTTP request with a content type: text/plain
100 | //http.addHeader("Content-Type", "text/plain");
101 | //int httpResponseCode = http.POST("Hello, World!");
102 |
103 | // If you need an HTTP request with a content type: application/json, use the following:
104 | //http.addHeader("Content-Type", "application/json");
105 | //int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
106 |
107 | if (httpResponseCode>0) {
108 | Serial.print("HTTP Response code: ");
109 | Serial.println(httpResponseCode);
110 | }
111 | else {
112 | Serial.print("Error code: ");
113 | Serial.println(httpResponseCode);
114 | }
115 | // Free resources
116 | http.end();
117 | }
118 | else {
119 | Serial.println("WiFi Disconnected");
120 | }
121 | //Send an HTTP POST request every 30 seconds
122 | delay(30000);
123 | }
124 |
--------------------------------------------------------------------------------
/code/HTTPS_ESP32_MySQL_Database_PHP.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Rui Santos
3 | Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files.
7 |
8 | The above copyright notice and this permission notice shall be included in all
9 | copies or substantial portions of the Software.
10 |
11 | */
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // Replace with your network credentials
21 | const char* ssid = "REPLACE_WITH_YOUR_SSID";
22 | const char* password = "REPLACE_WITH_YOUR_PASSWORD";
23 |
24 | // REPLACE with your Domain name and URL path or IP address with path
25 | const char* serverName = "https://example.com/post-esp-data.php";
26 |
27 | // Keep this API Key value to be compatible with the PHP code provided in the project page.
28 | // If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
29 | String apiKeyValue = "tPmAT5Ab3j7F9";
30 |
31 | String sensorName = "BME280";
32 | String sensorLocation = "Office";
33 |
34 | /*#include
35 | #define BME_SCK 18
36 | #define BME_MISO 19
37 | #define BME_MOSI 23
38 | #define BME_CS 5*/
39 |
40 | #define SEALEVELPRESSURE_HPA (1013.25)
41 |
42 | Adafruit_BME280 bme; // I2C
43 | //Adafruit_BME280 bme(BME_CS); // hardware SPI
44 | //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
45 |
46 | void setup() {
47 | Serial.begin(115200);
48 |
49 | WiFi.begin(ssid, password);
50 | Serial.println("Connecting");
51 | while(WiFi.status() != WL_CONNECTED) {
52 | delay(500);
53 | Serial.print(".");
54 | }
55 | Serial.println("");
56 | Serial.print("Connected to WiFi network with IP Address: ");
57 | Serial.println(WiFi.localIP());
58 |
59 | // (you can also pass in a Wire library object like &Wire2)
60 | bool status = bme.begin(0x76);
61 | if (!status) {
62 | Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
63 | while (1);
64 | }
65 | }
66 |
67 | void loop() {
68 | //Check WiFi connection status
69 | if(WiFi.status()== WL_CONNECTED){
70 | WiFiClientSecure *client = new WiFiClientSecure;
71 | client->setInsecure(); //don't use SSL certificate
72 | HTTPClient https;
73 |
74 | // Your Domain name with URL path or IP address with path
75 | https.begin(*client, serverName);
76 |
77 | // Specify content-type header
78 | https.addHeader("Content-Type", "application/x-www-form-urlencoded");
79 |
80 | // Prepare your HTTP POST request data
81 | String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
82 | + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
83 | + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
84 | Serial.print("httpRequestData: ");
85 | Serial.println(httpRequestData);
86 |
87 | // You can comment the httpRequestData variable above
88 | // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
89 | //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
90 |
91 | // Send HTTP POST request
92 | int httpResponseCode = https.POST(httpRequestData);
93 |
94 | // If you need an HTTP request with a content type: text/plain
95 | //https.addHeader("Content-Type", "text/plain");
96 | //int httpResponseCode = https.POST("Hello, World!");
97 |
98 | // If you need an HTTP request with a content type: application/json, use the following:
99 | //https.addHeader("Content-Type", "application/json");
100 | //int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
101 |
102 | if (httpResponseCode>0) {
103 | Serial.print("HTTP Response code: ");
104 | Serial.println(httpResponseCode);
105 | }
106 | else {
107 | Serial.print("Error code: ");
108 | Serial.println(httpResponseCode);
109 | }
110 | // Free resources
111 | https.end();
112 | }
113 | else {
114 | Serial.println("WiFi Disconnected");
115 | }
116 | //Send an HTTP POST request every 30 seconds
117 | delay(30000);
118 | }
119 |
--------------------------------------------------------------------------------
/code/HTTPS_ESP8266_MySQL_Database_PHP.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Rui Santos
3 | Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files.
7 |
8 | The above copyright notice and this permission notice shall be included in all
9 | copies or substantial portions of the Software.
10 |
11 | */
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // Replace with your network credentials
21 | const char* ssid = "REPLACE_WITH_YOUR_SSID";
22 | const char* password = "REPLACE_WITH_YOUR_PASSWORD";
23 |
24 | // REPLACE with your Domain name and URL path or IP address with path
25 | const char* serverName = "https://example.com/post-esp-data.php";
26 |
27 | // Keep this API Key value to be compatible with the PHP code provided in the project page.
28 | // If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
29 | String apiKeyValue = "tPmAT5Ab3j7F9";
30 |
31 | String sensorName = "BME280";
32 | String sensorLocation = "Office";
33 |
34 | /*#include
35 | #define BME_SCK 18
36 | #define BME_MISO 19
37 | #define BME_MOSI 23
38 | #define BME_CS 5*/
39 |
40 | #define SEALEVELPRESSURE_HPA (1013.25)
41 |
42 | Adafruit_BME280 bme; // I2C
43 | //Adafruit_BME280 bme(BME_CS); // hardware SPI
44 | //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
45 |
46 | void setup() {
47 | Serial.begin(115200);
48 |
49 | WiFi.begin(ssid, password);
50 | Serial.println("Connecting");
51 | while(WiFi.status() != WL_CONNECTED) {
52 | delay(500);
53 | Serial.print(".");
54 | }
55 | Serial.println("");
56 | Serial.print("Connected to WiFi network with IP Address: ");
57 | Serial.println(WiFi.localIP());
58 |
59 | // (you can also pass in a Wire library object like &Wire2)
60 | bool status = bme.begin(0x76);
61 | if (!status) {
62 | Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
63 | while (1);
64 | }
65 | }
66 |
67 | void loop() {
68 | //Check WiFi connection status
69 | if(WiFi.status()== WL_CONNECTED){
70 |
71 | std::unique_ptrclient(new BearSSL::WiFiClientSecure);
72 |
73 | // Ignore SSL certificate validation
74 | client->setInsecure();
75 |
76 | //create an HTTPClient instance
77 | HTTPClient https;
78 |
79 | // Your Domain name with URL path or IP address with path
80 | https.begin(*client, serverName);
81 |
82 | // Specify content-type header
83 | https.addHeader("Content-Type", "application/x-www-form-urlencoded");
84 |
85 | // Prepare your HTTP POST request data
86 | String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
87 | + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
88 | + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
89 | Serial.print("httpRequestData: ");
90 | Serial.println(httpRequestData);
91 |
92 | // You can comment the httpRequestData variable above
93 | // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
94 | //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
95 |
96 | // Send HTTP POST request
97 | int httpResponseCode = https.POST(httpRequestData);
98 |
99 | // If you need an HTTP request with a content type: text/plain
100 | //http.addHeader("Content-Type", "text/plain");
101 | //int httpResponseCode = https.POST("Hello, World!");
102 |
103 | // If you need an HTTP request with a content type: application/json, use the following:
104 | //http.addHeader("Content-Type", "application/json");
105 | //int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
106 |
107 | if (httpResponseCode>0) {
108 | Serial.print("HTTP Response code: ");
109 | Serial.println(httpResponseCode);
110 | }
111 | else {
112 | Serial.print("Error code: ");
113 | Serial.println(httpResponseCode);
114 | }
115 | // Free resources
116 | https.end();
117 | }
118 | else {
119 | Serial.println("WiFi Disconnected");
120 | }
121 | //Send an HTTP POST request every 30 seconds
122 | delay(30000);
123 | }
124 |
--------------------------------------------------------------------------------