/*
WSDuino Program for the clock in the Applachian Hardwood box.
Program as a "Arduino Decemilinova or Decimilaa". Processor Atmega328P
Press the yellow reset button until uploading just starts
Use Interactive from ds3231FS library to set the ime & date
The display is NHD-0216K1Z-NSW-FBW-L, wired for 4-bit parallel
The controller is ST7066.
There is a contrast preset trimmer center back, CCW is brighter
There is a 3-way slide switch nearby. Center is PST.up is +1 hour, down is +2 hours
*/
#include <ds3231.h> // High accuracy real-time clock (+/- 5ppm ageing,+/1 2 ppm temperature),
#include <Wire.h> // DS3231 is built-in the Arduimo-compatible board, connected by I2C
#include <LiquidCrystal.h> // Comes with the Arduino IDC, mostly comptible with the ST7066 controller.
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const float Vcc = 5.119; // Measured
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
ts t; //ts is a struct findable in ds3231.h
/*********************************************************************
Display functions
**********************************************************************
*/
const char weekdays[22] = {"MONTUEWEDTHUFRISATSUN"}; // 1(MON) through 7(SUN)
void displayWeekday(void) {
char c;
byte indx;
for (byte i = 0; i < 3; i++) {
indx = (3 * (t.wday - 1)) + i;
c = weekdays[indx];
lcd.print(c);
}
}
const char months[40] = {"DECJANFEBMARAPRMAYJUNJLYAUGSEPOCTNOVDEC"}; // 1 - 12
void displayMonth(void) {
char c;
byte indx;
for (byte i = 0; i < 3; i++) {
indx = (3 * t.mon) + i;
c = months[indx];
lcd.print(c);
}
}
/*
*********************************************************************
Temperature, Rattery Voltage
**********************************************************************
*/
void displayTemperature(void) {
float rtcTemp = DS3231_get_treg();
float f = rtcTemp * 9. / 5. + 32.;
lcd.print(f, 0);
lcd.print("F");
}
void displayBatteryVolts(void) {
int AnalogRead;
float BattV;
AnalogRead = analogRead(A1);
BattV = AnalogRead * Vcc / 1024;
lcd.print(BattV, 2);
lcd.print("V");
}
byte currSec;
void setup() {
Wire.begin(); //start i2c (required for connection to the clock chip)
DS3231_init(DS3231_INTCN); //register the ds3231 (DS3231_INTCN is the default address of ds3231, this is set by macro for no performance loss)
lcd.begin(16, 2);
pinMode(10, INPUT_PULLUP); // Time Zone switch
pinMode(13, INPUT_PULLUP); // Time Zone switch
//if (t.mon < 10) {
// t = {0, 17, 8, 3, 22, 1};
// DS3231_set(t);
// DS3231_set_addr(2,8);
// }
}
void loop() {
DS3231_get(&t); //get the value and pass to the function the pointer to t, that make an lower memory fingerprint and faster execution than use return
// DS3231_get() will use the pointer of t to directly change t value (faster, lower memory used)
lcd.clear();
int DST = t.hour + 3 - digitalRead(10) - 2 * digitalRead(13); // Hack for DST and mountain time using a slide switch
DST %= 24; // Keeps hour in 10-23 range. day may change late
lcd.print(DST);
if ((t.sec & 0x01) == 0 ) { // No space for second display, but colon flashes
lcd.print(":");
}
else {
lcd.print(" ");
}
lcd.print(t.min);
lcd.setCursor(6, 0);
displayWeekday();
lcd.print(" ");
displayMonth();
lcd.print(" ");
lcd.print(t.mday);
lcd.setCursor(0, 1);
lcd.print("2");
lcd.print("0");
lcd.print(t.year_s);
lcd.setCursor(5, 1);
displayTemperature();
lcd.setCursor(10, 1);
displayBatteryVolts();
delay(1000);
}