// simple thermostat
const char *Version = "Thermostat 260106a";
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#define ONE_WIRE_BUS_1 3
#define TEMPERATURE_PRECISION 11 // 0.125deg resolution
OneWire oneWire_range (ONE_WIRE_BUS_1);
DallasTemperature dallasRange (&oneWire_range);
LiquidCrystal_I2C lcd (0X27, 20, 4);
RTC_DS3231 rtc;
const byte PinButs [] = { 6, 7, 8, 9, 10 };
const int Nbut = sizeof(PinButs);
byte butState [Nbut];
enum { Bsel, Bup, Bdown, Bright, Benter };
// -------------------------------------
struct Room {
DallasTemperature *sensor;
int setPt;
const char *desc;
float tempC;
bool on;
}
rooms [] {
{ &dallasRange, 20, "range" }
} ;
Room *pR = & rooms [0];
// -------------------------------------
char s [90];
char t [20];
char u [20];
// -----------------------------------------------------------------------------
int
chkButtons ()
{
for (unsigned n = 0; n < Nbut; n++) {
byte but = digitalRead (PinButs [n]);
if (butState [n] != but) { // state change
butState [n] = but;
delay (30); // debounce
if (LOW == but) // pressed
return n;
}
}
return -1;
}
// -----------------------------------------------------------------------------
const char *DayOfWeek [] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char time [40];
void clock ()
{
DateTime now = rtc.now();
sprintf (time, " %10s %2d:%02d",
DayOfWeek [now.dayOfTheWeek ()], now.hour (), now.minute () );
}
// -----------------------------------------------------------------------------
void display ()
{
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print (time);
lcd.setCursor (0, 1);
dtostrf (pR->tempC, 5, 1, t);
sprintf (s, "%s%c %3dC %s", t, pR->on?'^':' ', pR->setPt, pR->desc);
lcd.print (s);
}
// -----------------------------------------------------------------------------
void heating (
Room *pR,
bool req )
{
if (req)
pR->sensor->requestTemperatures ();
pR->tempC = pR->sensor->getTempCByIndex (0);
pR->on = pR->tempC < pR->setPt;
pR->sensor->requestTemperatures (); // for next measurement
}
// -----------------------------------------------------------------------------
void menu ()
{
switch (chkButtons ()) {
case Bsel:
break;
case Bup:
pR->setPt++;
Serial.println (pR->setPt);
break;
case Bdown:
Serial.println (pR->setPt);
pR->setPt--;
break;
case Bright:
break;
case Benter:
break;
}
}
// -----------------------------------------------------------------------------
unsigned long msec0;
unsigned long msec1;
void loop ()
{
unsigned long msec = millis ();
menu ();
if (msec - msec0 >= 500) {
msec0 = msec;
clock ();
display ();
}
if (msec - msec1 >= 10000) {
msec1 = msec;
heating (pR, 0);
}
}
// -----------------------------------------------------------------------------
void setup ()
{
Serial.begin (9600);
lcd.init ();
lcd.print (Version);
rtc.begin();
dallasRange.begin();
dallasRange.setResolution(TEMPERATURE_PRECISION);
for (int n = 0; n < Nbut; n++) {
pinMode (PinButs [n], INPUT_PULLUP);
butState [n] = digitalRead (PinButs [n]);
}
heating (pR, 1);
}
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20
RESET
UP
AIRGUN
CLUB
RANGE
AIRGUN
RANGE
CLUB
SELECT
ENTER
RIGHT
DOWN
BOILER
DS3821
FITTED
HEARTBEAT
Uses the internal pullup resistors for the button inputs