This will be my first instructable and if you have any ideas how to improve it or make easier to understand please do not hesitate contacting me!
Well at first, this kind of "clock" is not my idea! I have seen lots of the througout the internet and they can be orderd for just a couple of bucks in diefferent webstores. But I didn´t want to buy one, I wanted to make one of my own to learn and to understand how it is working.
One word to "non-german" members... Sorry for the fact that this is just a "German Wort Uhr". It might be easily converted to english or any other language, but as I am German I made it in my language. If you need support for your language contact me and I will try to help you.
So let´s start...
Step 1: The Schematic
The schematic is straight forward and if the picture is to bad to read, there is a PDF file also.
Let´s begin at the bottom left corner. There is an simple power supply using an LM7805 to generate a stable 5V output for the PIC, shift registers (74HC164) and real time chip DS3231. All LEDs are also supplied from this part. D22 at the right end is just for indicating power supply and can easily be left apart if not wanted.
You can use any DC power supply for the clock with less than 40V, but you should then choose the appropriate value for C7. It should have a voltage rating of at least double the input voltage and remember you are creating heat in the LM7805 so you should try to keep input voltage as low as possible because everything else is just waste of energy. Best fit is something between 9V an 12V DC.
Do not bother about polarity of your power supply... The p-channel MOSFET (Q1) acts as an false polarity protection and the clock will just not work and not get any damage. You can check this on the "power" LED D22 if mounted.
On the right side of the schematic are the serial-in parallel-out shift registers. I decided to use them because I did not want to use an huge PIC with lots of I/O-Ports. I wanted to use a smaller one and I had still some 16F1829 at home so the choice was already clear. The data (IN_1, IN_2 and IN_3) is provided by the PIC (see code section below) and the REGISTER_CLK also. For simplicity in my code and PCB layout I used two of the 74HC164 for the hours and the last for the "logic".
In the upper left corner is the PIC and all necessary parts. I used the internal clock so no oszillator is needed. Only three resistors for SCL, SDA and MCLR. For the fact that I used the 32kHz as an indication of "exact seconds" there is no need for a quite stable and accurate frequency for the PIC.
In the middle there is the DS3231 with an minimum on external parts. In fact I used only the SDA and SCL inputs for communication over I²C and the 32kHZ output as an external clock reference for Timer1 of the PIC16F1829. For this output the datasheet says it is an external pull-up resistor needed. The other outputs I did not use in this project and left them unconnected.
Also in the middle, the LEDs... As you can read in the schematic I used blue LEDs (those with clear housing) and a resistor value of 1k Ohms. If you intend to make this project by yourself you should choose the values of these resistors according to the color and type of the LEDs you choose. Also keep in mind where you want the clock to be set up. My one is standing in my sleeping room therefore I did not want to the LEDs to be too bright and choosed a bigger value for the resistors. Make some tries on a breadboard with LEDs and resistor values before mounting them on the PCB.
Step 2: Layout
After finishing the schematic it is time to route the PCB. For that I used KiCAD (for schematic also). There is not very much to say, just route the lines.
For the fact that I printed the housing of the clock by myself, it was quite important where the LEDs on the top layer are located. I only put the LEDs and resistors on the top layer, because I ordered my PCB partly mounted (all the SMD parts) and because the company I choosed for that only places parts on one side and not double-sided.
You can see the placing in the two 3-dimensional pictures I made out of KiCAD.
If you are interested... It is possible to export the KiCAD PCB to Eagle and then it is quite easy to construct the housing, because you have a reference from the PCB.
Step 3: "Logic" of the "Wort-Uhr"
Biggest part for this project was the code for the PIC...
At first finding the "logic" of spoken time in German and translating it to code.
Unfortunately it was not possible to upload the Excel file directly, but I hope the PDF export is readable enough for you. If not, please contact me and I will send you the original Excel file. In the PDF you can see how I set up the logic for my clock. You can see how I went thrugh the different timessteps and how the spelling is. The calculation inside the code (mainly if-else statements) can be derived from the information on the right side of the table. One part is for minutes and one part for the hours.
As you can see this is no magic and can be easily coded in C. The "trickiest" point inside the logic is how to handle the hour as you can see in the file that only at the beginning of an hour the actual hour is shown. In German (maybe this might only be an Bavarian specific thing) the "next hour" is used quite early.
For coding I used MPLABX as my IDE of choice.
Step 4: Code Snippets
I will not post my code here, but if you intend to write your own code I will give you some hints what I have "stumbled over" during development...
First the "register"-filling:
If you transfer new data to the registers too often and in too short cycles I made the experieance, that the LEDs began to flicker. So I made some "blocking flags", that only everey minute a new "calculation" of spoken time is done and register update is made.
The code for filling the registers is in the picture above. As you can see I fill all 3 registers in parallel so I need 3 pins of the PIC for data and 1 pin for CLK. The 74HC164 takes over new data on a transition at the CLK line from 0 to 1.
Rest of code is mainly PIC dependent stuff, the "spoken time"-logic and handling communication and buttons. Communication is mainly provided by Microchip MPLABX because I used the MSSP module.
A good idea is reading the datasheet of DS3231 because data is stored inside as BCD so you might have to "transform" this in your code. Well as far as I am concerned I am a "learning by doing" guy and OF COURSE didn´t read the datasheet... Cost me al lot of nerves and hours.
As you might have noticed, there are two ways of "keeping time on track" with this implementation.
- You can read the actual time out of the DS3231
- You can "count seconds" in the PIC itself and just synchronice the time with DS3231 from time to time
It is up to you and both ways are practibal and straight forward. I used the first option and only synchronized time when adjusting time through the buttons (writing time to DS3231) or every 24 hours (reading time from DS3231), because I wanted to implement more logic by myself. I also turn of my clock during night (23:00 until 05:00) so that was a little bit easier in my opinion.
Step 5: The Housing
Last but not least it´s time taking a short look on the housing.
As I mentioned above, I made the housing by myself (using Eagle) and printed them with my 3D-Printer so I hade to keep look at the positions of the different LEDs.
Attached you can find the STL files if you want to use them.
Hope this instructable helps you when building your own "Wort-Uhr". If there are still "open questions" do not hesitate to contact me. Best way through commenting below, because you might not be the only one having a specific question.