AvBrand Exploring Technology
- Introduction
- Part 1 - Installation of the Car PC
- Part 2 - Adding a Rear-View Camera
- Part 3 - Time for some Software!
- Part 4 - An LED message sign
- Part 5 - Voice Commands
- Part 6 - Phone Integration
- Part 7 - XM Radio Integration
- Part 8 - Permanent Internet
- Part 9 - Front Camera
- Part 10 - Digital Dash
- Part 11 - Shuttle Jog Wheel
- Frequently Asked Questions
New LED Sign Technical Details
The specific sign I was using is the 4x26 Windowfront Three Color Programmable LED Sign from Brightledsigns.com. You can buy it here for $219. BrightLEDSigns.com 4x26 Windowfront Three ColorThe features it has that make it the right sign for the job:
- It uses two high-brightness LEDs per pixel. Indoor signs, especially cheap 3-color ones, cannot be read in sunlight during the day.
- It has a serial port and includes the cable, and the protocol was easy to reverse-engineer.
- It is relatively inexpensive compared to many signs
- It is powered by 5V, therefore easily married into a car with a simple step-down converter.
- It is a reasonable size, small enough to fit in the back window, but large enough to be seen from quite a distance.
The Serial Protocol
I used the included software and a serial port sniffing application to reverse-engineer the protocol that this sign uses. It's a more advanced protocol than the previous NS500-UA, and runs at 9600 baud instead of super-slow 2400 baud. I've included it on this page. If you find this useful, please be sure to give me credit. The code below is in Visual Basic 6 language.
Option Explicit Private MyComm As MSCommLib.MSComm Private WithEvents MyTimer As VB.Timer Private Const OneSecond = 1 / 24 / 60 / 60 Public Sub Startup(MyOwner As Form, Port As Long) Set MyComm = MyOwner.Controls.Add("MsCommLib.MsComm", "MyNS500Comm", MyOwner) ' Set up the comm settings MyComm.Settings = "9600,n,8,1" MyComm.CommPort = Port Debug.Print "Port Open: ", MyComm.PortOpen End Sub Public Sub setSignText(inTxt As String, delay As Long) If delay > 0 Then ditchMessageAt = Now + (delay * OneSecond) Else ditchMessageAt = 0 End If addToLog "[LEDSIGN]", "Sending ", inTxt On Error Resume Next addToLog "[LEDSIGN]", "Opening COM port", Form1.COM3.CommPort If Not MyComm.PortOpen Then MyComm.PortOpen = True If Err.Number <> 0 Then addToLog "[LEDSIGN]", "COM Port error:", Err.Description: Exit Sub Dim i As Long With MyComm .Output = "~128" ' COde number is 128 .Output = "~f01" ' File 01 .Output = "A" ' Auto Effect .Output = "\c" ' Default to Orange .Output = "\s" ' Default to 7x6 font '.Output = "Red\bRed2" .Output = fixText(inTxt) ' End of message '.Output = Chr(&HFF) & Chr(&HFF) & Chr(&H0) ' End of message .Output = Chr(13) & Chr(13) & Chr(13) '.PortOpen = False End With addToLog "[LEDSIGN]", "All done!" End Sub Private Function fixText(s As String) As String 'tID = 19 ' Original: ' Default color and font 'sC = Chr(&HEF) & Chr(&HB2) 'eC = Chr(&HFF) 'C = Chr(&HEF) & Chr(&HB0) 's = Replace(s, "\n", Chr(13)) ' You have to reinit after the line break ' TODO: After line break, the current effect needs to be sent again. Dim sc As String sc = Chr(13) s = Replace(s, "\", "\\") s = Replace(s, "^", "\^") s = Replace(s, "<COLOR:RED>", "\a") s = Replace(s, "<COLOR:BRIGHTRED>", "\b") s = Replace(s, "<COLOR:ORANGE>", "\c") s = Replace(s, "<COLOR:BRIGHTORANGE>", "\d") s = Replace(s, "<COLOR:YELLOW>", "\e") s = Replace(s, "<COLOR:BRIGHTYELLOW>", "\f") s = Replace(s, "<COLOR:GREEN>", "\g") s = Replace(s, "<COLOR:BRIGHTGREEN>", "\h") s = Replace(s, "<COLOR:LAYERMIX>", "\i") s = Replace(s, "<COLOR:BRIGHTLAYERMIX>", "\j") s = Replace(s, "<COLOR:VERTICALMIX>", "\k") s = Replace(s, "<COLOR:SAWTOOTHMIX>", "\l") s = Replace(s, "<COLOR:GREENONRED>", "\m") s = Replace(s, "<COLOR:REDONGREEN>", "\n") s = Replace(s, "<COLOR:ORANGEONRED>", "\o") s = Replace(s, "<COLOR:YELLOWONGREEN>", "\p") ' Fonts! s = Replace(s, "<FONT:7BY6>", "\s") s = Replace(s, "<FONT:DEFAULT>", "\s") s = Replace(s, "<FONT:SHORT>", "\q") s = Replace(s, "<FONT:SHORTANDWIDE>", "\r") s = Replace(s, "<FONT:WIDE>", "\t") s = Replace(s, "<FONT:7BY9>", "\u") s = Replace(s, "<FONT:EXTRAWIDE>", "\v") s = Replace(s, "<FONT:SMALL>", "\w") s = Replace(s, "<CYCLIC>", sc & "A" & "\c") s = Replace(s, "<IMMEDIATE>", sc & "B" & "\c") s = Replace(s, "<OPENFROMRIGHT>", sc & "C" & "\c") s = Replace(s, "<OPENFROMLEFT>", sc & "D" & "\c") s = Replace(s, "<OPENFROMCENTER>", sc & "E" & "\c") s = Replace(s, "<OPENTOCENTER>", sc & "F" & "\c") s = Replace(s, "<COVERFROMCENTER>", sc & "G" & "\c") s = Replace(s, "<COVERFROMRIGHT>", sc & "H" & "\c") s = Replace(s, "<COVERFROMLEFT>", sc & "I" & "\c") s = Replace(s, "<COVERTOCENTER>", sc & "J" & "\c") s = Replace(s, "<SCROLLUP>", sc & "K" & "\c") s = Replace(s, "<SCROLLDOWN>", sc & "L" & "\c") s = Replace(s, "<INTERLACE1>", sc & "M" & "\c") s = Replace(s, "<INTERLACE2>", sc & "N" & "\c") s = Replace(s, "<COVERUP>", sc & "O" & "\c") s = Replace(s, "<COVERDOWN>", sc & "P" & "\c") s = Replace(s, "<SCANLINE>", sc & "Q" & "\c") s = Replace(s, "<EXPLODE>", sc & "R" & "\c") s = Replace(s, "<PACMAN>", sc & "S" & "\c") s = Replace(s, "<STACK>", sc & "T" & "\c") s = Replace(s, "<SHOOT>", sc & "U" & "\c") s = Replace(s, "<FLASH>", sc & "V" & "\c") s = Replace(s, "<RANDOM>", sc & "W" & "\c") s = Replace(s, "<SLIDEIN>", sc & "X" & "\c") s = Replace(s, "<AUTO>", sc & "A" & "\c") ' Pauses s = Replace(s, "<PAUSE1>", "\Z1") s = Replace(s, "<PAUSE2>", "\Z2") s = Replace(s, "<PAUSE3>", "\Z3") s = Replace(s, "<PAUSE4>", "\Z4") s = Replace(s, "<PAUSE5>", "\Z5") s = Replace(s, "<PAUSE6>", "\Z6") s = Replace(s, "<PAUSE7>", "\Z7") s = Replace(s, "<PAUSE8>", "\Z8" & Chr(13) & "A" & " \Z8" & Chr(13) & "A \Z8") ' Speeds s = Replace(s, "<SPEED0>", "\Y1") ' Fastest s = Replace(s, "<SPEED1>", "\Y2") s = Replace(s, "<SPEED2>", "\Y3") s = Replace(s, "<SPEED3>", "\Y4") s = Replace(s, "<SPEED4>", "\Y5") s = Replace(s, "<SPEED5>", "\Y6") s = Replace(s, "<SPEED6>", "\Y7") s = Replace(s, "<SPEED7>", "\Y8") ' Slowest s = Replace(s, "<SUN>", "^66") s = Replace(s, "<CLOUDY>", "^67") s = Replace(s, "<RAIN>", "^68") s = Replace(s, "<CLOCK>", "^69") s = Replace(s, "<PHONE>", "^70") s = Replace(s, "<SPECS>", "^71") s = Replace(s, "<FAUCET>", "^72") s = Replace(s, "<ROCKET>", "^73") s = Replace(s, "<BUG>", "^74") s = Replace(s, "<KEY>", "^75") s = Replace(s, "<SHIRT>", "^76") s = Replace(s, "<CHOPPER>", "^77") s = Replace(s, "<CAR>", "^78") s = Replace(s, "<DUCK>", "^79") s = Replace(s, "<HOUSE>", "^80") s = Replace(s, "<TEAPOT>", "^81") s = Replace(s, "<TREES>", "^82") s = Replace(s, "<SWAN>", "^83") s = Replace(s, "<MBIKE>", "^84") s = Replace(s, "<BIKE>", "^85") s = Replace(s, "<CROWN>", "^86") s = Replace(s, "<STRAWBERRY>", "^87") s = Replace(s, "<ARROWRIGHT>", "^88") s = Replace(s, "<ARROWLEFT>", "^89") s = Replace(s, "<ARROWDOWNLEFT>", "^90") s = Replace(s, "<ARROWUPLEFT>", "^91") s = Replace(s, "<CUP>", "^92") s = Replace(s, "<CHAIR>", "^93") s = Replace(s, "<SHOE>", "^94") s = Replace(s, "<GLASS>", "^95") ' Time s = Replace(s, "<TIME1>", "^D") s = Replace(s, "<TIME2>", "^E") s = Replace(s, "<TIME3>", "^F") s = Replace(s, "<DATE1>", "^A") s = Replace(s, "<DATE2>", "^B") s = Replace(s, "<DATE3>", "^C") s = Replace(s, "<BEEP1>", "^q") ' 3 beeps s = Replace(s, "<BEEP2>", "^r") ' 3 short beeps s = Replace(s, "<BEEP3>", "^s") ' Short beep ' Static Graphics s = Replace(s, "<CITYSCAPE>", "^Q") s = Replace(s, "<TRAFFIC>", "^R") s = Replace(s, "<TEAPARTY>", "^S") s = Replace(s, "<TELEPHONE>", "^T") s = Replace(s, "<SUNSET>", "^U") s = Replace(s, "<CARGOSHIP>", "^V") s = Replace(s, "<SWIMMERS>", "^W") s = Replace(s, "<MOUSE>", "^X") ' Cartoons s = Replace(s, "<MERRYXMAS>", "^i") s = Replace(s, "<HAPPYNEWYEAR>", "^j") s = Replace(s, "<4THJULY>", "^k") s = Replace(s, "<HAPPYEASTER>", "^l") s = Replace(s, "<HALLOWEEN>", "^m") s = Replace(s, "<DONTDRINKDRIVE>", "^n") s = Replace(s, "<NOSMOKING>", "^o") s = Replace(s, "<WELCOME>", "^p") s = Replace(s, "<TEMP>", "^H") ' Doesn't work fixText = s End Function
Here are some examples of the messages you see on my sign:
NS500Color.setSignText "<OPENFROMRIGHT>< < < < < <", -1 NS500Color.setSignText "<OPENFROMLEFT>> > > > > >", -1 NS500Color.setSignText "<OPENFROMCENTER>< < < > > >", -1 NS500Color.setSignText "<FLASH>Backing Up<IMMEDIATE>Backing Up<PAUSE8>", -1 NS500Color.setSignText "<OPENFROMCENTER><COLOR:GREEN>Thank you!<PAUSE4><OPENFROMCENTER> <PAUSE8>", 20 NS500Color.setSignText "<FLASH><COLOR:RED>Sorry!<IMMEDIATE><COLOR:RED>Sorry!<PAUSE8>", 10 NS500Color.setSignText "<IMMEDIATE><COLOR:GREEN>Go Around Me<PAUSE8>", 10 NS500Color.setSignText "<SCROLLUP>TURN OFF<SCROLLUP>HIGH BEAMS<SCROLLUP><COLOR:GREEN>thank you<SCROLLUP> <PAUSE8>", 20 NS500Color.setSignText "<IMMEDIATE>Nice Car!<PAUSE8>", 15 NS500Color.setSignText "<SCROLLUP>Traffic Ahead<SCROLLUP> Use Alternate Route ", 45 NS500Color.setSignText "<FLASH><COLOR:RED>ALERT!<SLIDEIN>Your <COLOR:GREEN>LEFT HEADLIGHT<COLOR:ORANGE> is Broken! <PAUSE8>", 45 NS500Color.setSignText "<FLASH><COLOR:RED>ALERT!<SLIDEIN>Your <COLOR:GREEN>RIGHT HEADLIGHT<COLOR:ORANGE> is Broken! <PAUSE8>", 45