Created
September 18, 2024 04:33
-
-
Save heisvoid/2d4eb94310ffe09a2d063803c8bd6957 to your computer and use it in GitHub Desktop.
Arduino code for a nighttime electricity heater at home
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#define NO_MONITOR | |
#ifndef NO_MONITOR | |
#include <Wire.h> | |
#include <Adafruit_GFX.h> | |
#include <Adafruit_SSD1306.h> | |
#endif | |
#include <DS18B20.h> | |
#include <RTClib.h> | |
const int SETUP_TEMPERATURE = 45; | |
#ifndef NO_MONITOR | |
Adafruit_SSD1306 monitor(128, 64, &Wire, -1); | |
#endif | |
const int PIN_RELAY = 3; | |
const int PIN_THERMOMETER = 2; | |
DS18B20 thermometer(PIN_THERMOMETER); | |
RTC_DS3231 rtc; | |
void setup() { | |
Serial.begin(9600); | |
#ifndef NO_MONITOR | |
monitor.begin(SSD1306_SWITCHCAPVCC, 0x3c); | |
monitor.clearDisplay(); | |
monitor.setTextSize(1); | |
monitor.setTextColor(WHITE); | |
monitor.setCursor(0, 0); | |
#endif | |
bool r = rtc.begin(); | |
if (false == r) { | |
Serial.println(F("Couldn't find RTC")); | |
#ifndef NO_MONITOR | |
monitor.println(F("Couldn't find RTC")); | |
monitor.display(); | |
#endif | |
while (true) { | |
delay(1000); | |
} | |
} | |
r = rtc.lostPower(); | |
if (true == r) { | |
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); | |
Serial.println(F("RTC: adjust time")); | |
} | |
pinMode(PIN_RELAY, OUTPUT); | |
digitalWrite(PIN_RELAY, LOW); | |
} | |
void loop() { | |
DateTime now = rtc.now(); | |
const String datetime = now.timestamp(DateTime::TIMESTAMP_FULL); | |
Serial.println(datetime); | |
const float cur_temp = thermometer.getTempC(); | |
Serial.print(F("T: ")); | |
Serial.println(cur_temp); | |
const double voltage = get_voltage(); | |
Serial.print(F("V: ")); | |
Serial.println(voltage); | |
static uint32_t last_over_heated_secs = 0; | |
const uint32_t now_secs = now.secondstime(); | |
if (SETUP_TEMPERATURE <= cur_temp) { | |
last_over_heated_secs = now_secs; | |
} | |
static bool relay_on = false; | |
if ((SETUP_TEMPERATURE > cur_temp) && (180 < voltage)) { | |
const uint32_t s = now_secs - last_over_heated_secs; | |
const uint8_t h = now.hour(); | |
if ((144000 < s) || ((39600 < s) && (6 < h) && (9 > h))) { | |
if (false == relay_on) { | |
digitalWrite(PIN_RELAY, HIGH); | |
relay_on = true; | |
} | |
} | |
} else { | |
if (true == relay_on) { | |
digitalWrite(PIN_RELAY, LOW); | |
relay_on = false; | |
} | |
} | |
#ifndef NO_MONITOR | |
monitor.clearDisplay(); | |
monitor.setCursor(0, 0); | |
monitor.println(datetime); | |
monitor.print(F("T: ")); | |
monitor.print(cur_temp); | |
monitor.print(F(" ")); | |
monitor.println(SETUP_TEMPERATURE); | |
monitor.print(F("V: ")); | |
monitor.println(voltage); | |
if (true == relay_on) { | |
monitor.println(F("Relay ON")); | |
} else { | |
monitor.println(F("Relay OFF")); | |
} | |
monitor.display(); | |
#endif | |
delay(1000); | |
} | |
double get_voltage() { | |
const int VALUES_LEN = 20; | |
double values[VALUES_LEN]; | |
for (int i = 0; VALUES_LEN > i; i++) { | |
double val = analogRead(A0); | |
if (511 < val) { | |
values[i] = val; | |
} else { | |
values[i] = 0; | |
} | |
delay(1); | |
} | |
int max_v = 0; | |
for (int i = 0; VALUES_LEN > i; i++) { | |
if (max_v < values[i]) { | |
max_v = values[i]; | |
} | |
} | |
double eff_v = 0; | |
if (0 != max_v) { | |
eff_v = ((((max_v / sqrt(2)) - 420.76) / -90.24) * -210.2) + 210.2; | |
} else { | |
eff_v = 0; | |
} | |
return eff_v; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment