#include <HX711.h>
#include <Wire.h>
#include <U8x8lib.h>
#define DT 2
#define SCK 3
#define TRIG 9
#define ECHO 10
U8X8_SSD1306_128X64_NONAME_HW_I2C display(U8X8_PIN_NONE);
HX711 scale;
// ===== TIMER REALTIME =====
unsigned long previousMillis = 0;
const long interval = 2000; // 2 detik
// ===== STRUCT =====
struct DataSiswa {
float berat;
float tinggi;
float bmi;
String statusGizi;
};
// ===== FIFO =====
DataSiswa antreanFIFO[10];
int head = 0;
int tail = 0;
int totalAntrean = 0;
// ====================
// BACA BERAT
// ====================
float bacaBerat() {
float berat = scale.get_units(10);
berat = berat / 420.0;
if (berat < 0) berat = 0;
return berat * 2.0;
}
// ====================
// BACA TINGGI
// ====================
float bacaTinggi() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long durasi = pulseIn(ECHO, HIGH);
float jarak = durasi * 0.034 / 2.0;
return jarak;
}
// ====================
// HITUNG STATUS BMI
// ====================
String hitungStatusGizi(float berat, float tinggi) {
if (tinggi <= 0) return "Error";
float t = tinggi / 100.0;
float bmi = berat / (t * t);
if (bmi < 18.5) return "Kurus";
if (bmi < 25) return "Gizi Baik";
return "Obesitas";
}
// ====================
// REALTIME PROCESS
// ====================
void prosesRealtime() {
float berat = bacaBerat();
float tinggi = bacaTinggi();
float bmi = 0;
if (tinggi > 0) {
float t = tinggi / 100.0;
bmi = berat / (t * t);
}
String status = hitungStatusGizi(berat, tinggi);
DataSiswa data;
data.berat = berat;
data.tinggi = tinggi;
data.bmi = bmi;
data.statusGizi = status;
// ===== MASUK FIFO =====
antreanFIFO[tail] = data;
tail = (tail + 1) % 10;
if (totalAntrean < 10) totalAntrean++;
// ===== KELUAR FIFO (REALTIME) =====
DataSiswa out = antreanFIFO[head];
head = (head + 1) % 10;
totalAntrean--;
// ===== SERIAL OUTPUT (RAPI) =====
Serial.println("============================");
Serial.println("===== HASIL PENGUKURAN =====");
Serial.print("Berat : ");
Serial.print(out.berat, 1);
Serial.println(" kg");
Serial.print("Tinggi : ");
Serial.print((int)out.tinggi);
Serial.println(" cm");
Serial.print("BMI : ");
Serial.println(out.bmi, 1);
Serial.print("Status : ");
Serial.println(out.statusGizi);
Serial.println("============================");
// ===== OLED (SUDAH DIPERBAIKI) =====
display.clearDisplay();
display.drawString(0,0,"REALTIME BMI");
display.drawString(0,2,("Berat : " + String(out.berat,1) + " kg").c_str());
display.drawString(0,3,("Tinggi : " + String((int)out.tinggi) + " cm").c_str());
display.drawString(0,4,("BMI : " + String(out.bmi,1)).c_str());
display.drawString(0,5,("Status : " + out.statusGizi).c_str());
}
// ====================
// SETUP
// ====================
void setup() {
Serial.begin(9600);
display.begin();
display.setFont(u8x8_font_chroma48medium8_r);
display.clearDisplay();
display.drawString(0,1,"SYSTEM ONLINE");
scale.begin(DT, SCK);
scale.set_scale();
scale.tare();
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
// ====================
// LOOP REALTIME
// ====================
void loop() {
if (millis() - previousMillis >= interval) {
previousMillis = millis();
prosesRealtime();
}
}