CREATE TABLE sensor_data ( id INT(11) AUTO_INCREMENT PRIMARY KEY, sensor_id INT(11) NOT NULL, flow_rate FLOAT NOT NULL, volume FLOAT NOT NULL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ------------------------------------------------- ### 2. PHP Script - `insert_data.php` ```php connect_error) { die("Connection failed: " . $conn->connect_error); } // --- Get JSON data from POST request --- $json = file_get_contents('php://input'); $data = json_decode($json, true); // --- Prepare and execute SQL statements --- if (is_array($data)) { foreach ($data as $sensor => $sensorData) { $sensorNum = intval(substr($sensor, 6)); // Extract sensor number from key (e.g., "sensor1") $rate = $sensorData['rate']; $volume = $sensorData['volume']; $sql = "INSERT INTO sensor_data (sensor_id, flow_rate, volume) VALUES ($sensorNum, $rate, $volume)"; if ($conn->query($sql) === TRUE) { echo "New record created successfully for sensor $sensorNum\n"; } else { echo "Error: " . $sql . "
" . $conn->error; } } } else { echo "Invalid JSON data received"; } $conn->close(); ?> -------------------------------------------------------- To get flow rate and volume from five YF-S201 sensors on an ESP32 and send it via ArduinoJson to a PHP/MySQL backend for a Flutter app, you need ESP32 Code (C++) using interrupts (IRAM_ATTR), PHP Scripts, a MySQL Database, and Flutter code to display data, focusing on Wi-Fi connectivity, JSON serialization, HTTP POST requests, and SQL INSERT commands for data logging. The core involves ESP32 reading pulses, calculating flow (L/min) and volume (L), packaging data as JSON, sending to PHP, PHP inserting into MySQL, then Flutter fetching from PHP/MySQL. } } // Prepare JSON data DynamicJsonDocument doc(1024); // Adjust size as needed for (int i = 0; i < numSensors; i++) { char sensorKey; sprintf(sensorKey, "sensor%d", i + 1); JsonObject sensorData = doc.createNestedObject(sensorKey); sensorData["rate"] = currentFlowRate[i]; sensorData["volume"] = totalVolume[i]; } String jsonString; serializeJson(doc, jsonString); // Send data to PHP script if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverUrl); http.addHeader("Content-Type", "application/json"); int httpResponseCode = http.POST(jsonString); if (httpResponseCode > 0) { Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println(payload); } else { Serial.print("Error sending data: "); Serial.println(httpResponseCode); } http.end(); } else { Serial.println("WiFi Disconnected"); } lastMillis = millis(); } delay(10); // Short delay to prevent watchdog timer issues } ------------------------------- // --- Example Flutter Code Snippets --- import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; class SensorData { final int sensorId; final double flowRate; final double volume; SensorData({required this.sensorId, required this.flowRate, required this.volume}); factory SensorData.fromJson(Map json, int sensorId) { return SensorData( sensorId: sensorId, flowRate: json['rate'] as double, volume: json['volume'] as double, ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { List sensorDataList = []; bool isLoading = true; @override void initState() { super.initState(); fetchSensorData(); } Future fetchSensorData() async { setState(() { isLoading = true; }); try { final response = await http.get(Uri.parse('http://YOUR_SERVER_IP/api/get_data.php')); // Replace with your PHP script URL if (response.statusCode == 200) { final Map jsonResponse = jsonDecode(response.body); List fetchedData = []; jsonResponse.forEach((key, value) { int sensorId = int.parse(key.replaceAll('sensor', '')); fetchedData.add(SensorData.fromJson(value, sensorId)); }); setState(() { sensorDataList = fetchedData; isLoading = false; }); } else { print('Failed to load data. Status code: ${response.statusCode}'); setState(() { isLoading = false; }); } } catch (e) { print('Error fetching data: $e'); setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Sensor Data'), ), body: isLoading ? Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: sensorDataList.length, itemBuilder: (context, index) { final sensorData = sensorDataList[index]; return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Sensor ID: ${sensorData.sensorId}'), Text('Flow Rate: ${sensorData.flowRate.toStringAsFixed(2)} L/min'), Text('Volume: ${sensorData.volume.toStringAsFixed(2)} L'), ], ), ), ); }, ), floatingActionButton: FloatingActionButton( onPressed: fetchSensorData, tooltip: 'Refresh Data', child: Icon(Icons.refresh), ), ); } } ----------------------------------- connect_error) { die("Connection failed: " . $conn->connect_error); } // --- Fetch the latest data for each sensor --- $sql = "SELECT sensor_id, flow_rate, volume FROM sensor_data GROUP BY sensor_id ORDER BY timestamp DESC"; $result = $conn->query($sql); $sensorData = array(); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { $sensorId = "sensor" . $row["sensor_id"]; $sensorData[$sensorId] = array( "rate" => floatval($row["flow_rate"]), "volume" => floatval($row["volume"]) ); } } header('Content-Type: application/json'); echo json_encode($sensorData); $conn->close(); ?>