Baca data sensor dari ESP32, tampilkan chart real-time di Flutter menggunakan fl_chart.
ESP32 membaca sensor DHT11 dan LDR, lalu mengirim data JSON setiap detik.
C++ (Arduino)#include <ArduinoJson.h>
#include <DHT.h>
#define DHT_PIN 4
#define DHT_TYPE DHT11
#define LDR_PIN 34
#define LED_PIN 2
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// Baca sensor
float suhu = dht.readTemperature();
float kelembaban = dht.readHumidity();
int cahaya = analogRead(LDR_PIN);
// Buat JSON
JsonDocument doc;
doc["type"] = "sensor_data";
doc["suhu"] = isnan(suhu) ? 0.0 : suhu;
doc["kelembaban"] = isnan(kelembaban) ? 0.0 : kelembaban;
doc["cahaya"] = cahaya;
doc["led"] = digitalRead(LED_PIN) ? "ON" : "OFF";
doc["uptime"] = millis() / 1000;
serializeJson(doc, Serial);
Serial.println();
// Cek perintah masuk
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
JsonDocument cmd;
if (!deserializeJson(cmd, input)) {
const char* command = cmd["command"];
if (strcmp(command, "ON") == 0) digitalWrite(LED_PIN, HIGH);
if (strcmp(command, "OFF") == 0) digitalWrite(LED_PIN, LOW);
}
}
delay(1000);
}
Arsitektur: Sensor โ ESP32 โ USB โ Flutter Dashboard
Tambahkan fl_chart untuk visualisasi data sensor.
YAML โ pubspec.yamldependencies:
flutter:
sdk: flutter
usb_serial: ^0.5.1
fl_chart: ^0.68.0
Terminalflutter pub get
App Flutter yang menerima data sensor dan menampilkan gauge + line chart real-time.
Dart โ lib/main.dart (ringkasan)import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:usb_serial/usb_serial.dart';
import 'package:fl_chart/fl_chart.dart';
class SensorDashboard extends StatefulWidget {
const SensorDashboard({super.key});
@override
State<SensorDashboard> createState() => _SensorDashboardState();
}
class _SensorDashboardState extends State<SensorDashboard> {
UsbPort? _port;
double suhu = 0, kelembaban = 0;
int cahaya = 0;
List<FlSpot> suhuHistory = [];
int tick = 0;
@override
void initState() {
super.initState();
_connect();
}
Future<void> _connect() async {
var devices = await UsbSerial.listDevices();
if (devices.isEmpty) return;
_port = await devices[0].create();
await _port!.open();
await _port!.setPortParameters(
115200, UsbPort.DATABITS_8,
UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);
String buffer = '';
_port!.inputStream?.listen((Uint8List data) {
buffer += String.fromCharCodes(data);
while (buffer.contains('\n')) {
int idx = buffer.indexOf('\n');
String line = buffer.substring(0, idx).trim();
buffer = buffer.substring(idx + 1);
_processData(line);
}
});
}
void _processData(String line) {
try {
var json = jsonDecode(line);
setState(() {
suhu = (json['suhu'] ?? 0).toDouble();
kelembaban = (json['kelembaban'] ?? 0).toDouble();
cahaya = json['cahaya'] ?? 0;
suhuHistory.add(FlSpot(tick.toDouble(), suhu));
if (suhuHistory.length > 30) {
suhuHistory.removeAt(0);
}
tick++;
});
} catch (_) {}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Sensor Dashboard')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(children: [
// Sensor cards row
Row(children: [
_sensorCard('๐ก๏ธ Suhu', '${suhu.toStringAsFixed(1)}ยฐC',
Colors.orange),
const SizedBox(width: 12),
_sensorCard('๐ง Kelembaban', '${kelembaban.toStringAsFixed(1)}%',
Colors.blue),
const SizedBox(width: 12),
_sensorCard('โ๏ธ Cahaya', '$cahaya',
Colors.amber),
]),
const SizedBox(height: 24),
// Chart
Expanded(
child: LineChart(LineChartData(
lineBarsData: [
LineChartBarData(
spots: suhuHistory,
isCurved: true,
color: Colors.orange,
barWidth: 2,
dotData: const FlDotData(show: false),
),
],
)),
),
]),
),
);
}
Widget _sensorCard(String label, String value, Color color) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: color.withAlpha(25),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withAlpha(100)),
),
child: Column(children: [
Text(label, style: TextStyle(color: color, fontSize: 14)),
const SizedBox(height: 8),
Text(value, style: TextStyle(
color: color, fontSize: 24, fontWeight: FontWeight.bold)),
]),
),
);
}
}
Preview: Sensor Dashboard dengan card + line chart real-time