I want to make the design as simple as possible and easy to convert into a cheap kit. Therefore, this cool small word clock except for PCB, a bunch of LEDs, 3D print light boxes, main MCUs, buttons, and RTCs, and unparalleled devices.
When I started this project for the first time, it is important to worry that there is too much light from the nearby letters to exudate each other, so that the display is difficult to read due to lack of contrast. In order to help the printed circuit board, I chose the black solder resist layer, and use the copper layer to try to block as many light as possible, but these will not help the scattering light inside the printed circuit board FR4 material, the material is Light yellow translucent glass.
Therefore, I rely on the main method is very old way, that is, using a physical isolator between each LED to try to block as many light as possible. Because I have a 3D printer, I can print the LED clock very quickly, the light box can also serve as a clock bracket and support with a small angle.
The following is the appearance of the design iteration:
Although this project is definitely not perfect, at least for me, considering the trade-off between contrast and design cost / simplicity of the LED, this is enough (I plan to sell the kit of the project, the more simple and more it is good).
Here is the assembly of my cool small word clock and the corresponding Demo demonstration, I hope you like it.
software design
This may be somewhat boring, but let's take a look at how I / why design clock software in this way. Keep in mind that I am absolutely not a professional software developer, so the way I finally do things is likely to be optimized or traditionally.
For beginners, I need a way to move the 12x10 LED matrix so that my main code portion can be dialogue with the RTC chip, generating animation, etc. To this end, I chose to use the interrupt of trigger conditions in 4kHz. Each time the interrupt is executed, it draws the current LED column (stored as a global array), then incrementing the column counter so that it can draw the next list until the last column is reached. Therefore, you can see how this display image is updated when the interrupt is worried how to draw it, how to update this display image by writing a display array (acting as the original display buffer). Also, by selecting whether to skip the cycle, it can even make the display look brighter or darker!
However, there is a small trouble, in order to make the circuit board easier to wiring, I will finally assign all rows and columns to the seemingly random I / O (rather than I usually tissue / according to the pin sequential order sequential order). This means that I can't do a simple fast port writing and update all row / column values correctly. In order to solve this problem, I created a pin map and associated function that adopts the required row and column status and switch all pins correctly, even if they are not normal. This feature is basically a large Switch statement.
How do you multi-purpose / scan for display now? Ok, start the entire column immediately. To this end, the anode of the vertical LED light strip in the column is driven by the pattern we want them to light. In order to actually select the correct column, we will connect to the pins of all LED cathodes in this column to output and set it, and all other column pins are set to input (high impedance, there is no current to flow). Simple? If you search for things such as "LED matrix works" on the search engine, there are countless examples and schematic diagrams to better explain better than I.
Therefore, from the programmer's point of view, writing data to the display is to set the pixels stored in the display buffer array, which seems magical place to show the corresponding LED! cool!
The next step is to process the button input. Ok, I just use another interrupt triggered when the button is changed (called pin change interrupt, the PIC is supported on some pins). When my interrupt sees the button, it will set a global flag, and any part of the program can be read, the operation is then cleared, so that all the other programs know the effect of pressing the button.
The reason why I use an interrupt in a scan is that it is avoided to manually operate in the primary loop and manual button input, because sitting there and repeatedly reading buttons waiting to be a waste clock cycle. Therefore, interrupts can handle these two cumbersome tasks and leave sufficient calculation degrees for the main part of the program, which can actually perform some interesting operations, such as time or displaying neat animations.
So how do you track time? Ok, I have a simple road and use the DS1302 serial real-time clock chip to complete this work for me. It can even be charged for supercapacitors for a period of time when power is turned off. I use the soft skewers I have written through the three-wire serial interface (basically SPI) to the RTC communication so that any GPIO pin required can be used.
I have to face the last thing to add animation mode. So far, it has seven modes: chase, random, flashes, ping pong, rain, bounce ball and ripple. Chase lights from left to right, run from top to bottom. Random hypnotrates with a random pixel pixel pad. Blinking will randomly open and close random pixels on the screen. Table tennis is basically a single table tennis game, and the ball rebounds near it and hits a paddle at its bottom. Rain is a decline in pixels that are randomly plummeted (almost makes people recall the notorious Matrix drop letters animation). The bounce ball is basically PONG, but there is no paddle, and the speed will be randomly changed each time you hit the ball.漪 is randomly generated transmission wave (like the surface of the water droplets).
You may have discovered that many of these animations use Random. I want to display many animations in different ways each time, but how to use the microcontroller to do this. For computer systems, it is difficult to achieve randomness without reading a random input. Ok, I cheat again. I use RAND () (a standard C function) to generate a pseudo-random number.
I said that the pseudo random is because it is actually certain (because it is the advantage of linear shift feedback calculations), but for a short period of time, ordinary people will not notice that it is not very random. The problem is that if you only use rand (), then each time you open the miniature power, it generates the same "random" digital sequence ... this random function begins to sound very random!
It is well solved, we can use the function SRAND (SRAND = SEED + RAND ... very creative ...) in different start numbers "sowing" it. But to make sure the seed is not always the same, we use this device to be the fact of the clock, and when the user starts an animation, the movie time is not the same as the last time. Therefore, we set the seeds to the current time (I basically closes hours, minutes, and seconds into a large number).
Ok, this article is almost here, and the above is almost overview of all interesting parts of the software.
Be
Copyright statement: HackADAY authorization, Circuit City original translation video, declined!
If you also like open source projects, and want to share your own open source work, contribute your strength for the open source world!
Video content delivery channel:
[email protected]
Our other product: