I wanted to implement an auxiliary external display on Linux. I looked at a few displays and found three that had reasonable prices. Unfortunately none of them came with open source software, they did however come with some working but pretty poor windows software. So to use these devices from Linux or any other OS in a specialized way, I would have to reverse engineer the signs to a certain extent. This page is basically a summary on how I reverse engineered the communication protocols for the three signs.
I have not worked on this project in a long time, never completely finished the third sign’s writeup. I may finish it up if there is interest as I have the analysis written down in notes and a few files. I never wrote any programming in linux to control the signs. I was planning on using python, and I think it would be very easy to do anyway, I currently don’t have the need or time to write the code.
portmon.exe a tool made by SysInternals(now Microsoft) that monitors serial port communications, I haven’t found an equivalent tool in Linux yet.
Set of small screwdrivers…
MS Excel, and OO.o’s Calc
Details of sign will follow this general layout:
The grid paper’s major line interval is 1 cm and the minor line interval is 1 mm.
Made in China
37×7 led array
four 120 character long messages
5×7 LED characters
9 brightness/luminosity settings
9 speed settings
TekGems et-42065-con-red-9in-ledsign 9” Programmable Scrolling Red LED Sign $27.99
The Microprocessor is an STC 89C51RC, 40C-LQFP44 with a 22.1184MHz crystal. Which is an 8bit micro with a 32kByte Flash. I couldn’t find any data sheets in english on the STC part. I suspect it is a Chinese clone of the Atmel AT89C51RC. The pins don’t exactly match but they look to be very close. To multiplex the uC’s outputs the sign uses two NXP 74HC595D 8-bit serial-in, serial or parallel-out shift register with output latches.
Each row of LEDs are connected together, then connected to a 470 ohm resistor which is tied to VCC, in addition “”””””it may be connected to a pin of the micro. Each column of LEDs is tied together then tied to one of the microprocessor’s pins or one of the shift registers’ pins.
To program the sign, you use the DB9-F to USB Mini-B cable, and to charge/run it you either hook it up to a USB port, or connect the 120V to 5V wall wart that has a USB Mini-B connector.
The programming cable is very simple, it uses pins 2,3,4,5 on the DB9. Pin 5 (GND) is the serial port’s ground pin, this connects to a red wire which runs to pin 5 on the USB connector. Pin 4 (DTR) on the DB9 connects to Pin 2 (RXD) on the DB9 via a 20K0 +/-1% ohms 1/8 watt resistor (Red-Black-Black-Red-Brown). Pin 3 (TXD) on the DB9 connects to a white wire which runs to pin 3 on the USB connector. Pin 2 (RXD) on the DB9 connects to a green wire which runs to pin 2 on the USB connector. When programming the display power is provided by the internal Lithium Ion battery pack. When using the wall-wart power supply, power is provided by pin 1 on the usb connector.
Send 0xAA about twice per second to enter programming mode
To program the messages:
Stop sending 0xAA
After each byte is sent read 1 byte to make sure the link is still up.
Send the message number/address, message 1 = 0xCC; message 2 = 0xCD; message 3 = 0xCE; message 4 = 0xCF
Next send the luminosity and speed byte. The first nibble runs 1-9 and sets the luminosity, the second nibble runs 1-9 and sets the speed. So to set the luminosity to 8 and the speed to 4 you’d send 0x84.
Send the character count in hex, 0x00 to 0x78 or 0 to 120.
Send each letter of the message left to right, one byte at a time.
Repeat for the other three messages.
After programming is complete, and you don’t start sending 0xAA message 4 will scroll indefinitely.
I sent all possible characters, and found the following character set. See messagelink.xls
I’m not sure what values above 0x3B would display or do. I suspect sending values above 0x3B may brick the sign, display additional characters possibly asian, enter a rom programming mode, etc…
Item Code :GAD007801
Item :USB Scrolling LED Name Badge II
Option :GAD007801 Red Color
Price : US$22
Syncs via a serial to IR adapter, the serial port drivers are the same as the other devices.
Bus 005 Device 024: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
NXP LPC922F 6600806
The NXP device(P89LPC922 I think) is an 8bit, 20 pin, uC with 8kbytes Flash
1x CR2032 battery
marked V2.00 06/13/2004
three buttons: up, down, enter
This is the smallest of the three signs, both in physical size, and LED array size.
The programming interface is done via an unidirectional IR(InfraRed) serial link.
Item Code :GAD014201
Item :USB LED Mini Board
Price : US$45
6x NXP 74HC595D, l709K109, UAG0736D
1x Prolific PL-2303HX LFC08123A
1x ATMEL 734, 24C12BN, 6U27, B – 16,384 bytes serial EEPROM
1x ATMEL ATMEGA88, 20AU, 0741, 32pin uC
1x 12×48 red LED array (576 LEDs)
2x momentary push buttons
1x SPDT slide switch
1x USB Mini-B jack
Board is multi layer, looks like 3 layers
Lithium Rechargeable Polymer Cell – PTI (Pti Battery International?) PL042035P, 3.7V 240mAh, has a built in circuit board with a 6 pin chip, charge controller?
manufacture date 2008.04
This sign is physically sized between the other two signs, but has the largest LED array, and the most complex feature set.
Looks like there is a programming header for the ATMEGA88, Vdd, Vss and connections to two uC pins
each column of LEDs’ anode/cathode is connected together, and each column is then connected to one of the Q ports on the 74HC959D’s
each row of LED’s cathode/anode is connected together, and then connected to a pin on the ATMEGA88
6 messages of 250characters each for a total of 1500 characters message space
2 monochrome bitmap images 12×1024 pixels (1536 bytes per image?)
Animated character support
Asian character support (Japanese, Korean, Chinese, T-Chinese) character set chosen in software changes what’s sent to the sign.
Assuming 6 messages of 250chars and 2 images 12x1024pixels are sent:
The software sends data in groups of 69 bytes except for the first and last groups. The first message consists of one byte can be thought of as an intialization byte, and is always 0x00. The last group consists of 3 bytes: 0x02, 0x33, 0x?????. The last byte seems to be a checksum since it does change depending on the length of data sent.——-
After the first byte (0x00) the software sends the
Each group is divided into roughly 3 parts, Command/Address, Data and settings, and a checksum. The address/command part, always starts with 0x02 and is followed by 3 more bytes. The first of which is almost always 0x31, the only exception is the last data group sent. The last two bytes in this group appear to be an address, the first group is always 0x06 0x00 and each additional group increments by 0x40 or 64, one for each payload byte.
After the command/address is sent, the data and settings part of the data group is sent, it always consists of 64 bytes. If a particular group doesn’t have enough data to pack the entire 64byte block it is zero padded. If a particular group has more than 64 bytes it’s wrapped into the next data group. If a message is set, 4 data groups are sent for each message. However, text message can only be 250 characters, the maximum number of data blocks is 4 or 256 bytes, the “extra” 6 bytes are used as follows. The first 4 bytes in the first data group of each message provide the Speed setting, Message number, Style setting and message length. The last two bytes of the last data group of each message are always 0x00 and 0x00, I’d guess the designer(s) padded out these last bytes to make the maximum message length a nice round number, 250. These 250 bytes store the message, using english character set, it’s one byte for one character. The asian character sets require two bytes per character.
——————–character set image—————
Once the data and settings are sent, a check sum is sent. The checksum is easily calculated by adding up the last three bytes of the command/address data and the 64 byte data/settings part. The resulting sum is taken mod 256 to return an 1 byte number. It took me a while to figure out this check sum. Initially I thought it was a sum, however when I added up all of the bytes in a block I didn’t get the correct number. Graphing the checksum values showed an obvious cyclic pattern, so this would probably throw out something complicated like a CRC, plus a CRC wouldn’t really be nessary for a simple short serial link, also CRC would eat up too many resources to be of much benifit. Additional clues were if any byte in the message changed the check sum would change, if the address changed the checksum changed. At one point I thought it might be doing an XOR of all the bytes so I fiddled around with calculating XORs in excel but that didn’t give the correct result either. I went back to looking at sums again since there was such an obvious pattern. When I summed the message bytes I noticed that the sum (0x89_would be close to the check sum (0x87) then it hit me, exclude the first byte 0x02 from the checksum, and voila it worked for every data group I had captured!
——-picture of cyclic checksum value graph——-
The data format for images was also an interesting challenge. It was fairly obvious which data groups were being used for images by sending known images, ie all black, or only first and last pixel black, etc… However the device was sending more data than was needed. For a 12×1024 pixel or 12,288 bit image, it was sending 31 groups of 64 bytes and one group of 56 bytes or 2040 bytes 16,320 bits of image data. By sending a couple specially crafted images I was able to figure out how it was sending the data.
Image message settings and their address blocks, are they addresses?
image checksums or the following 24 bytes, what are they?
last byte of all data sent, what is it, why does it change?
behavior for sending less than 6 messages and 2 images