Hardwood Box Clock Arduino Sketch

Definitions and Variables

/*

   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

Functions

/*********************************************************************

                 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");

}

Setup and Loop

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);

}