Joystick Weather Clock, 15 months on


The original post for this project can be found here  A link to all the files on GitHub can be found here.

Following a suggestion from Alan Powell I decided to add a Humidity Sensor. The DHT11 is cheap and suited to this project. A lack of variable space meant that I was unable to save the data to the SD Card but as a bonus, the Humidity screen displays the Dew Point. See the end of this blog for more details.

Back in September 2015, I built this Joystick Weather Clock and it has sat on my desk recording pressure and temperature on an SD Card for fifteen months, without missing one hourly record. The data was stored as a CSV file so that it would load into EXCEL or similar spreadsheet program. I decided to see how it was faring after running all that time uninterrupted.

The fact that it was still saving data meant that there had been no stack overflow caused by unused variables filling up available free memory. The DS1307 Real time clock had not done too well, it was now 45 minutes fast, gaining around 38 seconds per week. The OLED display seemed to have lost a number of pixels and in places the display looked a little ragged, the LEDs used to light up under the display were still going strong. The pressure sensor was working perfectly.

So much for the hardware, what about the software? The calendar was perfect, having come through a leap year and the moon phase display was spot on. Data had been recorded exactly as designed and the whole file on the SD Card took up less than 4mb. Over 11,000 hourly temperature and pressure readings had been recorded and I believe this unit could run unattended for several years.

The pressure information was the most interesting, it was possible to follow the remains of a hurricane that hit the UK at the start of January 2016.


The pressure had remained fairly stable at around 102000 pascals until New Year’s Eve, dropping to below 98000 pascals over four days. The result was high winds and flooding.

I am really pleased with the software side, but I feel that a better Real Time Clock module is needed. To protect the OLED I think some kind of simple Screen Saver is needed and I will add this in the new year sometime. The subroutines to calculate the calendar and moon phase have worked flawlessly and, although the data saved on the SD Card is OK, I think that a VBA routine for EXCEL to extract the Pressure and/or the Temperature data and to place it all in a single column is needed. This will allow a graph to quickly be drawn. Please note that the hourly data builds up throughout the 24 hours and only the data saved at  2300 hours contains all the days’ data.

One final addition would be to use a 5-volt power bank as a backup battery, it can be left plugged into the Arduino and would only be used if the mains power was lost. The software saves the last 48 hours in a temporary file on the SD card, if the power is lost then once power is restored this temporary data is loaded, but if the power is lost for more than one hour the data for the time during power down would be lost.

Adding another Sensor:

The Sketch uses 74% of the available space for variables and at 78% usage the Arduino  IDE starts to complain, so I have tried to keep below this figure. I decided to try to fit a Humidity sensor, following a suggestion from Alan Powell. The DHT11 although slow is quite cheap and as long as you don’t request data too often it should work well. I started by installing the library and the routine to read the Humidity data. That consumed very little precious variable space. I then added a new screen to display the data. Now I had a working Humidity screen that also displayed the Dew Point.

The DHT11 is a slow device that should not be addressed more than once every few seconds. I decided to save the Humidity value and only update it once an hour when data is saved to the SD card. When you display the Humidity screen the value could be up to an hour out of date, but simply press the joystick and the value is updated immediately.

I fitted a ChronoDot board with a DS3231 RTC chip, this is just a simply plug in replacement, I just needed to swap the SDA and SCL lines. No change to Library or Sketch is needed.

Heres to the next 18 months when I can see how well the new RTC performs.


The new Humidity screen, accessed by moving the Joystick one place left from the Analog Clock Screen. The age of the reading is shown and although this is updated once an hour it can be updated manually at any time by pressing the joystick switch in this screen.

The DHT11 has three pins 5v, OUT and GND. Connect 5v and Gnd to the Arduino and OUT to digital pin 12. While I was fitting the DHT11 I took the opportunity to swap the DS1307 RTC for a (hopefully) more accurate DS3231.

The picture at the top of this post shows the new ChronoDot RTC and DHT11 fitted to the clock.


Use this connection diagram in conjunction with the wiring instructions in the sketch. Check the pinouts on your devices before wiring as they may not match those shown above. The OLED will die instantly if not connected correctly.

Arduino Stop Watch using ILI9328 2.4 inch Display

tft display

The sketch and all the images can be downloaded from my GitHub page here.

There are a number of versions of this ILI9328 TFT colour display, but the one shown in the picture above and here on eBay is designed to plug onto an Arduino and can use either 3.3 volt or 5 volt logic. There are a number of versions of this board that use 3.3 volt logic only and will need either a logic level converter or resistors on the logic pins.


This project uses the touch screen to start and stop the Stop Watch, the SD Card and loading and displaying images. I use the Adafruit Libraries and you will need the Adafruit_GFX.h (Core graphics library), the Adafruit_TFTLCD.h (Hardware-specific library) and the Adafruit Touchscreen.h (Touchscreen library). In addition you will need to download to your library folder SD.h and SPI.h libraries.

I wanted the display to look like an LED display so rather than printing the time I decided to go for a graphics approach. The sketch consists of three main parts, the clock section where a one second counter increments the variable secs from 0 to 59, the variable mins is incremented once every minute and the variable hrs is incremented once each hour. The second part checks the touch screen to see if one of the buttons has been pressed, so that the watch can be started, stopped and reset. The last part is the BMP file loader from the Adafruit test sketch, this loads a BMP graphic from the SD Card and displays it on the screen.

How it works::

Download the sketch and screen graphics from my GitHub page here and save the contents of the images folder to the root of the SD Card on the display. Upload the sketch then remove power and fit the display, reconnect the power to the Arduino and an image of a stopwatch is loaded from the SD Card and displayed on the screen. The LED display consists of five small graphics, hours, minutes and seconds and two colons and when these are loaded they overlay the graphic display. Touching the START button allows a timer to increment and each second the display is updated by loading new LED graphics. There are 59 graphics plus a colon and the stopwatch. It takes approximately 132ms to load each of the three graphics (hours, minutes and seconds) which is less than half a second in total. The timer uses the Arduino example sketch that times without using delay() and this allows the clock to keep reasonable time.

I could have simply printed the time as a string using txt.print(time, x, y) but the time display would need to be erased each time before printing the new time. Besides I think the LED graphics just look better. The colons could easily be made to flash every half second with just a small change to the Sketch.

The buttons are recognised by comparing the x,y values returned by the touchscreen library to the coordinates of an imaginary square around each button. The values in the sketch for the three buttons may need a small adjustment for individual screens, but touching the centre of the button should work in most cases.

Joystick Weather Clock using OLED Display

joystick clock

See how this project was doing after running non stop for fifteen months here

This project has been updated and now saves data to an SD card. The Git Hub code has been updated. I discovered a problem with the sketch that would give an incorrect February calendar  on some years, this problem has been fixed.

Code for this project can be downloaded from my Git Hub page here

If the SD Card is removed to read data while the clock is running, and then returned, the sketch will not be able to read the SD card. Press the Arduino Reset button to restart the sketch and reconnect the Card, the backup data will be uploaded to restore the data on the clock and data will be written to the card.

I wanted to try to build something that used a joystick for control and decided to build a clock with a number of different screens. These screens would be changed using the joystick and the natural choice for display was my small 128×64 OLED. After several weeks of trials I have come up with a clock that has the following specification. All screens are modified in some way, to display additional information, when the joystick button is pressed.


Once the circuit is built the code should be uploaded, although an SD card is optional using one will allow data to be restored after a power failure. The card should be formatted with a program like SDFormatter. When the sketch starts it will beep once, if the SD Card is recognised there will be a second beep. If the two files data.csv and backup.dat are not found these will be written to the card. If the backup file is found there will be a third beep as it is loaded. The small LED attached to pin 12 will flash briefly each time the backup is saved or loaded. The data.csv file adds data each hour and can be read by a spreadsheet program like Excel. The backup.dat file is overwritten each hour and contains up to three days data which is uploaded to the clock after a power failure. After the SD Card has been checked a splash screen is shown followed by the Analog Clock. Scroll through the screens by moving the joystick left or right.

The Display Screens::

analog clock

Screen 1. An analog clock with second hand. The alarm can be set/unset using joystick switch.

digital clock

Screen 2. A digital clock.Time is displayed in hrs/mins with a flashing colon for seconds. The alarm can be set/unset using joystick switch.

alarm set

Screen 3. This page is used to set the alarm time. Joystick Y pot is used to set time. The joystick switch allows both minutes and hours to be set. The underline shows which is being altered.


Screen 4. An event timer. Counts up to A maximum of 99 minutes (it will then stop), it is  started and stopped with joystick switch. This timer will continue to count when another screen is selected, to stop the counter return to this screen and press the joystick switch. A single beep is sounded every 10 minutes and three times when the counter has reached 99 minutes.




Screen 5. Pressure display in milli bars, shows current pressure change direction. When the joystick switch is pressed the reading changes to pascals.

pressure plot

Screen 6. A 24 hour graph of pressure. Clicking the switch shows last 24 hours and 2 days ago. Midnight starts on the left, 12pm is in the middle of the graph.



Screen 7. A weather forecast, a bit like the old ‘banjo’ barometers! The current pressure is compared to that from the last hourly reading, or if the switch is clicked, from the reading 2 hours ago. The difference in pressure is shown and a forecast based on this is shown.



Screen 8. Current temperature in degrees Celsius, click to show this in Fahrenheit.

temperature plot

Screen 9. 24 hour plot of temperature. and 2 days ago. Midnight starts on the left, 12pm is in the middle of the graph. Currently this is only displayed in degrees Centigrade.

moon phase

moon name

Screen 10. Moon phase, shows graphic and a description. Shows number of days to the next full moon. Clicking on this screen displays the name of this months Full Moon. Names from Medieval English are shown, but the code can be modified to show North American Indian or Chinese names.



child rhyme

Screen 11. Today’s Month and date. Clicking on this shows the appropriate verse from the childrens rhyme ‘Mondays Child’


month rhyme

Screen 12. The month displayed as a calendar. Clicking on this shows the appropriate verse from Sara Colridge’s poem.

In all 22 screens, all easily accessed using the joystick. The code is too large to show here and can be downloaded from my github page here. The github also has an RTC setting sketch and an instruction sketch that prints the instructions on the Serial Monitor.

Components and wiring:

An Arduino Mega is required, because of the program size, but I intend to publish two further blogs with the Barometer and Calendar as standalone sketches that can run on a UNO.

A joystick with switch                        (see this item on ebay)
A Real Time Clock – DS1307               (see this item on ebay)
A pressure sensor – BMP180             (see this item on ebay)
A 128 x 64 OLED display                    (see this item on ebay)
An active buzzer.                                (see this item on ebay)
SD card shield                                     (see this item on ebay)
Logic Level Converter for SD Card   (see this item on ebay)

(The logic level converter is only needed if the SD Card shield does not have a logic level converter chip. The SD card shield shown above does have one).

The SD card shield shown in the link above is a TF SD Card and has a logic Level chip that allows 5 volt signals without using a logic level board.

An active buzzer is required as the code required to operate a passive buzzer will interfere with the OLED display refresh.

The OLED, RTC and BMP are all wired in parallel and Vcc connected to 5 volts, Gnd to Gnd SDA to Mega pin 20 and SCL to Mega pin 21.The Joystick switch is connected to digital pin 2 (pulled high with a 10k resistor). Joystick Gnd to Gnd, Vcc to 5 volts. X Output to Analog pin 1 and joystick output Y to analog pin 0. The Active buzzer is connected to 5 volts, Gnd and digital pin 4. An optional SD  card can be used to store the hourly data in CSV format that can be opened in Excel. 5v connected to Arduino 5v, Gnd to Arduino Gnd (DO NOT CONNECT THE 3.3v PIN ON THE SD CARD. The next three pins needed to be connected via a Logic Level Shifter, MISO to Arduino pin 50, MOSI to Arduino pin 51 and SCLK to Arduino Mega pin 52. Arduino pin 53 is connected directly to the CS pin. All the connection details are in the Sketch. I laid all my components out on a breadboard for testing, but an Arduino Mega prototype shield could be used to make a permanent device.


Use this wiring diagram in conjunction with the wiring instructions in the sketch. Different manufacturers may have different pinouts to those shown here, so check, The OLED will die instantly if connected incorrectly!

The two small blue LEDs sit under the OLED and give a cool blue glow.

The program:

Upload the joystick clock sketch, the sketch sends some debug data to the Serial Monitor (9600, CR/NL selected) if you want to watch this output start the Serial Monitor now. The clock takes a snapshot of the pressure and temperature each hour and saves the data in a string. At midnight this data is moved to a second string (yesterday), the contents of that string is moved to a third string (-48 hours).

The graph displays the current 24 hours data for both pressure and temperature and -24 hours and -48 hours display can be seen by clicking the joystick. Data for the recorded pressure and temperature is stored in memory so if the power is removed, or the Serial Monitor is started the data would be lost. However, the data and a backup file are stored on an SD Card. The hourly data is stored  in a CSV file that can be opened in Excel. The sketch checks for the presence of an SD card on first starting. If one is found data will be stored on the card and any backup data will be uploaded.

If your RTC is already programmed with the correct time and date then the clock is up and running. If the time needs to be adjusted this can be done in one of two ways. Line 188 in the sketch is currently REM’d out (RTC.adjust(DateTime(__DATE__, __TIME__));) to set the clock un REM then upload the sketch. The RTC will be set to your computer time. REM line 188 again and upload this sketch (otherwise the RTC will be reset every time you run the sketch).

After a short Splash Screen the Home Screen is shown. This is an Analog Clock, the current Alarm state is shown and this can be set/unset by clicking the joystick switch. Move the joystick left or right to cycle through the various screens. Only one screen, the Alarm Set screen uses the Y (up/down) direction. To set the alarm, when the screen first opens the Minutes will be displayed with an underline. The minutes can be increased or decreased by moving the joystick up or down.  Click the joystick to move the underline over to the hours, this can then be set as the minutes were set. When the correct time is displayed move the joystick back to display the analog or digital display and set the alarm by clicking the joystick.

The alarm uses an active buzzer, this is pulsed on and off about once a second and the time has been set to run for 10 seconds (although this can easily be changed. The on-board LED is also connected to the alarm code.

The event timer counts up from zero to 99 minutes. Start and stop by clicking the joystick switch.

The barometer has a number of functions, first the current pressure in millibars, or pascals is shown. This is compared with the last reading taken and the direction  (rising, falling or constant) is shown. Just after the hourly reading this direction will almost always show constant, but as time passes this can show rapid changes in pressure between hourly readings.

The next barometer screen shows a graph of pressure readings taken each hour over a 24 hour period. The graph starts at midnight and continues until the last reading at 2300 hours. The data is stored in a string and just before the first reading at midnight the data is moved to a second string, the data from that having been moved to a third string. Data is therefore available for up to a three day period. To see an earlier 24 hour period click the joystick. The small ticks represent four hours. The bottom line is 990mb, the second line up is 1000mb. The next line up is 1010mb and the top line is 1020mb.

The last barometer screen is a Weather Forecast. This is the kind of forecast available on the old fashioned banjo barometers. The last two readings are compared, first to see if the pressure is rising or falling, then the rate of change measured. A forecast is then made based on these results. A result of this is that the forecast can be up to an hour old however, the forecast can often be good indication of weather conditions over the next hour or so. Clicking the joystick while this screen is showing will display the last forecast made and this can often give a better idea of the coming weather. A forecast cannot be made until the second hourly reading has been taken and the earlier forecast will not be available until three readings have been taken,

The next screen screen shows the current temperature in Centigrade, clicking the joystick displays the temperature in Fahrenheit. The temperature over a 24 hour period is shown on the next screen in the same way as the pressure screens. Click to display the last wo days data. The temperature is only displayed in Centigrade and the lower line represents 0C, the next line 10C, 20C and the top line 40C. If the temperature probe is to be placed outdoors the code would need to be altered if temperatures below zero are expected.

A moon Phase Screen is next, showing the phase of the moon in simple graphic format and the number of days to the next full moon. Clicking the joystick will show the name of the current months Full Moon. One of three version, Medieval English, North American Indian and Chinese names are shown, chosen at random.

There are two calendar screens, the first shows the month and day, rather like the old tear off calendar blocks, clicking on this shows the appropriate verse for today from the children’s rhyme Mondays Child. The second screen shows the month in standard calendar format and should be good for some years to come. Clicking on this screen will show the verse for the current month from the poem by Sara Coleridge.

About the joystick:

The joystick I am using has two potentiometers, X and Y, and a switch activated when the joystick is pushed down. With the connector on the left pushing the stick to the right moved from the analog clock to the digital clock. Pushing the stick up increased the values in the on the alarm set screen, for more information see this blog. The switch was very noisy so the code includes a ‘de-bounce’ routine. There is also a small delay in the joystick routines to ensure smooth switching of the screens. Move the joystick either fully left or right then allow it to return to its natural centre before moving it again. Occasionally the screen will skip to the next if the joystick is moved to quickly. The ‘centre’ value is read when the sketch first starts up to allow different units to be used without altering the code.

The Code:

The code consists of a number of routines controlled from the main loop, each screen is given a number and moving the joystick left or right will increase, or decrease, the current screen number. A switch loop is then used to call the required routine. The rest of the main loop checks the alarm time, gathers data each hour and sets or resets various variables and flags.

The use of an SD card is optional, if one is found then the buzzer is sounded twice, otherwise the buzzer only sounds once. The data is saved in CSV format to allow it to be read into a spreadsheet program. Data is saved once an hour as a backup. If this file is available when the program starts the buzzer will sound three times as this data is loaded. This is useful if there has been a temporary loss of power. Be aware that the data may be out of date if the Arduino has been powered down for some time.

Using delay() with U8glib can cause problems with screen refresh, so when a delay is needed (for example in switch de-bounce) the method used in the Arduino example for flashing a LED without using delay() was needed. Interrupt Service Routine is used to detect when the button is pressed and the ISR toggles flags that tell the routines to select alternative screens, or start and stop timers etc. The code is somewhat rambling. but achieves the aim I wanted. There is not much space left on the Mega and most of the diagnostic messages to the Serial Monitor have been REM’d out. There seems to be no problems with stack overflow .

In conclusion:

I had a lot of fun developing this project and intend to build a permanent version. I have extracted some of the routines and converted them to stand alone projects. My favourite routines are the pressure plotting routines and the weather forecast. I deliberately avoided using Progmem, but an optional an SD card can be used to store data.