#include <Wire.h>
#include <Adafruit_ADS1X15.h>
#include <RTClib.h>
#include <DHT.h>
/* ---------- CONFIG ---------- */
const float BURDEN = 100.0;
const float CT_RATIO = 2000.0; // SCT-013-000: 100A / 50mA
const float MAINS_VOLTAGE = 240.0;
const int SAMPLES = 50;
const float DEMO_SCALE = 0.13; // keeps pot sweep in a believable single-circuit range
const float WASTE_THRESHOLD_W = 400.0;
#define PIR_PIN 27
#define LED_PIN 25
#define DHT_PIN 4
#define DHT_TYPE DHT22
Adafruit_ADS1115 ads;
RTC_DS1307 rtc;
DHT dht(DHT_PIN, DHT_TYPE);
struct Circuit { const char* name; int adsChannel; };
Circuit circuits[2] = {
{"LAB_A_AIRCON", 0},
{"LAB_A_LIGHTING", 1}
};
bool scheduledOccupied(DateTime now) {
int wd = now.dayOfTheWeek();
int h = now.hour();
bool weekday = (wd >= 1 && wd <= 5);
return weekday && h >= 8 && h < 17;
}
float readCircuitWatts(int channel) {
float sumSq = 0;
for (int i = 0; i < SAMPLES; i++) {
int16_t raw = ads.readADC_SingleEnded(channel);
float voltage = raw * 0.125 / 1000.0;
float acComponent = voltage - 1.65;
float current = (acComponent / BURDEN) * CT_RATIO * DEMO_SCALE;
sumSq += current * current;
delay(1);
}
float rmsI = sqrt(sumSq / SAMPLES);
return rmsI * MAINS_VOLTAGE;
}
void setup() {
Serial.begin(115200);
Wire.begin();
if (!ads.begin()) Serial.println("ADS1115 not found!");
ads.setGain(GAIN_ONE);
if (!rtc.begin()) Serial.println("RTC not found!");
if (!rtc.isrunning()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
dht.begin();
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
Serial.println("room_id,watts,scheduled_occ,motion,tempC,humidity,status,timestamp");
}
unsigned long lastDHT = 0;
float lastTemp = NAN, lastHum = NAN;
void loop() {
DateTime now = rtc.now();
bool occ = scheduledOccupied(now);
bool motion = digitalRead(PIR_PIN);
if (millis() - lastDHT > 2500) {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (!isnan(h)) lastHum = h;
if (!isnan(t)) lastTemp = t;
lastDHT = millis();
}
bool anyWaste = false;
char ts[20];
snprintf(ts, sizeof(ts), "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
for (int i = 0; i < 2; i++) {
float watts = readCircuitWatts(circuits[i].adsChannel);
bool wasted = watts > WASTE_THRESHOLD_W && !occ && !motion;
if (wasted) anyWaste = true;
const char* status = wasted ? "WASTE" : "OK";
Serial.print(circuits[i].name); Serial.print(",");
Serial.print(watts, 1); Serial.print(",");
Serial.print(occ ? 1 : 0); Serial.print(",");
Serial.print(motion ? 1 : 0); Serial.print(",");
Serial.print(lastTemp, 1); Serial.print(",");
Serial.print(lastHum, 1); Serial.print(",");
Serial.print(status); Serial.print(",");
Serial.println(ts);
}
digitalWrite(LED_PIN, anyWaste ? HIGH : LOW);
delay(3000);
}