#include <LiquidCrystal.h>
#include <FixedPoints.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
const char DAYS_OF_WEEK[][4] {"Mon\0","Tue\0","Wed\0","Thu\0","Fri\0","Sat\0","Sun\0"};
//const char DIGITS[] {"0","1","2","3","4","5","6","7","8","9"};
const int PIN_CONTROLLER = A1;
const int PIN_THERMOMETER = A0;
const int PIN_HEATER = 7;
const int PIN_WAKE = 2; // NB: Sleep not working perhaps libruary cannot identify architecture
const int UNITS = 16;
const int DECIMALS = 8;
typedef SFixed<UNITS, DECIMALS> number;
constexpr number TEMP_CELCIUS_MIN = 5;
constexpr number TEMP_CELCIUS_MAX = 25;
constexpr long TEMP_RAW_MIN = 0;
constexpr long TEMP_RAW_MAX = 1015;
constexpr number TEMP_CELCUIS_GRADIENT = (TEMP_CELCIUS_MAX - TEMP_CELCIUS_MIN) / (TEMP_RAW_MAX - TEMP_RAW_MIN);
const number TEMP_DEAD_BAND = 1;
const long HEATER_CHANGE_PAUSE = 1000;
LiquidCrystal lcd(13, 12, 11, 6, 5, 4, 3);
number requiredTemperature;
number previousRequiredTemperature;
number measuredTemperature;
number previousMeasuredTemperature;
bool isHeaterOn;
long whenToChangeHeater;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.println(DAYS_OF_WEEK[3]);
lcd.setCursor(5,0);
lcd.print("Want");
lcd.setCursor(5,1);
lcd.print("Now ");
pinMode(PIN_CONTROLLER, INPUT);
pinMode(PIN_THERMOMETER, INPUT);
pinMode(PIN_HEATER, OUTPUT);
pinMode(PIN_WAKE, INPUT_PULLUP);
}
number convertTempFromRaw(long rawTemp) {
return TEMP_CELCIUS_MIN + (rawTemp - TEMP_RAW_MIN) * TEMP_CELCUIS_GRADIENT;
}
number getSelectedTemperature() {
return convertTempFromRaw(analogRead(PIN_CONTROLLER));
}
number getMeasuredTemperature() {
return convertTempFromRaw(analogRead(PIN_THERMOMETER));
}
void printTemperature(number temperature, int position) {
static char buffer[4];
lcd.setCursor(10, position);
lcd.print(" ");
lcd.setCursor(10 + ((temperature>=10)?0:1), position);
lcd.print(temperature.getInteger());
lcd.print(".");
itoa(temperature.getFraction(),buffer,10);
lcd.print(buffer[0]);
}
void loop() {
requiredTemperature = getSelectedTemperature();
if (requiredTemperature != previousRequiredTemperature) {
previousRequiredTemperature = requiredTemperature;
printTemperature(requiredTemperature,0);
}
measuredTemperature = getMeasuredTemperature();
if (measuredTemperature != previousMeasuredTemperature) {
previousMeasuredTemperature = measuredTemperature;
printTemperature(measuredTemperature,1);
}
if ((requiredTemperature + TEMP_DEAD_BAND) > measuredTemperature && !isHeaterOn) {
isHeaterOn = true;
whenToChangeHeater = millis() + HEATER_CHANGE_PAUSE;
}
if ((requiredTemperature - TEMP_DEAD_BAND) < measuredTemperature && isHeaterOn) {
isHeaterOn = false;
whenToChangeHeater = millis() + HEATER_CHANGE_PAUSE;
}
if (whenToChangeHeater != 0 && millis() > whenToChangeHeater)
{
digitalWrite(PIN_HEATER,isHeaterOn);
whenToChangeHeater = 0;
}
sleep();
}
void sleep() {// NB: Sleep not working perhaps libruary cannot identify architecture
attachInterrupt(digitalPinToInterrupt(PIN_WAKE), wakeUp, LOW);
sleep_enable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_cpu();
sleep_disable();
detachInterrupt(digitalPinToInterrupt(PIN_WAKE));
}
void wakeUp() {};