Sunday, March 17, 2019

Debugging the IN-17 Nixie clock (aka "Rothko clock")

This weekend I felt like doing something, which rarely happens lately. From the pile of semi-failed ("started but not finished", "finished but not working", "not fully functional" etc.) I picked the Nixie clock with 6 IN-17 tubes. Its problem was that it did not display any 6 nor 7, on all tubes. A quick check with the meter showed, indeed, a short between 2 neighbor pins. Upon visual inspection (not as easy as it used to be) and with a lot of luck (and magnification), I found the culprit: one tube in the middle of them all had two pins crossed (inverted), as shown in the photo below.

Here is the board with the IN-17 removed.

Since it was impossible for me to re-insert the old short-pined IN-17 (because of the tight space), I had to use a new one. Everything turned out well in the end.

Now onto the usability of this pretty Nixie clock. The only way to set the time is to send commands from a Bluetooth device (phone, tablet). This is not very "user friendly", nor quick, is it? The obvious "remedy" to this situation was to add a couple of buttons on top, where they can be easily pressed. As you may know from my old post, the high voltage (170V) for powering the IN-17 tubes is generated in the same top-of-the-board area, definitely not a good place for fingers. The solution was to use a longer piece of prototyping PCB to cover the danger zone.

As in most simple clocks, the right button increments the minutes, the left one increments the hours, while the seconds are always reset.

I also added a hardware "12 hour mode" through the use of a jumper placed at the bottom of the board:

With the jumper off, the clock shows military time (the hours between 0 and 23).

Unlike the first version, this new Nixie clock, which I shall name "Rothko clock" from now on, uses just 2 boards: wsduino (with on-board RTC and XBee support, assembled for 9V power) and the Nixie shield itself. The 2-button hack should be made somehow permanent, probably by adding them onto the Nixie shield, similar to the LED matrix mini display shield used in the Mondrian clock. Also note that the alarm feature won't work (although implemented in the code, shared here) since there is no buzzer. Bluetooth should still work with a BTBee module plugged into its wsduino socket.

Interestingly, after all these years, one "new old stock" IN-17 Nixie tube can still be bought on ebay for about $7 (compared with about $2 for the bigger IN-12s).

Sunday, March 3, 2019

Wise Clock 4 - March 2019 software release

A long overdue (3+ years since the previous one!?) release of the Wise Clock 4 software is finally here. This one compiles on Arduino 1.6.7 (and later) and has a few code improvements, most of them courtesy of MikeM:
  • created a display abstraction layer that will allow porting the display functions away from HT1632 Sure displays, eventually; essentially, any new "compatible" (min 16x32 resolution) display can be supported by implementing the set of functions declared in DisplayBase.h; currently, the HT1632 functions are defined in DisplayHT1632.cpp class;
  • eliminated the need to set the day-of-week, which is now calculated from date (Zeller method);
  • introduced the option to use MiniGPS class instead of TinyGPS, which saves some program memory and also RAM; the improved GPS code uses now a new setting in messages.txt (utc.offset);
  • some bug fixes related to buffer overruns when getting the weather RSS data; Mike discovered this issue after switching to a new weather service (, since the old one (e.g. is no longer supported (protocol was changed to https, which cannot be handled by the current ESP8266 class);
As a reminder note (for myself), the ESP8266 and GPS-related changes mentioned above should also find their way into the WiFiChron code, sometime.

Recently, Nick sent this photo of his stack (stash?) of WiFiChrons.

Saturday, February 23, 2019

Mondrian clock software release

Unbelievably, there is still demand for the Dual LED matrix shield for Arduino, which also pressures me to maintain and upgrade the supporting software, usually on client's request.
And that is how the Mondrian clock got a couple of new display modes: one picked directly from the Cube clock, showing just hours and minutes, the other one an improvement of the same, with the addition of a red dot moving around the rectangular clock face to indicate the seconds.
The display mode changes when both buttons are pressed simultaneously.

Here is the clock in action.

The Mondrian clock uses the Dual LED matrix shield and wsduino (as an RTC-equipped and XBee-supporting Arduino-compatible).
The code is available here. There is no GPS support, but that can be copied and adapted from the previous version of Mondrian software.

Note that the LED matrix shield was designed to accommodate either the common-anode or the common-cathode LED matrices, by soldering the correct LED driver, either A2982 or ULN2803 respectively. In the software, use either one of these defines:
#define _COMMON_ANODE_
//#define _COMMON_CATHODE_

The only user interface on the shield is the pair of buttons. Pressing the left one will increment the hours, the right one will increment the minutes, while the seconds are always reset.
By pressing both buttons at once, the display mode cycles through Mondrian mode (red hours, green minutes, orange seconds), 24-hour mode (HH:MM in green), 12-hour mode (HH:MM in orange), and moving second red dot (12-hour, HH:MM in green, more square font).

Saturday, August 11, 2018

Display Abstraction Layer

"Software never dies", the saying goes. But to help that happen, the software should be as independent as possible from the hardware it uses. Today, we are getting closer to this goal by introducing the Display Abstraction Layer (DAL), a simple framework that allows displaying on any suitable device. The implementation is based on polymorphism: using a virtual class when writing to the display, but instantiating a concrete display class depending on the device being written to. Each device requires its own concrete class that implements a set of functions (defined in the virtual class) used for outputting to the display. Thus every concrete display class becomes a simple “device driver” for the specific display device that was written for.

A class diagram of the DAL framework is shown below.

This is nothing revolutionary, just a simple solution that should have been there (in projects using displays) from the beginning. It provides an easy adaptation between the project functionality and the display, and also reduces the porting effort to just implementing a class for the new display.

The DAL interface consists of a set of function definitions used to output to the display. This set of functions depends on the project. That means that the DAL interface for WiFiChron will be different from the one for WiseClock. For example, in the case of WiFiChron, there are only 4 functions dealing with the display that need to be implemented:

    void setup();
    void writeDisplay (char* displayBuffer);
    void setBrightness(uint8_t brightness);
    void reset();

WiseClock uses a lot more display functions (currently defined in HT1632.h):

  void setup();
  void clear();
  void setBrightness(byte level);
  void snapshot_shadowram();
  byte get_snapshotram   (coord_t x, int8_t y);
  byte get_shadowram     (coord_t x, int8_t y);
  void clearSnapshot     ();
  void clearSnapshot     (int8_t dispNo = 0);
  void copyToVideo       (byte chipNo, char* vbuffer);
  void overlayWithSnapshotHorizontal(int8_t y);
  void overlayWithSnapshotVertical  (coord_t x);
  void plot         (coord_t x, int8_t y, byte color);
  void line         (coord_t x1, int8_t y1, coord_t x2, int8_t y2, byte val);
  void putChar      (coord_t x, int8_t y, char c, byte color);
  void putTinyChar  (coord_t x, int8_t y, char c, byte color);
  coord_t       putLargeChar (coord_t x, int8_t y, char c, byte color);
  void putBigDigit  (coord_t x, int8_t y, int8_t digit, int8_t fontNbr, byte color, int8_t columns);
  void putFullDigit (coord_t x, int8_t y, uint8_t digit, byte color, byte fontNumber=0);
  void putBitmap    (coord_t x, int8_t y, byte indexBmp, byte color=ORANGE);
  void putString    (coord_t x, int8_t y, const char* str, byte color);
  void putTinyString(coord_t x, int8_t y, const char* str, byte color);
  void displayStaticLine  (char* text, int8_t y, byte color);
  void displayStaticLine_P(const char* text, int8_t y, byte color);

Currently, I have implemented and tested a bunch of DAL classes for HDSPwise clock (the simpler version of WiFiChron). These include support for HDSP2534, DL1414, OLED (128x64). The common characteristic of these displays, that makes them suitable for the HDSP clock/WiFiChron, is that all of them can display 8 characters that can then be scrolled horizontally.

DAL for WiseClock would require implementing the above functions for a graphic display with a resolution of at least 32x16 pixels. Also, this graphic display should need no more than 4 control wires (hardware limitation of WiseClock4 board). So, if you wish to replace the 3216 display (not available from Sure Electronics anymore), a suitable candidate would be a TV (through the TV pixel library) or even an 128x64 I2C OLED. Keep in mind that controlling the 16x32 LED displays that use shift registers (either monochrome or RGB) requires more than 4 wires. Their support by Wise Clock 4 would need hardware changes, probably the insertion of a controller (e.g. HT1632, HT16K33 etc).

Sunday, June 24, 2018

WiFiChron adapter for DL-1414 displays

WiFiChron has now support for the obsolete (?) DL-1414 displays. I know, the question everybody is probably asking is "why bother?" The immediate answer is because these displays are cheap and easy to find (on ebay or Chinese electronics suppliers), compared to the HDSP-2534. I actually got a few as a gift from Mr. Kin, thank you very much!

DL-1414 is a 4-character 16-segment parallel intelligent display, the grandfather of HDSP-2534: put an ASCII code on the data lines, then flick the WR line, and there you have it, a character displayed at the position specified by A0 and A1 bits. It really does not get any simpler than this. The character set definition, also similar HDSP-2534 (only defines upper case letters though) is stored internally, so there is no need to manipulate any of the 16 segments individually. Although the magnifiers ("bubbles") make them look somehow like QDSP-6064, the DL-1414 display is much smarter, and therefore much easier to interface and program.

Below are some photos of the prototype adapter for the HDSP clock horizontal mod (more of them shown here).

The adapter PCB I designed is available from oshpark (not tested though).

Note that the DL-1414 display is higher, so it won't fit in the Serpac A20 enclosure, but it will fit in the Serpac A21.

Adapting the HDSP/WiFiChron code was super easy. The only functions requiring change are writeChar(...) and writeDisplay(). The next images show these 2 functions side by side, for DL-1414 (left) and HDSP-2534 (right):

Note that the 2 chips share the D0-D6 and A0-A1 lines, but WR lines are separate, which allows individual control of each chip.

In the end, the DL-1414 offers the same functionality as HDSP-2534, at a lower cost, but also with less visibility (characters are about half the size) and less coolness (harsher "font", no lower case).

The DL-1414 experiment opened the door for future WiFiChron displays. Essentially, any 8-character display can be adapted by modifying the two above mentioned functions. This will be next. Stay tuned.