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();
?>