Hardware components | ||||||
| × | 1 |
FINALLY, the schematic is available.
Why this clock?
I always wanted to make a so-called 'Gorgy' Clock. You see them often in music or TV studios. Now I could, so I bought a cheap clock at Ikea and ripped out the inside, making room for the electronics and display.
A commercial Gorgy clock and the Ikea clock I bought:
Because it was to be my bedside clock, I thought of adding some extra features such as an IR remote and barometer- humidity and temperature sensor because I love meteorology.
When I'm awake at night, I have something to look at: temperature (min/max), barometer trend of the last 24 hours and the air pressure change rate, which is a very good indication of pending bad weather.
WishlistAlarm clock function
I also would like to use the clock as an alarm clock with a blackbird sound to wake me up using an Adafruit sound card. But my lack of programming skills concerning the necessary menu structure was a stumbling block (so far).
Adjusting the time
Adjusting the time is sort of possible via the menu:
It is poorly implemented (for now), so what I did is assigned a button on the IR remote to set the seconds to zero when I press that button. If the seconds on the clock are <30, the minute stays the same and the seconds are reset to 0. When the seconds on the clock are >30, one minute is added and the seconds are reset to zero.
So with a accurate clock (on my phone), just before the '0' mark I press the button and the clock is synced. Then I'm good for a whole year because the temp compensated RTC is extremely accurate.
Videoclick HERE
Building the clockI just discovered the possibility to use a laser cutter at a local makerspace location: GREAT! So this way I could make the black acrylic mounting frame for the LED's and TFT display:
On top of that I also cut a piece of heavy weight black paper to cover the gaps around the TFT display. Then I cut a brown acrylic display to enhance the contrast of the LED's and make the gray 7 segment displays less noticeable.
The TFT displayOn the small 1.8" TFT display, I now have 5 display options:
As a gimmick, I included a 'thermal comfort indicator' in the form of a traffic light.
The Meteo sensorsWhen I'm awake at night and a storm is passing I can see the barometric pressure plunging and rising after the storm has passed. Better than looking at the ceiling.
Inside the clockCode version 2017-03
ArduinoIt should compile with Arduino IDE 1.6 up to 1.6.9, maybe not the newer versions of the IDE!!
PLEASE note: the needed LIBRARIES are found as a ZIP file under "CUSTOM PARTS AND ENCLOSURES"
/*
GorgyMeteoClock
2017-07-13 changing date display to also display day-of-the-week
2017-07-14 small edit: clear date display first and no decimal point
#### ###### ### ####
## ## ##### ###### ## ## #### ## ## ####### #### ## ## ## ## ## ## ##
## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ### ## ## ### ### ## ## #### ## ##### ##### ## ##
## ## ##### ## ## # ## ## ## # ## ##### ## ## # ## ## ## ## ## ##
## ## ## ## ## # ## ## ### ## # ## ## ## ### ###### ## ## ## ## ## ##
## ## ## ## ## ## ### ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ##
##### ##### ###### ## ## ##### ## ## ####### ##### ### ## ###### #### #### ####
*/
//----------------------------------------------------------------------------------------------------------
// Libraries
//----------------------------------------------------------------------------------------------------------
//
#include <SPI.h> // SPI interface library
// -> http://arduino.cc/en/Reference/SPI
#include <Time.h> // Arduino (new) Time library
// -> http://www.pjrc.com/teensy/td_libs_Time.html
#include <Timezone.h> // facilitate time zone conversions and automatic DST adjustments.
//https://github.com/JChristensen/Timezone
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
//
#include <LedControl.h> // Maxim 7219 displays library
// -> http://playground.arduino.cc/Main/LEDMatrix
#include <OneWire.h> // OneWire lets you access 1-wire devices made by Maxim/Dallas,
// such as DS18S20, DS18B20, DS1822.
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// http://milesburton.com/Dallas_Temperature_Control_Library
#include <IRremote.h> //
#include "ClickButton.h" // A simple one-button Arduino library to get short and long clicks,
// multiple clicks (double click, triple click etc.).
// Click-and-hold is also possible.
// -> https://code.google.com/p/clickbutton/
#include <Adafruit_GFX_AS.h> // Adafruit Core graphics library
#include <Adafruit_ST7735_AS.h> // Adafruit 1.8" TFT
#include "Adafruit_HTU21DF.h" // Adafruit HTU21D-F Temperature & Humidity Sensor
#include <Streaming.h>
#include <Adafruit_Sensor.h> // Adafruit Unified Sensor Driver
#include <Adafruit_BMP183.h> // Adafruit BMP183 Barometric Pressure + Temp sensor
#include "eeprom_routines.h" // EEprom routines for storing data
//#include "RotaryEncoder.h" // smallest and best rotary lib I have seen...
// https://code.google.com/p/arduino-rotary-encoder-with-velocity/
//----------------------------------------------------------------------------------------------------------
// I2C addresses
//----------------------------------------------------------------------------------------------------------
#define CHRONODOT_ADDRESS 0x68 // Chronodot I2C address
#define BH1750_ADDRESS 0x23 // BH1750 Lux Sensor I2C address
#define TSL2561_ADDRESS 0x39 // Lux Sensor I2C address
#define HTU21DF_ADDRESS 0x40 // Humidity Sensor I2C address
#define EEPROM_ADDRESS 0x50 // EEprom address for storing barametric array data etc.
//----------------------------------------------------------------------------------------------------------
// Humidity Sensor init
//----------------------------------------------------------------------------------------------------------
Adafruit_HTU21DF htu21df = Adafruit_HTU21DF();
//----------------------------------------------------------------------------------------------------------
// Barometric pressure sensor init
//----------------------------------------------------------------------------------------------------------
#define BMP183_CLK 52 // SCK to SPI Clock
#define BMP183_SDO 50 // MISO
#define BMP183_SDI 51 // MOSI
#define BMP183_CS 42 // CS: Chip Select Pin
// initialize BMP183 sensor with hardware SPI
Adafruit_BMP183 bmp183 = Adafruit_BMP183(BMP183_CS);
// or initialize with software SPI and use any 4 pins
// CLK SDO SDI CS);
//Adafruit_BMP183 bmp = Adafruit_BMP183( 3, 6, 2, 7);
//----------------------------------------------------------------------------------------------------------
// DS18B20 initialization
//----------------------------------------------------------------------------------------------------------
OneWire ds(46); // define Onewire instance DS
// address: 0x28, 0xF0, 0xEC, 0xE2, 0x04, 0x00, 0x00, 0x47
//----------------------------------------------------------------------------------------------------------
// IRreceiver initialization
//----------------------------------------------------------------------------------------------------------
IRrecv irrecv(44);
decode_results irReceive;
//----------------------------------------------------------------------------------------------------------
// Adafruit 1.8" TFT display init
//----------------------------------------------------------------------------------------------------------
//Connect to hardware SPI on Mega2560:
#define sclk 52 // Uno:13 // Don't change
#define mosi 51 // Uno:11 // Don't change
#define cs 48 // Uno:9
#define dc 49 // Uno:8
#define rst 47 // Uno:7 // you can also connect this to the Arduino reset
Adafruit_ST7735_AS tft = Adafruit_ST7735_AS(cs, dc, rst); // Invoke custom library
// or use any pins but a little slower
// cs dc mosi sclk, rst);
//Adafruit_ST7735 tft = Adafruit_ST7735(10, 9, 11, 13, 8);
// define colors for TFTdisplay
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define ORANGE 0xFD20
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define LGRAY 0xC618
#define DGRAY 0x8410
//----------------------------------------------------------------------------------------------------------
// Maxim 7219 Matrix Display initialization
//----------------------------------------------------------------------------------------------------------
//***** Please set the number of devices you have *****
// But the maximum default of 8 MAX72XX wil also work.
// LedConrol( DATAIN(SDI/MOSI), CLOCK, CS/LOAD , NUMBER OF MAXIM CHIPS,)
LedControl maxim = LedControl(40, 36, 38, 3, false); // Define pins for Maxim 72xx and how many 72xx we use
//LedControl maxim = LedControl(40, 39, 38, 3, false); // Define pins for Maxim 72xx and how many 72xx we use
//LedControl maxim = LedControl(11, 13, 6, 1, false); // Define pins for Maxim 72xx and how many 72xx we use
//----------------------------------------------------------------------------------------------------------
// Rotary encoder
//----------------------------------------------------------------------------------------------------------
//RotaryEncoder encoder(A0,A1,1,1,1);
//#define BUTTON_SELECT_PIN A2
//----------------------------------------------------------------------------------------------------------
// Miscellaneous
//----------------------------------------------------------------------------------------------------------
// Adafruit TFT screen things
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
//----------------------------------------------------------------------------------------------------------
// Daylight Savings Time calculation parameters
//----------------------------------------------------------------------------------------------------------
//Europe, Amsterdam Time Zone (ZT = DST, WT = DST)
TimeChangeRule myZT = {"ZT", Last, Sun, Mar, 2, +120}; //Daylight time = UTC +2 hours
TimeChangeRule myWT = {"WT", Last, Sun, Oct, 3, +60}; //Standard time = UTC +1 hours
Timezone myTZ(myZT, myWT);
//----------------------------------------------------------------------------------------------------------
// RTC DS3231 stuff
//----------------------------------------------------------------------------------------------------------
// set SQW output DS3231 RTC chip
#define SQW_FREQ SQWAVE_1_HZ // 0b00000000 1Hz
//#define SQW_FREQ SQWAVE_4096_HZ // 0b00001000 1024Hz
//#define SQW_FREQ SQWAVE_1024_HZ // 0b00010000 4096Hz
//#define SQW_FREQ SQWAVE_8192_HZ // 0b00010000 4096Hz
//#define SQW_FREQ SQWAVE_NONE // DISABLE
//----------------------------------------------------------------------------------------------------------
// EEPROM
//----------------------------------------------------------------------------------------------------------
// memory start address to for barometer array data
#define BAROGRAPH_START_ADDRESS 100
//----------------------------------------------------------------------------------------------------------
// Variable and array defenitions
//----------------------------------------------------------------------------------------------------------
// define Maxim 7219 display parameters
#define TIMEDISPLAY 1 // first Maxim 7219 in 'daisychain' must be '0', next '1' etc.
#define SECONDSDISPLAY 2 // first Maxim 7219 in 'daisychain' must be '0', next '1' etc.
#define DATEDISPLAY 0
//----------------------------------------------------------------------------------------------------------
// LED pins
//----------------------------------------------------------------------------------------------------------
#define ERRORLED 36
//----------------------------------------------------------------------------------------------------------
// PWM brightness ports
//----------------------------------------------------------------------------------------------------------
#define MARKERS_HOURS 10 // PWM
#define MARKERS_MINUTES 11 // PWM
#define TFT_LIGHT 12 // Lite - this is the PWM input for the backlight control. Connect to 3-5VDC to turn on the
// backlight. Connect to ground to turn it off. Or, you can PWM at any frequency.
//----------------------------------------------------------------------------------------------------------
// Buttons definition
//----------------------------------------------------------------------------------------------------------
// create 3 Clickbutton instances, one for each button
#define BUTTON_SELECT_PIN A0
#define BUTTON_UP_PIN A1
#define BUTTON_DOWN_PIN A2
ClickButton buttonUp(BUTTON_UP_PIN, LOW, CLICKBTN_PULLUP);
ClickButton buttonDown(BUTTON_DOWN_PIN, LOW, CLICKBTN_PULLUP);
ClickButton buttonSelect(BUTTON_SELECT_PIN, LOW, CLICKBTN_PULLUP);
//// user input actions
//enum {NO_ACTION, BTN_CLICK, BTN_DOUBLE_CLICK, BTN_HOLD, ROTATE_L, ROTATE_R}; // used for rotary
enum {NO_ACTION, BTN_SELECT, BTN_SELECT_HOLD, BTN_UP, BTN_DOWN, LED_RING_MODE, MEMORY_RESET, EEPROM_WRITE_BARO, EEPROM_READ_BARO};
//----------------------------------------------------------------------------------------------------------
// Related to the State Machine
//----------------------------------------------------------------------------------------------------------
// The different states of the system
enum states
{
STATE_MAIN,
STATE_TEMP_DISPLAY,
STATE_HUMIDITY_DISPLAY,
STATE_TIME_DETAIL,
STATE_BAROGRAPH,
STATE_BAROGRAPH_TREND,
STATE_MENU_ALARM_TIME,
STATE_MENU_SET_ALARM_HOUR,
STATE_MENU_SET_ALARM_MINUTES,
STATE_MENU_SECONDS_RING,
STATE_MENU_SET_SECONDS_RING_MODE,
STATE_MENU_LCD_MODE,
STATE_MENU_SET_LCD_MODE,
STATE_MENU_TIME,
STATE_MENU_SET_TIME_HOUR,
STATE_MENU_SET_TIME_MINUTES,
STATE_MENU_DATE,
STATE_MENU_SET_DAY,
STATE_MENU_SET_MONTH,
STATE_MENU_SET_YEAR,
STATE_MENU_BAROGRAPH,
STATE_MENU_SET_SEA_LEVEL_PRESSURE,
STATE_MENU_SET_PRESSURE_CORRECTION,
};
states currState; // Holds the current state of the system
/***************************************************************************************************************************************************
## ## ## ###### ###### ## ###### ## ####### #####
## ## ## ## ## ## ## ## ## ## ## ## ##
## ## #### ## ## ## #### ## ## ## ## ##
## ## ## # ###### ## ## # ###### ## ##### #####
## ## ###### ## ## ## ###### ## ## ## ## ##
### ## # ## ## ## ## # ## ## ## ## ## ##
### ### ## ## ## ###### ### ## ###### ###### ####### #####
****************************************************************************************************************************************************/
#define plotLimitH 130 // graph plotlimit Horizontal
#define plotRangeH 130 // graph plot size Horizontal
#define plotLimitV 115 // graph plotlimit Vertical
#define plotRangeV 100 // graph plot size Vertical
// Horizontal Grid lines
#define grid24HstartpositionXaxis 0
#define grid24HstartpositionYaxis 15
#define grid24HlineSpacing 20
#define grid24HlinePixelSpacing 2
#define grid24HlinePixelSpacing1H 5
#define grid24HlinePixelSpacing2H 10
#define grid24HlinePixelSpacing4H 20
#define grid24XaxisTicksStart 5
// Vertical Grid lines
#define grid24VstartpositionXaxis 10
#define grid24VstartpositionYaxis 15
#define grid24VlineSpacing 20
#define grid24VlinePixelSpacing 2
#define grid24VlinePixelSpacing10Hpa 20
#define grid24VlinePixelSpacing5Hpa 10
#define GRIDCOLOR LGRAY
#define PLOTCOLOR BLUE
#define XAXISCOLOR WHITE
#define YAXISCOLOR WHITE
#define XTEXTCOLOR WHITE
#define YTEXTCOLOR WHITE
#define PRESSUREVALUECOLOR GREEN
#define TEMPVALUECOLOR MAGENTA
#define HYGROVALUECOLOR ORANGE
char* strDOW[8] = {"null", "Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag"};
int strDOWlength[8] = {0, 6, 7, 7, 8, 9, 7, 8};
char* strMonth[13] = {"null", "Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"};
//char* strMonth[13] = {"null","Januari","Februari","Maart","April","Mei","Juni","Juli","Augustus","September","Oktober","November","December"};
byte readWeatherdataInterval = 12;
bool secondsRingUpdated = false;
bool tftMainUpdated = false;
bool tftTimeUpdated = false;
bool tftBarographUpdated = false;
bool tftBaroTrendUpdated = false;
int baroTrendValue = 0;
int baroTrend = 0;
enum {NA, ZEER_SNEL_DALEND, SNEL_DALEND, DALEND, LANGZAAM_DALEND, STABIEL, LANGZAAM_STIJGEND, STIJGEND, SNEL_STIJGEND, ZEER_SNEL_STIJGEND};
bool pressureDataUpdated = false;
bool pressureDataStored = false;
bool pressureDataToEEprom = false;
bool pressureDataFromEEprom = false;
long pressureSample = 0;
long pressure = 0;
long pressureMin = 0;
long pressureMax = 0;
int minPressureHour = 0;
int minPressureMinute = 0;
int maxPressureHour = 0;
int maxPressureMinute = 0;
int testpressure = 980;
int step = 5;
int previousPressureMin = 0;
int previousPressureMax = 0;
int meanSeaLevelPressure = 10155;
int pressureCorrection = 2;
bool resetBarograph = false;
int countdown = 10800;
int x = 0;
int plotvalueP = 0;
int plotvalueP1 = 0;
int plotvalueT = 0;
bool highScale = false;
bool currentScale = false;
int barometerData[132]; // array to hold barometric data
unsigned int readings = 0;
int pressureHourAvarage[130];
int pressureHourlyTrend = 0;
unsigned long timer1 = millis();
unsigned long lastRotation = millis();
unsigned long lastUpdate1 = millis();
bool startup = true;
int q;
// Humidity related variables
int humidity = 0;
int climateComfort = 0;
int minHumidity = 0;
int maxHumidity = 0;
int minHumidityHour = 0;
int minHumidityMinute = 0;
int maxHumidityHour = 0;
int maxHumidityMinute = 0;
bool humidityMemoryReset = false;
#define ccRED 0
#define ccYELLOW 1
#define ccGREEN 2
// temperature variables
bool temperatureMemoryReset = true;
int tempCelcius = 0;
int minTemp = 0;
int maxTemp = 0;
int minTempHour = 0;
int minTempMinute = 0;
int maxTempHour = 0;
int maxTempMinute = 0;
//@1
byte tCount;
byte present = 0;
byte data[12];
byte addr[8] = {0x28, 0xF0, 0xEC, 0xE2, 0x04, 0x00, 0x00, 0x47};
// Time related variables
bool setSecondsToZero = false;
int previousDay = 0;
int lastMinute = 0;
time_t t;
byte previousSecond = 0;
byte previousMinute = 0;
byte previousHour = 0;
int TMPsecond; // holds time & date while setting the time
int TMPminute;
int TMPhour;
int TMPweekday;
int TMPday;
int TMPmonth;
int TMPyear;
int daylightSavingTime = 0;
bool daylightSavingTimeHasChanged = false;
boolean RTCERROR = true; // flag to check RTC communication, used in SHOW_TIME_DATE_WEATHER_DATE_WEATHER and SHOW_DATE
short dayNumber; //Returns the number of day in the year
short weekNumber; //Returns the number of the week in the year
byte alarmHour = 8;
byte alarmMinute = 30;
bool sw1 = true;
bool stateChange = false;
int userAction = 0;
int previousMenu = 0;
volatile unsigned long timeOfLastButtonPress = 0;
bool secondsRingFull = true;
bool lcdScrollModeAuto = false;
bool needToSaveTime = false;
bool needToUpdateBarograph = false;
bool needToUpdateTFT = false;
bool isWaitingforTimeout = false;
//Brightness
byte brightnessTimeDisplay = 1; // value from 0-15
byte brightnessSecondsRing = 0; // value from 0-15
byte brightnessDateDisplay = 3; // value from 0-15
byte brightnessMinuteMarkers = 505; // USE PWM value from 0 - 512, higher is dimmer
byte brightnessHourMarkers = 512; // USE PWM value from 0 - 512
byte brightnessLcdBacklight = 420; // USE PWM value from 0 - 512
bool irRemote = false;
byte ledRingMode = 0;
bool ledRingModeIsChanged = false;
int sec = 0;
// Define Interrupt function
volatile boolean updateTime = false;
// DS3231 1Hz pulse ISR
void pulseISR()
{
updateTime = true;
}
/***************************************************************************************************************************************************
## ##
##### ####### ###### ## ## ###### ## ##
## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ##
##### ##### ## ## ## ###### ## ##
## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ##
##### ####### ## ##### ## ## ##
## ##
****************************************************************************************************************************************************/
void setup()
{
//DEBUG
pinMode(A8, OUTPUT);
pinMode(A9, OUTPUT);
pinMode(A10, OUTPUT);
pinMode(A11, OUTPUT);
//END DEBUG ;)
pinMode(ERRORLED, OUTPUT);
pinMode(TFT_LIGHT, OUTPUT);
pinMode(MARKERS_HOURS, OUTPUT);
pinMode(MARKERS_MINUTES, OUTPUT);
pinMode(53, OUTPUT); // Set to OUTPUT NEEDED FOR SPI HARDWARE MASTER MODE
Wire.begin(); // start I2C
irrecv.enableIRIn(); // Start the IR remote receiver
Serial.begin(115200); // start Serial for debug purposes
//RTC.squareWave(SQW_FREQ); // Set RTC DS3231 SQW frequency (1 Hz in this case)
attachInterrupt(0, pulseISR, RISING); // DS3231 sends an 1Hz pulse - we use this to update the display
readRTC();
setTime(TMPhour, TMPminute, TMPsecond, TMPday, TMPmonth, TMPyear);
//setTime(2, 59, 45, 25, 10, 15); // test for change to winter time
//setTime(1, 59, 45, 29, 3, 15); // test for change to summer time
//timeDateToTemporaryMem();
//writeRTC();
// store current DST value in variable to check if DST is changed
daylightSavingTime = myTZ.locIsDST(now());
//setTime(RTC.get());
//setSyncProvider(RTC.get); // set RTC as the Syncprovider
//setSyncInterval(5); // time in sec of resync with RTC
// clear barometer pressure data array
for (int i = 0; i <= 130; i++)
{
barometerData[i] = 0;
}
initTFT(); // Initialize the TFT screen
clearTFT();
init7SegDisplay(); // initialize 7 segment display
initHumiditySensor(); // start Humidity Sensor
initBaroSensor(); // initialize Pressure sensor
brightnessAdj();
requestTemperature();
readHumidity();
// initialize array
for (int i = 0; i < 133; i++)
{
barometerData[i] = 0;
}
currState = STATE_MAIN; // Initial state of the FSM
}
/***************************************************************************************************************************************************
## ##
## ### ### ###### ## ##
## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ##
## ## ## ## ## ###### ## ##
## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ##
###### ### ### ## ## ##
## ##
****************************************************************************************************************************************************/
void loop()
{
if (updateTime == true)
{
updateTime = false;
executeState();
}
userAction = checkUserAction();
if (userAction != NO_ACTION) // user has pressed a button
{
processAction(userAction);
}
else if (isWaitingforTimeout == true && millis() - timeOfLastButtonPress > 5000)
{
isWaitingforTimeout = false;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
startup = true;
currState = STATE_MAIN;
}
}
/***************************************************************************************************************************************************
#### ## ## ## ## ## ## ##### ####### ###### ## #### ###### ###### ### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ##
## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ### ##
## ####### #### ## ## ##### ##### ###### ## # ## ## ## ## ## ## # ##
## ## ## ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ## # ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ## ###
#### ## ## ## ## ##### ##### ####### ## ## ### ## #### ## ###### ### ## ##
****************************************************************************************************************************************************/
// check for user input
int checkUserAction()
{
//////////////////////////////////
// check for IR remote commands //
//////////////////////////////////
if (irrecv.decode(&irReceive))
{
switch (irReceive.value)
{
case 0x1C3B939F: // "Menu" key
userAction = BTN_SELECT_HOLD;
irRemote = true;// needed to check for IR input!
break;
case 0x75E8EBA3: // "Select" key
userAction = BTN_SELECT;
irRemote = true;
break;
case 0x150ADC43: // "Up" key
userAction = BTN_UP;
irRemote = true;
break;
case 0xA8A8B363: // "Play"
irRemote = true;
break;
case 0x6551963F: // "Down"
userAction = BTN_DOWN;
irRemote = true;
break;
case 0x2560B67: // "+" key
userAction = EEPROM_WRITE_BARO;
irRemote = true;
break;
case 0x5655FCFF: // "-" key
userAction = EEPROM_READ_BARO;
irRemote = true;
break;
case 0x3C1B0E83: // "|<<" key
break;
case 0xB55AE2FF: // ">>|" key
readArray(); // Debug. read array and display on Serial Monitor
readRTC(); // DEBUG. read RTC time and update system time
setTime(TMPhour, TMPminute, TMPsecond, TMPday, TMPmonth, TMPyear);
break;
case 0xD293DA9F: // "Spatial" key
userAction = MEMORY_RESET;
irRemote = true;
break;
case 0xF761B2A3: // "Power" key
break;
case 0x12284AC3: // "Shuffle" key
break;
case 0x509BADB: // "Repeat" key
userAction = LED_RING_MODE;
irRemote = true;
ledRingModeIsChanged = true;
break;
}// switch
//Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
// if IR remote is used, activate time-out function, used in the settings menu
if (irRemote == true)
{
irRemote = false;
timeOfLastButtonPress = millis();
return userAction;
}
////////////////////////////
// check for button input //
////////////////////////////
// no IR signals received, next check for button input
// check state of each button
buttonUp.Update();
buttonDown.Update(); // 1 = short click, -1 = long click (>1 second)
buttonSelect.Update(); // 0 = no input, Duh!
if (buttonSelect.clicks != 0) // check for user action of SELECT BUTTON
{
int clicks = buttonSelect.clicks;
if (clicks > 1) clicks = 1; // no double clicks...
switch (clicks)
{
case 1: // Select button is pressed 1x
userAction = BTN_SELECT;
break;
case -1: // Select button is pressed 1x for > 1 second
userAction = BTN_SELECT_HOLD;
break;
}
}
else if (buttonUp.clicks == 1) // check for user action of UP BUTTON
{
userAction = BTN_UP;
}
else if (buttonDown.clicks == 1) // check for user action of DOWN BUTTON
{
userAction = BTN_DOWN;
}
// no IR commands or button press
else
{
userAction = NO_ACTION;
}
if (userAction != NO_ACTION)
{
timeOfLastButtonPress = millis();
}
return userAction;
}
/***************************************************************************************************************************************************
###### ###### ### #### ####### ##### ##### ## #### ###### ###### ### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ##
## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ### ##
###### ###### ## ## ## ##### ##### ##### ## # ## ## ## ## ## ## # ##
## ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ## # ##
## ## ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ## ###
## ## ## ### #### ####### ##### ##### ### ## #### ## ###### ### ## ##
****************************************************************************************************************************************************/
// change state of the "state machine" based on the user input;
// also perform one-time actions required by the change of state (e.g. clear display);
void processAction(int userAction)
{
// Uses the current state to decide what to process
switch (currState)
{
case STATE_MAIN: //---------------------{ 0 }--{ STATE MAIN }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_TEMP_DISPLAY;
stateChange = true;
}
if (userAction == BTN_UP)
{
clearTFT();
currState = STATE_BAROGRAPH_TREND;
stateChange = true;
}
if (userAction == LED_RING_MODE)
{
ledRingMode++;
if (ledRingMode > 3)
{
ledRingMode = 0;
}
}
break;
case STATE_TEMP_DISPLAY: //---------------------{ 1 }--{ STATE TEMP DISPLAY }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_HUMIDITY_DISPLAY;
stateChange = true;
}
if (userAction == BTN_UP)
{
clearTFT();
currState = STATE_MAIN;
stateChange = true;
}
if (userAction == LED_RING_MODE)
{
ledRingMode++;
if (ledRingMode > 3)
{
ledRingMode = 0;
}
}
if (userAction == MEMORY_RESET)
{
temperatureMemoryReset = true;
minTemp = maxTemp = tempCelcius;
minTempHour = maxTempHour = hour();
minTempMinute = maxTempMinute = minute();
}
break;
case STATE_HUMIDITY_DISPLAY: //---------------------{ 2 }--{ STATE HUMIDITY DISPLAY }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_TIME_DETAIL;
stateChange = true;
}
if (userAction == BTN_UP)
{
clearTFT();
currState = STATE_TEMP_DISPLAY;
stateChange = true;
}
if (userAction == LED_RING_MODE)
{
ledRingMode++;
if (ledRingMode > 3)
{
ledRingMode = 0;
}
}
if (userAction == MEMORY_RESET)
{
humidityMemoryReset = true;
minHumidity = maxHumidity = humidity;
minHumidityHour = maxHumidityHour = hour();
minHumidityMinute = maxHumidityMinute = minute();
}
break;
case STATE_TIME_DETAIL: //---------------------{ 3 }--{ STATE TIME DETAIL }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_BAROGRAPH;
stateChange = true;
}
if (userAction == BTN_UP)
{
clearTFT();
currState = STATE_HUMIDITY_DISPLAY;
stateChange = true;
}
if (userAction == MEMORY_RESET)
{
setSecondsToZero = true;
}
if (userAction == LED_RING_MODE)
{
ledRingMode++;
if (ledRingMode > 3)
{
ledRingMode = 0;
}
}
break;
case STATE_BAROGRAPH: //---------------------{ 4 }--{ STATE BAROGRAPH }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_BAROGRAPH_TREND;
stateChange = true;
}
if (userAction == BTN_UP)
{
clearTFT();
currState = STATE_TIME_DETAIL;
stateChange = true;
}
if (userAction == EEPROM_WRITE_BARO)
{
// + button of remote pressed: store barometer pressur data array in EEPROM
pressureDataToEEprom = true;
}
if (userAction == EEPROM_READ_BARO)
{
// + button of remote pressed: store barometer pressur data array in EEPROM
pressureDataFromEEprom = true;
}
if (userAction == LED_RING_MODE)
{
ledRingMode++;
if (ledRingMode > 3)
{
ledRingMode = 0;
}
}
break;
case STATE_BAROGRAPH_TREND: //---------------------{ 5 }--{ STATE BAROGRAPH TREND }--------------------
if (userAction == BTN_SELECT_HOLD)
{
currState = STATE_MENU_ALARM_TIME;
stateChange = true;
isWaitingforTimeout = true;
clearTFT();
clearTimeDisplay();
clearDateDisplay();
clearSecondsDisplay();
drawSettingsMenu();
}
if (userAction == BTN_DOWN)
{
clearTFT();
currState = STATE_MAIN;
stateChange = true;
}
if (userAction == BTN_UP)
{
...
This file has been truncated, please download it to see its full contents.
Comments