Sunday, September 29, 2013

Play Tetris on Wise Clock 4

No kidding.
I was looking for a suitable application to demo with Wise Clock 4 placed vertically (that is, standing on its shortest side), when I found this hackaday post about Tetris on a LED matrix. The code, already written for Arduino, clean and easy to understand (kudos to Jianan), was a breeze to port. I only had to change a few functions (display, user buttons), comment out a few more (sound, text etc) and downsize from 7 colors to just 3.
Commands come from Bluetooth terminal ("BlueTerm" app on Android), basically replacing the buttons with letters (U, R, L, D; you got the idea).


The Wise Clock 4 vertical stand is possible thanks to the enclosure-mounted power jack, wired to the display's screw terminals, as shown in the photo below (that also captures a part of my messy desk).



(This is a typical example of how one thing leads to another. I don't usually play games, but when I do, I use my implementations. "Time well wasted", as the saying goes.)

Thursday, September 26, 2013

New release of Wise Clock 4 software

Some of the latest software features have already been introduced (see this post). Since then, a few bugs have been fixed (again, thanks Mike!), the code was streamlined even more, and some apps (Countdown, Score, Stopwatch, Quote) have been expanded and improved.

Below is a list of the most recent code changes:
  • added PWRON setup option to select app to run when the clock starts up;
  • compilations options (add/remove features) moved to file "UserConf.h". That is:
- Instead of editing WiseClock.cpp to select applications to build, edit "UserConf.h".
- Instead of editing WiseClockVer.h to select WiseClock 3 or 4, edit "UserConf.h".
- Instead of editing HT1632.h to select the number of displays, edit "UserConf.h".
  • on dual display, Countdown includes days as well, in the format DD:HH:MM:SS;
  • Countdown shows the correct amount of time left even if power was down for a while (this is done by saving the end time in eeprom); for this feature, the PWRON must be set to "CNTDWN";
  • similar to Countdown, app Score has been extended to "remember" the numbers even after the power was out for a while; in either case, the respective app must be selected in PWRON;
  • ability to display quotes randomly, if the user selects "RND" in app Quote;
  • on dual display, Stopwatch is now using regular-size font (still using tiny font on single display);
  • Stopwatch has a new mode, "Conventional", in addition to the previous one (called "Rattrapante"); the conventional mode accumulates the time passed between consecutive presses of the start/stop button, as a mechanical chronometer would do; "rattrapante" mode shows the amount of time passed from the moment it was first started, regardless of how many times the chronometer was stopped;
  • on dual display, with "Font+" selected, Score and Stopwatch are using big font and no longer show the current time on the bottom line (they show as before with "Font-" selected); 

One of the challenges in writing complex code for embedded systems is the compromise between following an Object Oriented approach and trying to minimize the amount of RAM at runtime. Let me elaborate a bit. Each C++ object, once created (at runtime), used or not, takes some RAM, storing data members and the vtable (when using virtual functions). Wise Clock software is trying to follow an OO design. Each App class is derived from an abstract base class. The base class defines 2 pure virtual functions (init and run), which must be implemented by every App class.
At runtime, each app is created as a static object. Therefore, if 12 apps are declared (through the use of ifdefs in UserConf.h), 12 objects will be created in RAM, each one storing its own data and its own vtable. That's a pretty big price to pay in the world of embedded systems with little RAM space (just a guess, based on my very limited experience).

A non OO approach would create and use variables only for the app that is in current use, as the code is being executed. Although this solution would use less RAM, the current complexity would make the code unmanageable.

So back to the compromise, how does one solve it? (This is not a rhetorical question.)

Wednesday, September 18, 2013

Mechanical Design and Engineering

I was having a conversation with my friend JohnW, a Mechanical Engineer by education and trade, about his latest "small" project. I suggested he should publish and document aspects of his interesting work. But he mentioned he does not have a blog just yet, so I "volunteered" to do it for him right here, as a quick (and hopefully useful) example.

John designed a portable agitator, a device used for mixing low-viscosity liquids or liquids with small-size solids.
Mixing is performed by a propeller driven by an internal pneumatic system, and not using an electrical motor, as shown in the diagram below.


The whole contraption is made of plastic, calculated for a maximum internal pressure of 80 psi.
The liquids are poured in manually, through PRV-07 (features a screw-in lid). The mixed liquid is released through the pinch-valve PRV-06. The lid PRV-01 can be removed (8 screws) for inside cleaning.

The mixing capacity is 1 gallon, but it can be easily scaled, in both dimensions and power.

This agitator was designed to be safely used in the food, pharmaceutical, chemical industries.

Here is a photo of the agitator built to specs.


If anyone is interested in this kind of engineering work, I will be glad to re-direct them to him. John is versatile, works on tight budgets and schedules, and very proficient in Autocad, Inventor etc.

Monday, September 16, 2013

More open source VFD clocks

I just finished assembling the latest version of akafugu VFD clock, the "MK2". Per, from akafugu, generously sent me the board for testing/review. It comes will all SMD components pre-soldered, and the processor pre-programmed. The rest of the components, all through-hole, I sourced on my own.
Here is a photo of the kit as I put it together (I forgot to include the through-hole resistors though).



Assembling was straightforward thanks to the combination of good board design and easy-to-follow instructions. The result is shown in the photo below.



MK2 has some improvements over version 1:
- newer processor (Atmega32U4, as the one used in Leonardo);
- 5V power source (vs 9V previously);
- direct sketch upload from Arduino IDE (no hacking required);
- integrated support (on-board 24LC256 eeprom) for four-letter-word feature;
- all SMD parts (quite a few actually) come pre-soldered;
- directly compatible with the existing (version 1) VFD display shields;
- better clearance with the VFD display shield (because parts are shorter in height).

In conclusion, MK2 is another winner for akafugu.


I also recently assembled the Ice Tube clock from adafruit. I bought the PCB(s) a while ago (when they were still available for sale on adafruit site) and I sourced the parts on my own. I followed the legendary assembly instructions, but things did not go without a glitch for me. Here is what I learned in the process:
  • The Ice Tube clock is not Arduino-compatible as I initially thought (see here). It cannot be programmed from the Arduino IDE and it does not have an FTDI interface/connector. The processor (I used Atmega328, but ATmega168 should work with the base software too) uses the internal 8MHz oscillator and an external 32kHz crystal. This crystal, in conjunction with TIMER2 (see file iv.c), is the heart of the clock "mechanism". (More details on the design can be found here.)
  • The high voltage for the tube is produced with impulses generated from an output pin of the processor (instead of using an external chip, like may other designs). Therefore, high voltage is not there until the chip is correctly programmed.
  • Programming the chip was a bit of a challenge; I used the makefile to build the hex file from the source, but programmed the chip with avrdude directly, as shown in this screenshot (click for bigger picture).

  • IV-18 tubes bought on ebay, even when they are new (with the wire terminals intact) can be defective. Out of the 5 tubes I got, 4 had a blackened spot on the back and one had a white spot, as shown in the photo below. Guess which one did not work.

  • Inserting all 24 wire terminals of the IV-18 tube in their holes is a challenge. I would much rather prefer the solution adopted by akafugu in their VFD clock, with half terminal holes, opening in a big empty circle (as shown below, photo from akafugu).

  • IC sockets, particularly PLCC28, although bought from digikey, can be "defective". Unlike the DIP IC sockets which press each IC pin on two sides, the PLCC28 sockets actually press against the IC pins on one (external) side only. It took me many minutes to figure out that the tube was not lighting up because one socket pin was loose and did not make contact with the IC's pin.
  • MAX6921 VFD driver used in the Ice Tube clock is more than twice as expensive as HV5812 VFD driver used in MK2. Yet, adafruit's Ice Tube Clock is still the cheapest complete (including enclosure) VFD clock kit out there.

Overall, building the Ice Tube clock was a pleasant and rewarding experience, which I recommend to kit-builders at any level. This clock looks compact, sleek, stylish, and stands out in my clock collection.

Saturday, September 7, 2013

"Close enough" Wise Clock display mode

Inspired by this article, MikeM added the "Close enough" mode to the functionality of Wise Clock 4.
This new "face" is accessed by pressing the "Set" (middle) button inside the application "BIG".
The time is shown as an approximation, with the hours as an explicit number, the minutes filling the circle of  a 60-minutes clock and the passing seconds represented by a moving red dot on the bottom line. Thus, one can tell time with a 5-minutes "precision" at a very quick glance.



I will soon publish a new software release that will include this mode. It will also include some other changes I've done recently:
  • moved some "app" functionality out of the main class (WiseClock.cpp) into their own separate classes (AppDemo, AppPacman); will probably need to re-organize WiseClock.cpp, since it almost grew beyond a manageable size (currently at 103KB);
  • in dual-display mode (64x16 resolution), extended AppCountdown to include days in addition to hours: minutes:seconds;


Below is a clip of the countdown in action. The bottom line can show (subject to code change) either the current time (HH:MM::SS) or a static line as in the photo above.


For comparison, this is how the countdown looks on the single-display Wise Clock 4.


  • used (long overdue) proper C++ polymorphism (created CAppBase class with pure virtual functions) to simplify the calls to run() functions of each app class (which are now derived from the base class); essentially, most of the case branches in the switch statement are gone and replaced by a simple pCrtApp->run(), as shown in the code snippet below:

switch (crtApp)
{
case APP_TMP:
ms = runappTmp();
break;
case APP_NEWSD:
ms = runappNewSD();
break;
case APP_STATS:
ms = runappStats();
break;
case APP_SET_POWER_ON:
ms = runappSetPowerOn();
break;
default:// for all other apps;
ms = pCrtApp->run();
}