EC1204B Led Rotating Clock: Schematic, upgrade, firmware

0. Foreword

Please, do not post elsewhere the code found here.

– the code isn’t ready yet:

– I wish to develop more with several DS1621 sensors on a cable, in order to collect more than one temperature;

– The code should reside in one place and people should use links to my site instead. I have a hard time browsing the Internet for pieces of code sometimes, and finding old or obsolete code instead of links to the original developer is always a pain in the ass.

– I expect people to comment on the code and make optimizations/new developments, especially for student usage. Having this in mind, the code itself is an ongoing process which can be followed by students, from its first state (intelligible, but unoptimized) to its latest state (optimized, but unintelligible). Many people asked me how the code becomes awful and almost impossible to understand. It is my chance to show that I always start from a human approach and I am ending to a computer approach, and that this is always an endeavour that takes time and patience and endless computations and verifications, it doesn’t just come from thin air.

– the last reason is that I collect stats on page visits and downloads, which show me where to insist with open source development and where not to. I cannot collect stats from foreign sites, nor do I wish or have the time to do so.

1. Introduction

I have built the first one in ~3 hours and spent another ~6 hours to tutor a pupil of mine into soldering the second one.

The 3rd one had a badly burned firmware and didn’t want to start. Banggood will replace it, but I thought to spend some time and rewrite the firmware, since there were some things in the original firmware I didn’t like and I wished to improve.

Figure 1. Original EC1204B Led Rotating Clock

Moreover, what is the point in having a soldering kit without having the firmware and playing for hours with it afterwards, making modifications to the firmware and learning both soldering and programming?

So, I have decided to make this project and to turn it over to the community. Teachers will have a starting point to use this interesting and cheap kit to tutor their pupils.

More advanced hobbyists will have a full working example, using the excellent PCB coming with the kit.

The whole programming stuff took me 8 full days, including the time to write and post this article.

Later edit:

It took me 8 days to finish the first version, 16 days to the first working one, including errors, modifications and improvements suggested by Philipp Klaus and Sergey, with their kind comments.

Much later edit: After almost two years I still have found improvements to the code.

Disclaimer:

The software/firmware presented here is a complete rewrite from scratch, just by observing the schematic and by understanding the way it works. It did not involve any kind of disassembly of the original firmware, reverse engineering or other similar stuff.

I do not condone copying the work of others in any way. However, progress is difficult to achieve these days from zero and it is easier to build up on something that already exists, while respecting the original work and effort.

I advice my readers to buy Banggood kits, the PCB has an excellent quality and all the parts delivered will be used, even with the modifications I suggest in this post. The idea is to start learning soldering and coding using affordable ressources.

Video: Modified EC1204B clock, latest version.

2. Modifications to the original schematic

First of all, the kit contains a few spare parts, that we will use to make the actual modifications to the clock.

Why modify the kit?

The clock is powered by an AT89S52 processor, which is an enhanced version of the classic Intel 8051. Pin to pin compatible, this processor is capable of running much faster than the original i8051. However, finding a nice development interface (IDE) and a good programmer for it is quite difficult. So, why not use more a more modern processor?

I found the AT90S8515 as being pin to pin compatible with the AT89S52, with minor differences:

– pins 29, 30 and 31 which have different functions. These pins are not used anyway, so no modifications required here.

– the reset pin (pin 9) is active high on the AT89S52 and low on the AT90S8515. So, a first modification would be required here.

– Pins 12 and 13, tied to the micro switches, should be pulled up with resistors, in order to minimize noise on these pins.

– AT90S8515 runs at 8MHz maximum while the original AT89S52 works at 12 MHz.

Figure 2.Modifications to EC1204B Led Rotating Clock

The modifications are written on the picture, but I will enumerate them here one more time:

1. Cut wiring on PCB, removing the link from the reset switch to VCC.

2. Solder a piece of wire as shown, linking the reset switch to GND.

3. Desolder C5 and R21. Solder R21 at the place of C5, building a pull-up resistor for the reset pin.

4. Do not solder anything at the place of R21. A capacitor on the reset pin will make the processor unprogrammable through ISP (in-system programming), since the RST signal is handled by the programmer.

5. Solder two resistors between 4.7Ko and 10Ko as shown, in order to pull up the SET and SELECT signals. The kit provides for 3 extra 10Ko resistors. I have used 5.6Ko resistors just because the other ones were not at hand at the time I have make these modifications.

6. Desolder the 12MHz quartz and replace it with an 8 MHz one. AT90S8515 will not run consistently (or will not run at all) at 12 MHz.

Later edit: Don’t do it at home! I wondered for quite some time how an overclocked Atmel processor would perform. So I reverted to the original 12MHz crystal, closed my eyes and powered the circuit after defining the new frequency in the software and recompiling it. Surprise! It really worked!

After a few days, though, I saw some glitches:

– mode 9 of displaying seconds doesn’t work as expected – the leds are completely crazy;

– the connection with “some” DS18B20 stop working after a while: the display shows always 127 (communication error). They start working again after a reset, so…

Still, the processor is as cold as before and, if you’re not too bothered by these two issues, you can test it for several months and post your experience here.

Figure 3. EC1204B Led Rotating Clock with AT90S8515 micro controller

At this time, the clock is ready to be connected to an external programmer. I have used an STK500:

Figure 4. Modified EC1204B Led Rotating Clock connected to a STK500 development board

Whichever programmer you wish to use, you need wires to link the programmer’s signals to the clock’s programming pins. The clock’s PCB is clearly marked with all the signals: GND, RST, SCK, MISO, MOSI and VCC.

3. Modus Operandi (How It Works)

This operation manual was updated on 26.02.2017, following the many additions to the firmware during the last two years. All timigs were also recomputed during this rewrite of the operation manual.

Definitions:

SET key: the left key

SELECT key: the middle key

RESET key : the right key

A. Special Startup Mode: Seconds Led Design

Keep pressing both SELECT and SET keys then press shortly RESET. Depress the SELECT and SET keys. You are now into Seconds Led Design menu.

Pressing SELECT, you will see numbers from 1 to 9 corresponding to the 9 ways seconds can be displayed by the circular leds. The leds show a live preview for every display mode.

Pressing SET , the selected mode will be written to memory and you will hear a confirmation beep. The selected mode will be in effect after a power off of the clock

Not pressing any key will revert to Clock Mode after about 10 seconds but the selected mode will not be written to memory, preserving it just until the next reset or power toggle.

B. Special Startup Mode: EU or US mode

Keep pressing the SELECT key then press shortly RESET. Depress the SELECT key. This will toggle between European (EU) and United States (US) modes and will affect the way the clock is displaying information:

EU mode: the clock displays 24h time and temperature in Celsius;

US mode: the clock displays 12h time and temperature in Fahrenheit;

C. Special Startup Mode: temperature toggle every 10 seconds

Keep pressing the SET key then press shortly RESET. Depress the SET key. This will toggle between regular time display mode and a mix of time and temperature. In the latter case, the clock displays the time, except for 0,10,20,30,40 and 50 seconds when it will display the measured temperature for one second. This mode was requested and it can be used in rooms or locations where a visual display of the temperature is important: saunas, datacenters etc.

Only the temperature of the first sensor is displayed in this mode.

D. To Show The Temperature

While in clock mode, short press SELECT. This will trigger the temperature mode, displaying it for all connected temperature sensors in a loop.

First, the sensor number will be displayed: “tE: 1”. A second press on SELECT will display the corresponding temperature for the first sensor.

If there are multiple DS18B20 sensors connected to the clock (maximum is 5 sensors), pressing SELECT again will display in order “tE: 2” then pressing select again the temperature of the second sensor and so on, in a loop.

EC. To Show The Day, Month and Year

While in clock mode, press SET and depress it as long as “dAtE” is displayed on the screen (<5 seconds). The month and day will be displayed for about 2 seconds.

Alternatively, pressing SET in this mode, you don’t have to wait for “dAtE” to be displayed. A short press will suffice.

Press SET again and the year will be displayed for about two seconds.

Press SET again and the clock will show the time.

D. To Set The Alarm

While in clock mode, press SET and depress it as long as “S :AL” is displayed on the screen (6-10 seconds).

First you may change the minutes of the alarm by pressing SELECT.

Pressing SET again will display the alarm hour.

You may change the hour of the alarm by pressing SELECT.

Pressing SET again will display “on” or “oFF” depending on the value read at start time from the EEPROM.

You may change if the alarm is on or off by pressing SELECT.

Pressing SET again will write the alarm values into EEPROM and the you will hear a confirmation beep.

Not pressing the final SET will change the alarm time, but it won’t be memorized in EEPROM. Thus, a power toggle or a RESET will revert alarm time to whatever was stored in EEPROM.

E. To Stop The Alarm

Just press either SET, SELECT or RESET to stop the alarm until the next time match will occur. If no button is pressed, the alarm will keep beeping for about 10 minutes.

F. To Set The Time

While in clock mode, press SET and depress it as long as “S :CL” is displayed on the screen (more than 10 seconds).

First you may change the year by pressing SELECT.

Pressing SET again will display the month.

You may change the month by pressing SELECT.

Pressing SET again will display the day.

You may change the day by pressing SELECT.

Pressing SET again will display the minutes.

You may change the minutes by pressing SELECT.

Pressing SET again will display the hour.

You may change the hour by pressing SELECT.

Pressing SET again will write the set time into DS1302 and the you will hear a confirmation beep.

Not pressing the final SET will discard all modifications made and the clock will revert to the previous settings.

Every step has a 10 seconds timeout. Not pressing any key during this interval will revert the clock to time display mode. All the settings will be lost.

4. Firmware

The code is (almost) fully commented,, because I wanted to make it easy to read, easy to understand, and a possible start for a programming course example.

What can a pupil learn from this nice clock?

Hardware:

– How to solder both through-hole and SMD components, by hand;

– How to arrange for parts on both sides of a PCB and solder them, taking into account the height of each part.

– How to find the best spots to make modifications on a given PCB.

Software:

– How to deal with the special registers of a micro controller;

– How to enable/disable interrupts;

– How to multiplex data on a large bus (12 bits) using interrupts;

– How to use variables, constants, #define and EEPROM variables and to grasp the difference between them;

– How to build custom menus for a given task;

– How to make variables prisoners between two given values;

– How to use 1-wire and 3-wire communications;

– How to dynamically program ports for input or output;

– How to write nice and clean code, easy to debug; The RTC library is a bad example of how to write a library.

– How to program a basic alarm which can be shut off;

– How to deal with bitwise operations. I wrote the program specially using |,||,~,^,&,&&,_BV(), binary and hex values, to show the many ways an operation could be done.

-How to use local and global variables;

I am sure a good tutor will find several other stuff to dissect and learn to willing pupils. The main code is almost fully commented for a better understanding.

B. DS1302 stuff.

5. Final considerations and Downloads

The code takes almost all the AT90S8515 flash memory (7.51K out of 8K available), so there is place for small modifications.

There is also place for improvements, if one is interested enough.

Another candidate to replacing AT89S52 would be an ATMega8515, which can run at 16 MHz instead of 8MHz when driven with a crystal. This processor is also able to run at 8MHz with an RC internal oscillator. If programmed as such, we don’t need the crystal and the two capacitors anymore!

I know there is also an other candidate from the ATMega family, compatible pin to pin with AT89S52, but I let to you the burden to browse through datasheets and discover it 😉

All the project for Atmel Studio 4 can be downloaded here. It contains an error, see 7. Errata

repeating the whole process in all the program, makes the code drop again from 6.5 Kbit to 5.86 Kbit.

With just two functions related to the way we display seconds, the code dropped with an astounding 1.74K (21%).

Unreadable code, but no less much smaller than the original!

I dare you to try reducing the code to 4K, while keeping all its features!

7. ERRATA

The code above (clock.c) contained an error related to DS1302: instead of using dt.date, I have used dt.day. Thus, reading and writing the date showed and wrote in fact the day of the week.

This error has been addressed below.

8. More Modifications And More Learning

While looking at the kit, there is something missing on the PCB: a 4-pin connector marked “bluetooth”.

Pin 1: connected to pin 10 of the processor

Pin 2: connected to pin 11 of the processor

Pin 3: GND

Pin 4: VDD

According to the datasheet, Pin10 is RxD and Pin11 is TxD of the embedded UART (AT90S8515) or USART (ATmega8515).

I remembered those HC-05 or HC-06 bluetooth modules available on the market and I realized the producer already thought to a further development of the kit, probably the possibility to set its parameters through bluetooth, from a phone.

While this is an interesting development, it doesn’t imho add too much to a learning curve. It just augments the addiction young people have today to smart phones.

Why not put his connector to a better use?

I had at home some DS1621 digital temperature chips, working on I2C.

So, I have created the following schematic:

Figure 5. Schematic for a DS1621 addon card.

I fitted the board with the help of two 4-pin male and female connectors to the clock’s board and started to write code.

What is so interesting in this DS1621 chip? Well, nothing special. It is just another thermometer, using I2C communication.

What is special is the fact that ATmega8515, which I have used for this modification:

a) does not have a hardware Two Wire Interface (or TWI) that could be used for I2C communication. Thus, a bit banged library had to be used (a library which recreates by software a whatever protocol, instead of relying on hardware).

b) it can be programmed to run out of its own internal 8MHz oscillator, meaning that the 8MHz crystal I had to changed may be removed permanently.

c) may be clocked by crystals of up to 16MHz, so we could resolder the original 12 MHz crystal (while I don’t see the point of doing this).

In order to maximize speed, an assembler code had to be used. Thanks to Peter Fleury, who has already wrote this library years ago, the implementation became suddenly much easier.

The new project for Atmel Studio 4, which includes the I2C (orTWI) and the DS1621 AVR GCC libraries can be downloaded here.

– if the minutes are odd, we light every led until the current lit led equals the current second, then we turn off all other leds, one by one

– we wait for 700 microseconds

– if the minutes are even, we turn off every led until the current lit led equals the current second, then we lit all other leds, one by one

– we wait for 700 microseconds

The total computing time reaches ~90 milliseconds, there is a rest of 10 milliseconds to have a delay between seconds.

These delays over delays have a negative impact on the way the clock works, especially if another execution thread comes into action:

– the alarm sounds like crap;

– setting the clock becomes a pain in the a** because short key presses are almost never felt, since the clock is “waiting for time to pass”.

This led me to reconsider the approach and to try to eliminate the delays, without having a strong visual impact.

9.2 Second and final attempt

Since the display and the leds are multiplexed, and the timer overflow code runs again and again (in fact it runs 1024 times a second), why not use a counter to see how many refreshes were made, divide this counter by 13 and use the result? Why 13? Well, 1024/24=78. We could use the first 60 numbers (0-59) to light up the corresponding led, and wait during the numbers 60 to 78.

This approach would solve more than one issue:

– the delay between two leds is determined by the setting of the timer itself, i.e. by hardware, instead of software (delays);

– the delay between two leds is very precise, since we don’t do for cycles anymore.

– the delay between the end of the last led and the following second is very precise;

– we don’t use delays anymore, so reading keys and sounding an alarm will perform as good as in the other modes of seconds display (1 to 8).

– the processor is processing slightly more than in the first case, when it had to process A LOT.

There is an issue though: the refresh/13 and the start of a new seconds are almost certainly not in phase. Resetting the refresh counter at 1024 does not mean it will be reset at the same moment a new second is coming. This leads to a shift between showing the seconds dots and displaying the seconds leds. When the seconds reach 59 and before changing to zero again, part of the leds don’t lit anymore.

The solution was to reset the refresh counter at the same time the read second from the DS1302 changed. This was accomplished in the timer overflow routine with a simple code, as follows:

ISR(TIMER1_OVF_vect)
{
uint8_t PV;
//comment up to the next sign in order to use first version of function for seconds #9
// |
// |
// v
refresh++;
timestamp1=seconds;
if (timestamp1==timestamp2)
{
if (!refresh_resetted)
{
refresh=0;
refresh_resetted=1;
}
}
else
{
refresh_resetted=0;
}
// ^
// |
// |
//comment from the first sign in order to use first version of function for seconds #9
switch (digit_addressed)
... blah blah the same thing as in previous versions
if(digit_addressed>=12) digit_addressed=0;
//comment the following line in order to use first version of function for seconds #9
// |
// |
// v
timestamp2=dt.second;
// ^
// |
// |
}

I have discovered a few errors in the firmware (delays not working) and also typos in this very article.

I wrote also a couple of supplementary functions to lower the code size.

11. Multiple DS18B20 on a wire

This development took some time because I was waiting for my DS18B20 stack to arrive.

Thanks, Sergey, for commenting on my blog and giving me the necessary push to write the code.

Thanks, Philipp Klaus, for showing me the error in defining the CPU frequency. It helped a lot, especially in the 1-wire protocol, where delays are of the essence and strongly tied to the CPU frequency.

The nice little clock is able now to show up to 5 (modifiable variable) DS18B20 sensors, connected in parallel on the same wire.

The program does an automatic search for the sensors and is able to read and display the temperature of each of the sensors it finds at start-up.

Sensors can be plugged in live, while the clock is running, but to detect new sensors the clock must be reset from the reset button.

If the temperature shows at times “85C” it is because this is the initial value of the sensor.

If the temperature shows “127C” it means there is a miscommunication with that particular sensor. Check the cables, solderings etc. It might also mean the sensor is dead, in which case it needs to be replaced.

The order the sensors are discovered seems random to the end user. This order is in fact determined by the serial number of each sensor. The good thing is that the sensors are always detected in the same order if they are not changed. Their position on the wire doesn’t matter.

While adding or removing sensors, the order modifies again, but remains the same if no more sensors are added/removed after a reset or power failure. This way, in order to match the software order with the physical order of the sensors, it is enough to rearrange the position of the sensors on the wire so it matches the software detection order.

Connecting the sensors must be done by using shielded microphone cables especially for longer distances (more than 3 meters or 9 feet). An alternative would be the use of a 3-wire twisted cable. Check and see what works.

What is NOT implemented in software:

– negative temperatures (with a “-” in front of the temperature). I tried putting an ice cube onto one sensor and it got down to…1C after 5 minutes. It didn’t want to get to a lower temperature. The code is however opened to modifications.

– parasitic supply and all the other exhaustive features DS18B20 know about. I’ll leave this for whoever wishes to better the DS18B20 library. It’s not hard. It’s just that I don’t have the time to write a full library for this sensor.

– CRC8. First, it would be a software burden, bearing in mind the flash is almost full with this version of the firmware. Second, you don’t need CRC8 is your sensors are connected with shielded microphone cables of up to 3 meters. Cautin, however, in very noisy environments. Reading could be wrong.

The seconds don’t show accurately on mode 9 while performing temperature readings, mainly because the low level of the one-wire protocol are disabling and re-enabling interrupts. All other functions are working just fine.

This firmware release is not implementing the I2C protocol anymore, neither is it capable to read from the DS1621 anymore. The libraries were removed from the project in order to make space for the larger code of the main program and the new DS18B library. The files remained however in the project’s zip file.

13. Displaying the temperature every x seconds while displaying the time

Peter Casper had a request to alternatively show the clock and the temperature, for he wishes to use the clock in an infrared-heated room.

I thought using the same idea as above, so a new EEMEM variable was defined and if at programming time it is equal to 1, it fires a condition in the main loop that shows the temperature for 1 second every 10 seconds. It displays just with one (or the first) temperature sensor.

Some optimizations to the display routine were also made.

Because this firmware is about to hit the available flash memory in the mega8515, I had to look closely of the size of the binary data that was about to be burned into the MCU. How to do this, since the HEX file size has nothing to do with the size of the binary code? I have written this morning a Windows tool that converts Intel HEX files to binary and viceversa + it allows for automation…well, silent repetition of a load and save operations. I know, I am lazy, that’s why I wished for automation. Find what it is all about in this post.

14. Combining all latest developments in one and allowing for setup without the need to reprogram the flash

While working on the latest requests for US mode (12H display and Fahnrenheit instead of Celsius), I used EEPROM variables to shorten the code and allow for its implementation. Unfortunately, to change these modes, the clock needed to be reprogrammed.

After many optimizations, I have succeeded to implement a way to set these modes without the need for a programmer.

Resetting the clock with the SELECT key pressed will toggle between US and EU mode:

At this moment, the firmware has EXACTLY 8192 bytes, occupying all the flash memory available on the processor:

15. Latest optimizations and additions

Having lots of people testing the software is certainly an asset, as other may discover hidden bugs otherwise impossible to see.

It just happened to one clock that, when the power came down and up again repeatedly, the eeprom section of the clock just erased by itself.

A more in-depth look at the mega8515 datasheet states in fact eeprom corruption in special circumstances, when the voltage is slowly rising, on heavy filtered power sources, or, maybe, when power goes down and up again, leading to the same effect. The MCU executes erratic commands and the voltage is too low for proper eeprom operation, so anything can happen.

Since the code was 100% full, I had to look and identify which are the similar sections of code and write a procedure to be called insted of repeating the same lines of code. This code was identified in the menu section of the main loop. It was optimized and I got some other ~300 bytes of flash that could be used to implement an eeprom corruption prevention system.

Basically, all constants in the eeprom were defined with separate default values and a crc was implemented. Every eeprom read was checking the crc and every time an eeprom value changed, like the alarm etc, the crc was recomputed and written into the eeprom. If the crc is not the expected one while reading any eeprom value, the whole bunch of eeprom variables are reinitialized with their default values.

17. Timings

All the latest additions to the firmware made that some timings related to the duration some information was displayed became erroneous. This latest development addresses these errors and corrects them.

INTERNATIONAL

Adblock user:

Hey, adverts can be pretty annoying, right? I know how it is; I don't like it when I'm browsing a site and I accidentally trigger an awful flash ad where a big, freakish iPhone starts singing at me. That's why here I'll only ever serve up nice banners that behave properly.
This website is a personally-funded hobby, and without donation/advert revenue I won't be able to keep it going. Please, if you enjoy the site, consider adding it to your AdBlock whitelist—it really does make a difference.