fulhack.org/nerdclock

[FAQ] [Technical Stuff] [Pics] [Downloads] [License]

General information (FAQ)

What is NerdClock?
It's a simple clock, showing the time in binary coded decimal (BCD) format using RGB LEDs.

It includes a Bluetooth chip, which allows for wireless configuration of the NerdClock via a phone or other blutetooth-capable device. The following parameters are configurable via the bluetooth connection:

  • LED colour (individually for each LED)
  • LED calibration/dot correction (individually for each LED)
  • Current time
  • Test mode on/off (Test mode turns ALL LEDs on)
  • All settings can also be retrieved from the device over the Bluetooth connection

NerdClock also comes with an Android companion app that can control all aspects of the NerdClock device.

All settings are saved in the device so that if the device looses power, all settings are automatically re-applied when power is restored.

In addition, the RTC module is powered by a battery so that time can be kept even during power loss. This means that no configuration at all is needed after a power loss - once power is reapplied, the device will keep going as if there had been no power loss in the first place.

Why is NerdClock?
Mainly because building stuff is fun, but also because I wanted to try building something that would give me a reason to develop an Android app.

Can my phone run the Android companion app?
My current phone when developing it was an LG Spirit H440N running Android 6.0 (Marshmallow). Because of this, I also chose API level 23 (Marshmallow) as the intended API and this is also the only phone it has ever been tested on.

The best way to know if you can run it is probably to just download the APK and try.

What communication protocol is used for configuring the NerdClock?
You should be able to figure the communication protocol out by looking at the definitions in ConfigEntry.h.

There is one thing that might be less obvious, though:
In order to make sure that the NerdClock will not get lost forever in the configuration reception in case of error, the value 0xff has been reserved as a special value meaning "Begin new config entry".

Since the configuration protocol is a binary protocol where 0xff is a perfectly acceptable value in some fields, this means that measures are required to make this reservation of 0xff work.

This has been solved by also reserving the value 0xfe to mean "interpret the next byte in a special way"

This means that if the sender wants to send "0xff" it sends "0xfe 0x01" instead, and if the sender wants to send "0xfe" it sends "0xfe 0x00" instead.

The receiver then also interprets the data in the same way, meaning that when it sees "0xfe 0x00" it is interpreted as just "0xfe" and when it sees "0xfe 0x01" is interpreted as "0xff".

Also:
The ATMega firmware is implemented without use of interrupts. Everything is polled and actions are performed in sequence.

This means that in order to avoid data being lost, special care must be taken when communicating with the device.

  • Before attempting any other communication, a ConfigurationMode command/ConfigEntry must be sent to the device.

    This command is exactly 3 bytes long and the reason this is important is that the ATMega328/168/88/48 UART receive FIFO is 3 bytes long (or actually, 2 bytes + the UART shift register itself). This enables the device to receive 3 bytes without error even if the data is not handled internally in the device, which is exactly the scenario we have.

    When the device receives this command telling it that Configuration mode is enabled, it stops communicating with the DS3231 and TLC5940 devices and enters a mode where it keeps constantly polling the UART for data. This polling is now fast enough for it to receive any amount of data without loosing any of it.

    After performing the needed configuration, another Configuration mode command should be sent to tell the device to resume communication with the DS3231 and TLC5940 chips. If this is omitted, the device will get "stuck" in configuration mode and will not update the current time.

  • After receiving a command, the device will answer with an ACK when it is ready to accept new commands. Failure to wait for this ACK before sending new messages will most likely result in data being lost.

    The ACK consists of the ConfigurationEntryType of the received command being sent back to the user.

All of this communication stuff is of course implemented in the Android companion app.

Anything else?
You are fully responsible for any and all actions you take using information and/or code or hardware from this site. Basically: USE AT YOUR OWN RISK!


Technical Stuff

The firmware for the ATMega has been written in C++11 and the Android companion app is (of course) written in Java.

The main reason to opt for C++ instead of plain C is that I wanted to see how well C++ was supported in the AVR tool chain (and so far I'd say the support is good).

The main reason to go for C++11 specifically is that it introduced a whole bunch of new features not available in older C++ versions, while still being old enough to make me feel confident about compiler support.

When it comes to HW, you need the following stuff to build a NerdClock:

Arduino Nano

You don't actually need an Arduino Nano for this - all you really need is an ATMega48/88/168/328. The Nano is an excellent bit of kit though and might be the best thing since sliced bread.

Just take a look at some of the features it offers:

  • ATMega328 already wired-up (and running @ 16MHz)
  • Pin headers for all pins
  • ISP header
  • On-board 5V voltage regulation
  • On-board FTDI chip and mini-USB connector (great for debugging!)
  • Small form-factor that allows for easy mounting to breadboards
  • Can be had for ~3 USD on eBay (which is an absolute steal!)

DS3231

IC RTC (Real-Time Clock) module. Used (obviously) to actually keep track of the current time.

HC-05

Bluetooth module. Connected via UART and works as a bluetooth UART bridge. Used for configuration purposes (current time/LED colours/...).

TLC5940

PWM/LED driver chip. Each chip can drive 16 independent PWM channels (and each RGB LED uses 3 of those channels).

Common Anode RGB LEDs

I chose large (10mm) and bright LEDs but you can of course use whatever you want. It is important that they are common anode though (common cathode won't work with the TLC5940).


Pics

NerdClock Device

Android companion app

Main Activity Configure LED Apply settings to all LEDs

Downloads

Note that the Android companion app especially could use some more love. It's a bit lacking in the UI design/implementation department. Just one example of that there's room for improvement is that the UI is not scrollable. At all. So if the entire UI doesn't fit on your screen, there's no way to actually see everything...

Sources

The zip file(s) contains a schematic of the hardware and source code for the firmware and Android companion app.

Binaries

Self-signed APK file for the NerdClock companion app.


License

NerdClock is released under the MIT License.


/Olof Holmgren [olof@fulhack.org]

Valid HTML 4.01! Valid CSS!