// Beer Thermostat #define STATUS_OFF 0 #define STATUS_ON 1 #define TOGGLE_NOCHANGE 0 #define TOGGLE_ON 1 #define TOGGLE_OFF 2 #define TOGGLE_MALFUNCTION 3 #define WAIT 1000 struct Thermistor { int base; // *100, see below int diff; // *10 because of floats (10.2, for example->102) int pin; }; struct Controller { int relayPin; int thermInvert; // 0 = power on cools, 1 = power on heats int lastRead; int low; int high; int status; // 0=off;1=on int toggle; // 0=nochange; 1=turnedon; 2=turnedoff; 3=malfunction int timer; // seconds since last status change struct Thermistor Therm; // Thermistor }; Controller Freezer; Controller Fermenter; Thermistor ThermA; Thermistor ThermB; void setup() { // Thermistor Calibration ThermA.base = 22500; // re-calibrate me! ThermA.diff = 102; ThermA.pin = 0; ThermB.base = 22500; ThermB.diff = 102; ThermB.pin = 1; // Freezer Setup Freezer.relayPin = 12; Freezer.low = 40; // (10 * ºC) Freezer.high = 60; // (10 * ºC) Freezer.thermInvert = 0; Freezer.status = STATUS_OFF; Freezer.toggle = TOGGLE_NOCHANGE; Freezer.timer = 0; Freezer.Therm = ThermB; // Fermenter Setup Fermenter.relayPin = 11; Fermenter.low = 170; // (10 * ºC) Fermenter.high = 180; // (10 * ºC) Fermenter.thermInvert = 1; Fermenter.status = STATUS_OFF; Fermenter.toggle = TOGGLE_NOCHANGE; Fermenter.timer = 0; Fermenter.Therm = ThermA; Serial.begin(9600); pinMode(Freezer.relayPin, OUTPUT); pinMode(Fermenter.relayPin, OUTPUT); } void loop() { checkTemp(Freezer); toggle(Freezer); Freezer.timer++; doOutput("KEG", Freezer); delay(WAIT); checkTemp(Fermenter); toggle(Fermenter); Fermenter.timer++; doOutput("FER", Fermenter); delay(WAIT); } void checkTemp(struct Controller &c) { int span = 20; int aRead = 0; for (int i = 0; i < span; i++) { aRead = aRead + analogRead(c.Therm.pin); } aRead = aRead / span; c.lastRead = (((1024 - aRead) * 100) - c.Therm.base) / c.Therm.diff; // ºC } void toggle(struct Controller &c) { c.toggle = TOGGLE_NOCHANGE; if (c.lastRead > c.high && c.status != STATUS_ON) { // getting too hot tooHot(c); } else if (c.lastRead < c.low && c.status != STATUS_OFF) { // getting too cold tooCold(c); } } void tooCold(struct Controller &c) { if (c.thermInvert) { digitalWrite(c.relayPin, HIGH); c.status = STATUS_ON; c.toggle = TOGGLE_ON; } else { digitalWrite(c.relayPin, LOW); c.status = STATUS_OFF; c.toggle = TOGGLE_OFF; } c.timer = 0; } void tooHot(struct Controller &c) { if (c.thermInvert) { digitalWrite(c.relayPin, LOW); c.status = STATUS_OFF; c.toggle = TOGGLE_OFF; } else { digitalWrite(c.relayPin, HIGH); c.status = STATUS_ON; c.toggle = TOGGLE_ON; } c.timer = 0; } void doOutput(char name[4], struct Controller &c) { Serial.print(name); Serial.print(" "); Serial.print(c.lastRead); Serial.print(" "); Serial.print(c.status); Serial.print(" "); Serial.print(c.toggle); Serial.print(" "); Serial.println(c.timer); }