Sunday, June 26, 2011

June 2011 release of Wise Clock 3 software

Mr. Ruud van der P. graciously offered his skills and time to extend and improve the Wise Clock 3 software, for which I am grateful.
He also took the video below, showing some of the newly added features in action.




This June/2011 release of Wise Clock 3 software (download from here) includes these features and changes:
  • PacMan - this new menu entry will show PacMan every 60 seconds.
  • Brightness of the display can now be changed with the Set key.
  • Show seconds in some of the "BIG" modes.
  • Time color when alarm is set: 3 hours before the alarm goes off, the time is displayed in orange, 2 hours before the alarm goes off in red; otherwise, time is displayed in green.
  • Chime may be enabled, giving a short beep at the half hour and a double beep at the full hour.
  • Alarm sound - the alarm will now play "Frere Jacques" followed by a siren and can be stopped by any button.
  • Menu will no longer show entries which do not make sense, like DATE+ when the Date was already on.
  • Score - new menu entry to keep a score for 2 players from 0 - 99.
  • Colors are now used in the Life and Demo apps.
  • Temperature is now a bit more accurate (after warming up) and uses the degree symbol to display the temp both in Celsius and Fahrenheit. In order to quickly see if the temp is rising or falling it is displayed with 1 decimal.
  • Bug fix: the file manager for the memory card did not read the last sector of a file and did not always handle the EOF (03) character correctly. It is important that all files have a EOF (03) character at the end to prevent reading behind the end of the file.
  • Displaying reminders:
    • At startup and at midnight the message.txt file is scanned for any reminder for that new day.
    • An orange dot is displayed at the bottem during this scan
    • If a reminder is found then it will be displayed (like the quotes) for the next 24 hours
    • The message file may also contain the start and end date of the Daylight Saving Time period (DST), this will adjust the clock by 1 hour.
    • The personal Message is still contained in this message file but must now start with [M1] which will allow for more then 1 Personal Message in a future release.
    • See message.txt for more details and add your own reminders.

Related posts:

Tuesday, June 21, 2011

My impressions of Lunatik + iPod Nano

For my pledge for Lunatik on kickstarter, I got two different watch kits that can transform iPod Nanos into wrist watches. Here they are, in their original packages, as I received them. One is plastic (TikTok), the other, the cooler one, is aluminum (Lunatik), both with rubber straps.















One of my motivations for the pledge was to get a re-usable watch case. I still wishfully think that I can make DWex (or any future watch I may make, for that matter) in the form factor of a Nano, so it can be used with Lunatik or TikTok (or other iPod Nano case/wrist band for that matter). But until then, I am going to use it for its intended purpose.

I have been wearing the Lunatik watch for several months now, so I had enough time to form an opinion.
A few impressions that come to mind, in no particular order:
  • stunning design (I find it); sometimes I look at the watch without checking the time;
  • there is a (sometimes annoying, depending on my mood) delay between the touch of the screen and the moment the watch actually displays the time (waking up from sleep mode, in microcontroller speak); but this is a function of the iPod nano and not of the Lunatik;
  • the free end of the rubber strap sometimes pops up from the metal "strap keeper" rather easily (especially when accidentally touching the desk, for example);
  • when new, the rubber strap has a strong odor; it goes away after a couple of days;
  • when used only as watch, iPod Nano would require charging just once a week.

Overall, I am very pleased with my Lunatik watch. As everybody knows, iPod Nano is more than a watch. I am actually carrying a small computer on my wrist. It definitely attracts attention :)



















The problem with any iPod/iPad-related gadget is that they will eventually get thrown away with the iPods/iPads themselves. There is little chance that the gadget will fit a newer generation of the Apple product, so there is little chance that it can be re-used. That is, don't expect Lunatik to fit the next generation of iPod Nano, 'cause it probably won't. Well, good for the manufacturer, not so good for the consumer. Still, Lunatik will make a nice conversation piece even when it will be on display in the "personal museum".

Friday, June 17, 2011

North Carolina Maker Faire Preview

Justin just sent this photo from North Carolina Maker Faire, happening this weekend (June 18-19, 2011), with lots of clocks, some bigger, some smaller.


















And here is an instructable on how to assemble C3Jr, available for sale as a kit here.
Vote here for your favorite project in the LED contest.

Monday, June 13, 2011

How to define bitmaps and fonts

This piece of knowledge is especially useful for understanding and hacking the Wise Clock 3 software, but can  be also applied to any software that deals with pixel manipulation.

To define a small bitmap, start from a grid/matrix on paper (see photo below). Each square of the matrix will represent a pixel. Blacken the squares until the matrix resembles your bitmap. Next step is to translate the content of the matrix to numbers.



















Let's take a closer look at the example below, a bitmap of 5x5 pixels.


















This translates into an array of 5 numbers, one number per line. Each number is calculated by adding the values (at the top) of the selected columns.
So, the number for the first line is 14 (2 + 4 + 8), second number is 21 (1 + 4 + 16) and so on.
For the binary oriented fellows :), the hex values are between brackets.

Let's now jump to the actual code. The bitmap definition will look like this:


byte PROGMEM smallBitmap[3][5] = {
  {
    0x0E,    // _XXX_
    0x15,    // X_X_X
    0x1F,    // XXXXX
    0x1F,    // XXXXX
    0x15,    // X_X_X
  },
...
}


The above piece of code declares a two-dimensional ("[3][5]") array of bytes, in program space ("PROGMEM"). The first dimension ("3") represents the number of defined bitmaps. The second dimension ("5") represents the number of lines in each bitmap. A line in the bitmap definition is referenced using values for both dimensions. For example smallBitmap[0][4] is 0x15 and represents the last (index 4) line of the first (index 0) bitmap. [Note that array indexes start with 0, that is, first element in an array has index 0.]

Similarly, snippets of font definitions are shown below:


// define all ascii characters starting with 32 (blank);
unsigned char PROGMEM myfont[95][8] = {
  {
    0x00,    // ________   blank (ascii 32)
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00     // ________
  },
  {
    0x00,    // ________  !
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x00,    // ________
    0x08,    // ____X___
    0x00,    // ________
  },
...
  {
    0x00,    // ________  0
    0x1C,    // ___XXX__
    0x26,    // __X__XX_
    0x26,    // __X__XX_
    0x26,    // __X__XX_
    0x26,    // __X__XX_
    0x1C,    // ___XXX__
    0x00,    // ________
  },
  {
    0x00,    // ________  1
    0x0C,    // ____XX__
    0x1C,    // ___XXX__
    0x0C,    // ____XX__
    0x0C,    // ____XX__
    0x0C,    // ____XX__
    0x1E,    // ___XXXX_
    0x00,    // ________
  },
  {
    0x00,    // ________  2
    0x1C,    // ___XXX__
    0x26,    // __X__XX_
    0x0C,    // ____XX__
    0x18,    // ___XX___
    0x30,    // __XX____
    0x3E,    // __XXXXX_
    0x00,    // ________
  },
  {
    0x00,    // ________  3
    0x3E,    // __XXXXX_
    0x06,    // _____XX_
    0x1C,    // ___XXX__
    0x06,    // _____XX_
    0x26,    // __X__XX_
    0x1C,    // ___XXX__
    0x00,    // ________
  },
...
}


The data structure "myfont" above is an array of 95 character-bitmaps, each bitmap having 8 lines and 6 columns.

Bigger bitmaps, those having more than 8 columns, require more than a byte for each line.
Take a look at the definition of the Pacman bitmaps below.


uint16_t PROGMEM bitmap[7][14] = {
  {
    0x02E0,    // ____XXXXX_____
    0x0FF8,    // __XXXXXXXXX___
    0x07FC,    // ___XXXXXXXXX__
    0x03FC,    // ____XXXXXXXX__
    0x01FE,    // _____XXXXXXXX_
    0x00FE,    // ______XXXXXXX_
    0x007E,    // _______XXXXXX_
    0x007E,    // _______XXXXXX_
    0x00FE,    // ______XXXXXXX_
    0x01FE,    // _____XXXXXXXX_
    0x03FC,    // ____XXXXXXXX__
    0x07FC,    // ___XXXXXXXXX__
    0x0FF8,    // __XXXXXXXXX___
    0x02E0,    // ___XXXXX______
  },
  {
    0x03E0,    // ____XXXXX_____
    0x0FF8,    // __XXXXXXXXX___
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x07FE,    // ___XXXXXXXXXX_
    0x01FE,    // _____XXXXXXXX_
    0x007E,    // _______XXXXXX_
    0x007E,    // _______XXXXXX_
    0x01FE,    // _____XXXXXXXX_
    0x07FE,    // ___XXXXXXXXXX_
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x0FF8,    // __XXXXXXXXX___
    0x03E0,    // ____XXXXX_____
  },
  {
    0x03E0,    // ____XXXXX_____
    0x0FF8,    // __XXXXXXXXX___
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x3FFE,    // XXXXXXXXXXXXX_
    0x07FE,    // ___XXXXXXXXXX_
    0x00FE,    // ______XXXXXXX_
    0x00FE,    // ______XXXXXXX_
    0x07FE,    // ___XXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x0FF8,    // __XXXXXXXXX___
    0x03E0,    // ____XXXXX_____
  },
  {
    0x03E0,    // ____XXXXX_____
    0x0FF8,    // __XXXXXXXXX___
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x3FFE,    // XXXXXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x3FFE,    // XXXXXXXXXXXXX_
    0x1FFC,    // _XXXXXXXXXXX__
    0x1FFC,    // _XXXXXXXXXXX__
    0x0FF8,    // __XXXXXXXXX___
    0x03E0,    // ____XXXXX_____
  },
...
};

And this is the function that uses the actual Pacman bitmaps defined above.

/************************
 * load and display a given bitmap (defined in bitmaps.h);
 */
void putBitmap(int x, int y, byte nBmp, byte color)
{
  for (byte row=0; row < 14; row++)
  {
    uint16_t rowDots = pgm_read_word_near(&bitmap[nBmp][row]);
    for (byte col=0; col<14; col++)
    {
      if (rowDots & (1<<(13-col)))
        ht1632_plot(x+col, y+row, color);
      else
        ht1632_plot(x+col, y+row, BLACK);
    }
}

Now you should be all set to start your own animation (which is just a sequence of bitmaps).


Saturday, June 11, 2011

Pacman mode on Wise Clock 3

This display mode shows the time with seconds. To add some spice, Pacman passes by once a minute, when the minutes are about to change.












The animation is based on a short sequence of bitmaps (only monochrome at the moment) loaded from program memory.



The latest code will be released soon, and will include new features courtesy of fellow Arduino-er Ruud. Stay tuned.


Related posts: