├── README.md ├── code ├── ESP32_ESP8266_MySQL_Database_PHP.ino ├── HTTPS_ESP32_MySQL_Database_PHP.ino ├── HTTPS_ESP8266_MySQL_Database_PHP.ino ├── SensorData_Table.sql ├── esp-data.php └── post-esp-data.php └── project-image.jpg /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 | [![Project Image](https://raw.githubusercontent.com/RuiSantosdotme/ESP32-ESP8266-PHP-MySQL/master/project-image.jpg)](https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/) 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 36 | 37 | 38 | 39 | 40 | 41 | 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 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | '; 68 | } 69 | $result->free(); 70 | } 71 | 72 | $conn->close(); 73 | ?> 74 |
IDSensorLocationValue 1Value 2Value 3Timestamp
' . $row_id . '' . $row_sensor . '' . $row_location . '' . $row_value1 . '' . $row_value2 . '' . $row_value3 . '' . $row_reading_time . '
75 | 76 | 77 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /project-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuiSantosdotme/ESP32-ESP8266-PHP-MySQL/8ecbf8128b838f79af13a0f61b95a457fd6ee5b9/project-image.jpg --------------------------------------------------------------------------------