Thursday, January 30, 2014

Vacuum Fluorescent Display Alarm Clock

I have been working on this fun little project for the last couple of days. I ordered this VFD display from Noritake as a free sample. I am quite grateful for their generosity and I decided to put this display to good use.

I have written a driver in C# that implements a partial selection of the commands available from this display. The driver is object-oriented with property accessors used to set configuration parameters of the display.

Weather Data, Emails and a Loader Animation :]
I put all of this together into a sample application for a smart alarm clock that I would like to build eventually. The sample application gets my unread e-mail from Gmail and weather data from Open Weather Map. I am also attacking the 16 custom characters that reside in ram to display a few simple animations.

The Hardware


The hardware is quite simple for this article. I have a USB to RS232 converter. This display accepts RS232C levels so you cannot use the UART of a microcontroller directly without using a transistor to invert the signal.

Hardware Overview 
The display itself is the CU24063-Y100 model from Noritake. I don't know a whole lot about the theory of operation behind these displays, but it is a vacuum sealed type device. It has a "getter" on the front glass to catch any impurities during the sealing process. It also contains a heater that is visible during very low-light conditions.

Display Front
This display uses a microcontroller to implement the command set. It is from the Renesas R8C lineup, a very simple and interesting processor. I will likely order some this summer to experiment with. These processors implement numerous security features including read/write protected flash pages and a 2^56 complexity key for reprogramming. Quite impressive if you ask me. Given a baud rate of 500000bps, it would take a few hundred years to brute force these devices. Not to mention the fact that you need to reset the chip after each attempt.

Thankfully, Noritake left a nice hole in their protocol that let me read out the firmware contents. This is a story for another blog post (maybe :]).

Display Back

The Driver


The first thing I did was develop a subset of the commands into a clean object-oriented driver. I created a GitHub repo to share the code with anyone who wishes to drive this display. It is tested on Mono, but I can't see any reason why this wouldn't work on Microsoft's implementation. Submit an issue on GitHub if you encounter any issues and I can fire up my Windows virtual machine and debug it.

I will give you a quick taste of the code here but you can see the rest on GitHub. Here is the constructor that initializes a serial port and configures it for the default baud rate of the device. Note the optional parameter that would allow you to override it.
/// <summary>
/// Initializes a new instance of the
/// <see cref="TheResistorNetwork.VfdDriver.VdfDisplay"> class.
/// </summary>
/// <param name="serialPort" />Serial port.
/// <param name="baudRate" />Baud rate.
public VdfDisplay (string serialPort, int baudRate = 38400)
{
 this.serialPort = new SerialPort ();
 this.serialPort.PortName = serialPort;
 this.serialPort.BaudRate = baudRate;
 this.serialPort.StopBits = StopBits.One;
 this.serialPort.Parity = Parity.None;
 this.serialPort.Handshake = Handshake.None;
 this.serialPort.Open ();

 displayMode = VfdDisplayMode.Flickerless;
 brightness = VfdBrightness.Percent200;
 blinkMode = VfdBlinkMode.Off;
 cursorMode = VfdCursorMode.Underline;
 customCharacterMode = VfdCustomCharacterMode.Disabled;
}
This driver is for the 24x6 character display. I only have the one display from this company so I didn't bother abstracting it as an IVfdDisplay or anything like that.

I have modelled the cursor mode using an enum that extends byte.
public enum VfdCursorMode : byte
{
 Underline = 0x13,
 Off = 0x14,
 Block = 0x15,
 UnderlineBlink = 0x16
}
This allows me to cast it directly to a byte and send it to the device during a property assignment.
/// <summary>
/// Gets or sets the cursor mode.
/// </summary>
/// <value>The cursor mode.</value>
public VfdCursorMode CursorMode
{
 get {
  return cursorMode;
 }

 set {
  cursorMode = value;

  var cmd = new byte[] { (byte)cursorMode };
  serialPort.Write(cmd, 0, cmd.Length);

  Thread.Sleep (1);
 }
}
This should be enough to give you an idea of what is going on in this driver. Feel free to fork the repo on GitHub if you wish to implement the rest of the commands. I will be more than willing to review your code and merge it in!

The Sample Application


I consumed my driver in a sample application that fetches e-mails, weather data, date/time and animations. This code is far from pretty, but it works. Here is a link to the GitHub repo for you to peek at. There are probably hundreds of ways that I could have done this better.

As an example, I could have created a TextScroller class that scrolls text at any location on the screen with a configurable width. At the moment, it is a mess of hard-coded constants.

Spinning Globe Animation with no Unread Email
It takes a few moments to initialize as it downloads contents from Open Weather API and Gmail.

Spinning Envelope with Unread Email
So there you have it! My VFD driver and sample application. Thanks for reading!

No comments :

Post a Comment

Note: Only a member of this blog may post a comment.