Friday, July 3, 2015

Wiseduino Next Generation

You have a "tube shield" like the Axiris IV3 shield or the Nixie shield and you want to make a clock. You will definitely need an Arduino. You can either program it to (roughly) count the seconds, minutes, hours, or you can add an extra RTC, specialized in (accurate) time keeping, and program your Arduino to just get the time from RTC. The latter is Wiseduino, the first board I ever designed (also discontinued a long time ago). I badly needed one to finish the Axiris IV3 clock, since neither the software solution (second-counting) nor the hardware solution (adding a second RTC shield) was suitable. And so I re-designed it, improved on existing features (power, RTC) and added new ones (support for XBee/BTBee/GPSBee). This new version, spelled "wsduino" (but still pronounced "wiseduino") is shown below, next to the Axiris IV3 shield.


The wsduino board has an Arduino-compatible footprint, so it fits perfectly in the Axiris-designed-and-made enclosure (which I got as a gift from Nick :).


As you notice from the photo, the crystal is optional. Lately, I prefer to run the ATmega328 processor with the internal oscillator at 8MHz. The fewer the parts, the fewer the points of failure (and also cheaper). The wsduino board can be powered from either the USB miniB connector, or from the barrel connector, through a 7805 voltage regulator, selectable with a jumper. The board also has a 500mA 3V3 regulator, soldered on the bottom.

The DS3231 RTC is also soldered on the bottom. An XBee-footprinted serial device is connected to Rx/Tx of ATmega328, with voltage-divider level-shifting for Tx (pin D1). For the Axiris clock, I used the BTBee as a way to set the time and date, since the enclosure was not designed with buttons in mind. The sketch can be found here.


The photo below shows a couple of wsduino bare boards, top and bottom.


wsduino kit can be purchased here.

Wednesday, June 24, 2015

WiFiChron fix and other WiFis

The peculiar feature of the "May 2015" revision of WiFiChron board is that it was designed to use software serial to communicate with either the XBee or ESP module. The reason is related to debugging. I wanted to be able to send messages to the serial monitor while (software serially) communicating with the serial device. This solution works well for XBee (GPSBee, BTBee), but not for ESP8266, only because the software takes more than the available 2K of RAM in this case (WiFi + software serial).

The immediate fix to use the ESP module is to connect its Rx/Tx lines to Rx/Tx of the processor. The existing connections can be left uncut, since they are not used in the sketch for ESP8266. The wiring should be like in the photo below.


The "permanent" fix would be re-designing the board to use ATmega1284 SMD (DIP-40 would not fit).

Talking about 1284, take a look at Farit's WiseClock4 mod. He used the WiseClock4 board, but completely re-wrote the software, including, it seems, the definition of new fonts. The SD card is now used for storing MIDI files (among others) that can play tunes through the Fluxamasynth shield.


A few of the other hardware and software features are:
  • WiFi access to the internet through WiFly module;
  • accurate time keeping through NTP;
  • display weather forecast read from the web;
  • daily alarms;
  • automatic adjustment of the display brightness with light sensor;
  • user-selectable display color.
The exquisite and elaborate wooden enclosure adds even more character.

And a photo of the internals, with the extra hardware:



Farit also shared the software he wrote, hopefully an inspiration for future mods.

Thursday, June 11, 2015

Prototype 14-segment-display shield

Update Apr 14, 2019: The kit for this shield can be ordered here.

There are many ways (*) to drive the 6-digit 14-segment common cathode display from Seeed Studio.
This time I chose to multiplex two MAX7221, a method described here (but used for driving a bi-color 8x8 LED matrix).


The code is based on LedControl library, which I extended to cover the definition and display of 14-segment characters (digits, upper case letters, and a few specials). Below is a relevant fragment of the code I added:

/*
* Segment names in the 14-segment (plus DP) display:
*
*     -     A
*   |\|/|   F,I,J,K,B
*    - -    G,H
*   |/|\|   E,N,M,L,C
*     -  .  D,P
*/
// my wiring:
//            GFEDCBAx
// 1st byte: B11111111
//
//            NHJIKMLP
// 2nd byte: B11111111

const static byte charTable14Seg[43][2] = {
    {B01111110,B10001000},  // 0
    {B00001100,B00001000},  // 1
    {B10110110,B01000000},  // 2
    {B00011110,B01000000},  // 3
    {B11001100,B01000000},  // 4
    {B11010010,B00000010},  // 5
    {B11111010,B01000000},  // 6
    {B00000010,B00001100},  // 7
    {B11111110,B01000000},  // 8
    {B11011110,B01000000},  // 9
    {B00000000,B01000000},  // :
    {B00000000,B01000000},  // ;
    {B00000000,B01000000},  // <
    {B00000000,B01000000},  // =
    {B00000000,B01000000},  // >
    {B00000000,B01000000},  // ?
    {B00000000,B01000000},  // @
    {B11101110,B01000000},  // A
    {B00011110,B01100100},  // B
    {B01110010,B00000000},  // C
    {B00011110,B00100100},  // D
    {B11110010,B01000000},  // E
    {B11100010,B01000000},  // F
    {B01111010,B01000000},  // G
    {B11101100,B01000000},  // H
    {B00000000,B00100100},  // I
    {B00111100,B00000000},  // J
    {B11100000,B00001010},  // K
    {B01110000,B00000000},  // L
    {B01101100,B00011000},  // M
    {B01101100,B000100L0},  // N
    {B01111110,B00000000},  // 0
    {B11100110,B01000000},  // P
    {B01111110,B00000010},  // Q
    {B11100110,B01000010},  // R
    {B11011010,B01000000},  // S
    {B00000010,B00100100},  // T
    {B01111100,B00000000},  // U
    {B01100000,B10001000},  // V
    {B01101100,B10000010},  // W
    {B00000000,B10011010},  // X
    {B00000000,B00011100},  // Y
    {B00010010,B10001000},  // Z
};
...
void setChar14Seg(byte pos, byte ascii)
{
  if (pos>7)
    return;

  if (ascii>90 || ascii<48)
    return;

  byte index = ascii - 48;
  for(byte seg=0; seg < 8; seg++)
  {
    SetLed(SEG_AG, pos, seg, charTable14Seg[index][0] & 1 << seg);
    SetLed(SEG_GN, pos, seg, charTable14Seg[index][1] & 1 << seg);
  }
}

This method (hardware and software) can be used for up to 8 14/16-segment displays.


(*) Should be the topic of a future post.


Monday, May 18, 2015

Ideas

First off, a new adapter for the WiFiChron or HDSP clock. The 8-LED Neopixel stick from adafruit has the perfect dimensions to fit them. Naturally, the time is displayed in color code. The best definitions for the 10 colors I could come up with are these:

byte color[10][3] =
{
  {0,0,0}      /*black*/,
  {30,9,0}     /*brown*/,
  {100,0,0}    /*red*/,
  {128,60,0}   /*orange*/,
  {110,120,0}  /*yellow*/,
  {0,64,0}     /*green*/,
  {0,0,111}    /*blue*/,
  {64,0,63}    /*violet*/,
  {15,15,15}   /*grey*/,
  {127,127,127}/*white*/
};

The clock code is trivial, especially because it's using the great Neopixel library. Below is the most important function:

void displayTime()
{
  byte digit1 = hour/10;
  byte digit2 = hour%10;
  
  strip.setPixelColor(0, strip.Color(color[digit1][0], color[digit1][1], color[digit1][2]));
  strip.setPixelColor(1, strip.Color(color[digit2][0], color[digit2][1], color[digit2][2]));

  digit1 = minute/10;
  digit2 = minute%10;

  strip.setPixelColor(3, strip.Color(color[digit1][0], color[digit1][1], color[digit1][2]));
  strip.setPixelColor(4, strip.Color(color[digit2][0], color[digit2][1], color[digit2][2]));

  digit1 = second/10;
  digit2 = second%10;
  
  strip.setPixelColor(6, strip.Color(color[digit1][0], color[digit1][1], color[digit1][2]));
  strip.setPixelColor(7, strip.Color(color[digit2][0], color[digit2][1], color[digit2][2]));
    
  strip.show();
}

The video I took of the clock in action is, for the lack of a better word, of too little value :), mainly because my camera doesn't seem to distinguish the colors as well as my eyes.

Even though this photo sucks, I added it only as proof :)


The time is shown as "HH MM SS", with spaces between hours, minutes and seconds. 0 is represented by an unlit (off) pixel. It is easy to get used to the colors, with help from the changing seconds.

Note that the 595 shift register on the board is not used (could even be removed, or not mounted at all).

Secondly, here is how one can save $20 on WiFiChron with GPS: use the $12 ublox instead of the $32 GPSBee. Some minimal wiring is required though, to connect 3 lines (5V, Gnd and Rx) to the module. Luckily, the GPS module has the right dimensions to fit in the spot for XBee (without the 2 headers mounted, nor the 74HC125, which is not needed in this case anyway).


If you really want everything to fit in the Serpac A20 box, you need to replace the original antenna with a smaller one (but working just fine), as shown in the next photo.


Thirdly, Craig (thanks very much!) published on thingiverse the plans for a 3D-printed enclosure he designed for Wise Clock 4:


Saturday, April 4, 2015

"Home-made", Wise Clock-based, Alpha Clock Five

I saw Justin's recent post on Alpha Clock Five and I just couldn't resist not to try it myself too. Since I didn't have that clock, I thought of improvising one by making a 5-character display that would plug into my Wise Clock 4 board. The idea was easy, the implementation not so. After many hours of hand-wiring, this is how it looks like.


The displays are 1" single digit alphanumeric (common anode) from sparkfun, now retired. They came with non-functional dots, probably the reason they were less than $2 each.
The spacing between the individual displays is forced by the protoboard.


The 2 boards are connected through the pairs of 2x8 headers. All pins used by Alpha Clock 5 to drive the displays are wired to the unused header on the Wise Clock 4 board.


Not to mention  that the software compilation and upload worked without any glitch (after downloading the very nice DS1307RTC library)

The only regret is that this clock lacks seconds. One extra display would have added lots of extra value, but probably lacked the cool factor (the "6-letter clock" requires a lot more memory to store all 6-letter words than the approx 50k required by the 5-letter-word collection).

You should try this at home :)