The BetaBrite is fully programmable via the infrared remote, but keying in long messages on the remote is a giant pain. It's a lot easier to connect the BetaBrite to your PC through a RS-232 Serial to RJ-12 cable, then use the bundled Windows software to program the sign:

The Windows software works fine, but what I really wanted was a native .NET API. So, armed with the protocol document and a functioning BetaBrite connection, I set out to write an easy to use .NET API for the BetaBrite.

Understanding the BetaBrite LED Sign

The BetaBrite understands a subset of the Alpha Sign Communications Protocol. We're talking about RS-232 serial communications to a device with a whopping 32 kilobytes of internal memory-- not exactly a supercomputer. So, as you might expect, the protocol is a little primitive and sometimes confusing. I spent the last week poring over the documentation; here's what I found:

BetaBrite only understands version 1.0 of the Alpha protocol

Anything in the Alpha Protocol Documentation referring to 2.0 or 3.0 features won't apply to the BetaBrite. Some of these are obvious, such as multiple line commands-- the BetaBrite only has one line-- and some are less obvious.

All communications are in a standard packet format

The sign communicates with the PC via a RS-232 serial port connection at 9600,N,8,1. All of the messages sent to the sign will be in a standard packet format:

To simplify communications, all messages are sent in plain-text ASCII, with no unprintable high-bit ASCII characters. If high-bit ASCII is needed, it is encoded in a double-byte format as you'll see later.

The sign stores "files" in slots labeled by a single ASCII character

Any ASCII character from 20h (space) to 7Eh (1/2 space) is valid as a file label, and you can allocate any combination of file labels up to the 32 kilobyte internal memory limit of the sign. Note that file label "0" is a so-called "priority label" and is treated a little differently, but other than that, they're all just named file labels for storing either Text, a String, or a Picture.

All memory must be allocated in advance

I guess I've been spoiled by the automatic memory management and garbage collector of .NET, because this one took me a while to wrap my head around. Any time you program the sign, you must allocate all the memory you'll need in advance. Any attempt to allocate more memory later will destroy all the existing memory allocations! Be sure to allocate all the memory you'll need before writing anything to the sign. This isn't a big deal in practice, but it cannot be abstracted away, so you must be aware of it.

Architecture

Early on, I made the decision to implement the API as a set of three classes:

BetaBrite.Sign

This is the primary Public interface for the sign. It drives the Protocol and RS232 classes behind the scenes, so the user is protected from the complexities of both the Alpha Sign Communications Protocol and RS-232 serial communications. Here's a quick glance at it:

BetaBrite.Protocol

This Private class factory defines all the low-level commands necessary to talk to the sign, which can all be rendered to a byte stream via the ToBytes() method. Additionally, if you want to preview a "pretty printed" version of the command, you can call the overridden ToString() method for the command. All commands inherit from the BaseCommand class, which implements the standard Alpha packet format. The child commands must override the FormDataField method, which returns the string of text specific to that particular command class. The Sign.SetDateAndTime method illustrates how this works:

'''<summary>''' Sets the date and time on the sign to any arbitrary date/time
'''</summary>PublicSub SetDateAndTime(ByVal dt As DateTime)
Dim dc AsNew BetaBrite.Protocol.SetDateTimeCommand(dt)
If _IsDebug Then
Debug.Write(dc.ToString)
EndIf
Write(dc.ToBytes)
EndSub

Note that a few of the ProtocolEnums are exposed in the Sign methods -- for transitions and so forth -- as these are unavoidably determined by the underlying protocol.

BetaBrite.RS232

This Private class defines the communication method between the PC and the sign. It is almost completely Private, however, you still need to provide the Sign object with a comm port number. Internally, all Protocol commands are rendered into byte streams and automatically transported to the sign using Cory Smith'sDBComm class. It's unmodified, other than some header comments I added attributing it to Cory. I compiled this in so the entire BetaBrite DLL can be used as a standalone interface API with no other dependencies.

Using BetaBrite.Sign

As promised, this API is very simple to use. Here's the canonical "Hello, World" example -- assuming your BetaBrite is connected via the first serial port:

Now, this example cheats a bit because the Display() method is ultra-simple. This method can only display a single message (although it can be a very long message, up to 32 KB) as a result. In order to progress beyond "Hello World", I'll show examples of the three things you can show on a BetaBrite sign.

The Text item is the most frequently used, and represents formatted text followed by a transition state:

If you run this code, you should see three different messages, with different colors, fonts, and transitions between the messages. Pay attention to the explicit memory allocation-- be sure you allocate enough memory for your text plus the one or two bytes of formatting codes per tag. As you may have noticed, text message strings support a set of lightweight HTML-style formatting codes, which you can find in the Text Formatting region of the Protocol class: look for Protocol.ControlChars, Protocol.Color, Protocol.Font, Protocol.ExtChar and Protocol.CharAttrib. I won't bother listing them all here, because the demonstration solution shows examples of each and every one. However, it is important to bear in mind that, unlike HTML, these tags do not support closing tags-- so if you change the color, it will stay changed for the rest of your messages! Be sure to change the color back when you're done.

I didn't specify a run sequence here because file A always runs by default. The main advantage of strings is that they can be dynamically updated without making the sign "flash", so think of them as variables. They support a subset of the formatting codes that text messages support, so unless you need a variable, stick with text messages.

Note that, unless you specify otherwise, the maximum amount of picture memory (80x7) will be allocated in that file label. Here's what you should see when this is run:

This will scroll up and be replaced by another full-size 80x7 picture of some "modern art" I created. Now, I know what you're thinking: yes, you can load any arbitrary 80x7 pixel image into the BetaBrite, in whatever file formats .NET supports. However, do not expect this to look good! 80x7 is a tiny number of pixels, and the BetaBrite has a very limited palette: essentially two reds, two greens, and four yellows (see Protocol.PixelColor). Try it and see, but don't say I didn't warn you. I recommend sticking with the 8-color bitmap templates I created in the demonstration solution; look in the \bin folder for these.

Animated images (ala animated .gifs) isn't supported natively, but can be hacked in using the <NoHold> or <Speed5> tags and a sequence of cleverly designed picture files. There's an example of simulating animation in the demonstration solution, too.

Some Limitations

I'm pretty happy with the way this API turned out, but I think it's worth mentioning a few of the things I decided not to do. Some of these might make sense as possible future enhancements, and some were intentionally avoided.

It is BetaBrite-only. I thought about making the API generic enough to work with any Alpha sign, but then quickly decided that was a bad idea, because I don't have any other Alpha signs to test against.

It is write-only. I only implemented the Write commands, but for every Write, there is a Read. Making the API read-write isn't essential for a PC connected sign, in my opinion, but it might be useful.

It does not expose advanced run functionality. After setting the date and time on the sign, you can tell certain file labels to run at certain times of the day. The run sequence could display "GOOD MORNING" from 9 a.m. - 12 p.m., and "GOOD EVENING" from 6 p.m. - 9 a.m. Although this is supported in the BetaBrite.Protocol class, I didn't expose it in BetaBrite.Sign. This would not be hard to do, but I don't think it's very useful for PC-connected signs -- I expect the PC to be overwriting the sign every few minutes anyway. It'd be more useful for signs that were running standalone.

Conclusion

If you own a BetaBrite LED sign, I think you'll have a lot of fun with these classes; they make it easy to write .NET applications that support the BetaBrite sign. There are many more details and comments in the demonstration solution provided at the top of the article, so check it out.

I hope you enjoyed this article. Please don't hesitate to provide feedback, good or bad! If you enjoyed this article, you may also like my other articles as well.

History

Sunday, March 20th, 2005 - published.

Thursday, April 21st, 2005 - version 1.1

Modified picture methods to support directly passing a Bitmap.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

My name is Jeff Atwood. I live in Berkeley, CA with my wife, two cats, and far more computers than I care to mention. My first computer was the Texas Instruments TI-99/4a. I've been a Microsoft Windows developer since 1992; primarily in VB. I am particularly interested in best practices and human factors in software development, as represented in my recommended developer reading list. I also have a coding and human factors related blog at www.codinghorror.com.

I'm hoping to use your BetaBrite code significantly in a script I'm writing for Homeseer (www.Homeseer.com). Once finished, I want to post it for other Homeseer users. I don't intend to sell it, but rather just allow people to download it and I will support them with any problems they have. I also plan to point to this article in the credits with your name.

Thanks to the information from this project, the betabriteusb.dll and the Alpha Protocol Document I have been able to program the Prism pretty much the same way I have been programming BetaBrite Classic displays. The one thing I'm still struggling with is writing Small Dots pictures. I can write them the same way I can also write them on the classic displays, but I can't get the additional colors to work. The version of the "Alpha Sign Communication Protocol" (pn 97088061, Rev F, March 2006) currently available online does not document the additional colors of the Prism display. The 'Write SMALL DOTS PICTURE' packet only supports colors from "0" to "8" (0x30 to 0x38) for pixels, i.e. black to yellow, just like for the classic displays. Other values are interpreted as black pixels.

I used the IR remote to create 7x80 DOTS Graphic with pixels of all possible colors, and used the "Read SMALL DOTS PICTURE" command to read the picture back to the PC. From the received packet it is apparent that the values for the Prism colors are the following:

where 30 is red and 7f is pink. However, when I send a picture using these colors, only values from 30 to 38 are accepted and any other values are ignored. They are turned in to 00, which I confirmed by reading the picture back.

I seem to be missing something, obviously, but I can't seem to find what that is using the Alpha Sign Communication Protocol documentation.

I did find a post on the ams-i forums that talks about how to use additional colors for TEXT messages, using <1C> "Z" and then 3 RGB values, which seem to indicate that the Prism implements at least part of the Alpha 3.0 protocol). However, I couldn't find any information regarding additional colors in pictures.

I was hoping that there is a newer version of the protocol documentation that specifically discusses the additional features the Prism display has over the classic displays, and that someone reading this is able to point me to where I can obtain such documentation.

do you have the sample code at all I am looking for this dll and code that everyone is talking about but the ftp site is down. I am looking at porting some of it to C# so I can use it in a few products, but I am looking at sending rgb colors to the display. Could you post or email me the code that you have been using for getting these extra colors.

There is also a demo program in basic that demonstrates how to use it.

It is not possible, to send Small Dot picture files with more than the 8 standard colors. I've tried. However, it is possible to send regular text using RGB colors. Send the command code 0x1C followed by "ZRRGGBB" to change the text color and "1CH" followed by "YRRGGBB" to change the shade color. The prism can reproduce the following 64 colors:

E.g. to set the text color to blue, send the character 0x1C, the character "Z", and then 6 characters representing the RGB value in hex, i.e. "0000FF"

The individual bytes for R, G, and B can not assume arbitrary values. They can only be "00", "40", "80", or "C0". (Note that the Adaptive Micro Systems program uses the value FF rather than C0. Both produce the same color result.)

It's been ages since I've done any BetaBrite programming, but one thing I found is that attempting to edit a stored message or string will disrupt the display, but the sign supports programmable macros which can be changed without disrupting the display. One is unfortunately limited in what one can do with macros (IIRC, they can contain font-change commands, but not end-of-line or transition commands), but they nonetheless provide a useful way to have text that will change 'smoothly' in response to external stimuli.

I have one of these signs and it came with no cable or software. I found the link to build the cable but I dont know nothing about .net and VB. Can someone please help by pointing me in the right direction to using this pages code?

so here's the deal i have a single line beta brite sign.i really love it, and i want to do more with the sign(i'm currently developing an application for my store, we rent dvd, vhs, games, and also do instore gaming) from my application,but......i bought the sign from sam's club and to my surpise it came without software. all attempts to d/l anything from the web site only gets me demos.does anyone have a copy of the disk that they would be willing to send to me?this is completely legit.

First off, I'd like to say that you've done a tremendous job with this code. It works really well, and I've used it to great effect with my BetaBrite sign.

I do have a problem with your bitmap handling, though, specifically in the WritePictureFileCommand class. You never call Dispose() on the Bitmap object that you create. I wrote a web interface which allows people to draw on my sign, and I have to take their drawing, save it to a file, then feed the file to your code. I'd like to be able to delete the file afterward, but I can't because your internal Bitmap object is still using it. I think a more flexible design might be for your class to take a Bitmap object instead of a file path. That way, people could be responsible for their own resource cleanup, and I'd be able to create an in-memory Bitmap object and feed it to your sign without the in-between step of having to save it to a file.

Well, it's not wrong per se-- the web context just holds on to the reference a lot longer than a console or winforms app would. You need the resource released faster in a web environment. Which is no problem! Just modify the Sign.SetPicture method as follows: