This project is a clock that can display time, date and temperature. The main unique feature of this clock is the ability to display date in Hebrew (Jewish) calendar format. Some other special features are:
You can set the time and date using an IR remote control.
The code is written as a state machine with no golbal variables at all.
The date is toggled between a gregorian calendar date to hebrew (jewish) calendar date.
In the end I'll show a nice package for the clock, which can be used in other projects.
Step 1: Disclaimer
THE AUTHOR OF THIS INSTRUCTABLE MAKES NO GUARANTEE OF VALIDITY AND NO WARRANTY WHATSOEVER.
Electronics can be dangerous if you do not know what you are doing and the author cannot guarantee the validity of the information found here. This is not a professional advice and anything written in this instructable can be inaccurate, misleading, dangerous or wrong. Do not rely upon any information found here without independent verification.
It is up to you to verify any information and to double check that you are not exposing yourself, or anyone, to any harm or exposing anything to any damage; I take no responsibility. You have to follow by yourself the proper safety precautions, if you want to reproduce this project.
Use this guide at your own risk!
Step 2: What You Need (Bill of Materials)
What you need to follow all steps of this tutorial is
- Arduino UNO (or nano)
- DHT22 sensor
- DS1302 real time clock
- IR Receiver TSOP1738
- LCM1602/2004 I2C Converter Module
- Car MP3 remote control.
You can use any other temperature sensor, I used DS18B20 temperature sensor at first but it doesn't supply a humidity measurement so I replaced it by DHT22.
The real time clock I have is DS1302. It's not an I2C device, it has 3 pins for communication. You can use another device such as DS3231, which is an I2C device.
The LCM1602/2004 is an I2C module that can operate the LCD. Instead of wiring about 14 pins, you wire only 4.
The remote control I have is the one you get with arduino kits, but you can use any other remote you have, as long as you change the remote control codes in the source code (the codes are in the carMP3Remote include file).
Step 3: Wire It All Together
Connect all wires like in the figure.
- The DHT22 sensor requires a pull-up resistor.
- The LCM1602 I2C module must be soldered to the LCD, you can't just put its pins in the LCD holes.
- After you turn on the LCD, to see something you must set the contrast using the pot on the LCM1602 module.
- The LCM1602 has an I2C address. Mine was 0x27, but some are 0x3F. There are tutorials about these modules.
- If you want the real time clock keep time when you disconnect it from power suply you must put in a battery. The battery is not used when external power is supplied to the clock.
Step 4: Code Description
Note: when I say "the clock" I mean the entire clock as a system. When I say "real time clock", I mean only the clock chip.
For the hebrew date I used the following public domain code:
"Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold, Software---Practice & Experience, vol. 20, no. 9 (September, 1990), pp. 899--928.
The above code converts between the gregorian date that the real time clock supplies to hebrew date. It actualy contains also Julian, Muslim and ISO calendar conversions, so you can use these if you like. Or you can use it without conversion at all.
Because the conversion is very slow I had to change some lines of code, so that it doesn't start searching all the past years over and over. Before the change, date conversion took almost 4 seconds and the clock seconds were jaggy. Because it's a clock the year figure changes once in a year (of course). The original code is more generic, it's used to convert different, non-related dates. But in a clock as i mentioned, the year is almost constant, so I changed the code so in the beginning it converts once using the slow method, but in the following conversions it uses the past year conversion approximation to start searching.
Other libraries are included in the zip file.
To prevent the use of global variables, all the variables and classes that their value should be saved are static. Also, classes that their instantiation time is long were defined as static. The problem with this method is that your setup() function can't access the variables in the loop() function so you have to redefine them. To prevent this redundancy, the state machine notion is introduced.
The code is built as a state machine. Every time the loop function is called, the clock is in a certain state. Transition between states are made according to defined rules. For example, when the clock starts, it enters INIT_STATE. This state is used instead of using the setup() function, so the loop() variables can be accessed.
After INIT_STATE the clock enters IDLE_STATE. This state is the starting position for all other state transition. The IR receiver is checked every time the clock is in idle state. This is not optimal, because if the clock is in some other state, the remote control won't respond. For example, temperature sensor is access is relatively slow. During temperature reading, the IR receiver will be inactive. A better way is to use interrupts (as I am a newbie, I didn't know about interrupts until later).
The temperature is read in READ_TEMP_STATE, and the time is read in READ_TIME_STATE. The rate of this states is defined in the beginning of the program. Time is read every 120milliseconds and temperature is read every 2 seconds.
Another thing to note is that the time update should be very synchronous. All time consuming actions must take place after the seconds figure was updated. So temperature reading is done immediatley after the time was updated. It leaves the clock a second to do other things, until the next time update. If we go to READ_TEMP_STATE from IDLE_STATE, the temperature reading might occur when we need to update the time and the clock seconds figure will not change in a constant rate. In such case the seconds don't tick at a regulat pace and it is disturbing, the clock looks very amature.
Required library list:
- DHT sensor library
- Arduino IRremote
- DS1302 library - included in my zip file, and here: DS1302 OOP
- Car MP3 library - included in my zip file
- time conversion library - included in my zip file
note that the DS1302 library is not the original file, I changed it to a class structure.
Step 5: Remote Control Manual
To set the time:
- EQ button toggles between seconds, minutes, hours.
- Use +/- buttons to set the number.
To set the date:
- CH button toggles between day, month, year.
- Use CH+/CH- buttons to set the number.
To turn off the backlight press 2 (you can't dim it).
- The hebrew date changes accordingly automatically.
- You can't set the hebrew date directly (maybe in the next issue).
- The day of week changes automatically.
- When the clock is in set time/date mode, the temperature is not updating.
Step 6: Cool Enclosure Box
You can put everything in this box that's normaly used for electricity wiring. I bought it in a local hardware store. The cheap ones cost less than 3$. Their plastic is soft and cuts easily. The expensive ones can reach up to 13$, but they are made of hard ABS plastic.
The LCD is placed in the lid by cutting a rectangle in the LCDs size. Be sure to cut from the inside, because if you accidently scretch the lid, it inside and not outside.
For the actual project I used arduino nano (altough uno can also fit inside the box). Instead of the breadboard I bought a PCB board 4x6 and soldered everything on the board.
I put the DHT22 sensor in the upper part of the box inside a hole. You can also extend it by a wire and put the sensor somewhere else (it is probably recommended because the backlight heat might mess up the temperature measurement).
The IR receiver is peeking from the left side of the box.
Step 7: Other Improvements
More special features I plan to add:
- Connect it to the internet using ESP8266 wifi module to synchronize the clock on a daily basis.
- Send messages over the interenet and display them on the LCD (buzz or blink an LED when a message received).
- Dim control over the LCD backlight.
- Atomatic dim control with a photodiode.
- Alarm clock.