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.