System Requirements:
- Adafruit USB Serial RGB Backlight Character LCD Backpack
The Problem:
I recently needed a fast, cheap and modular way to output small amounts of information from a headless Windows 7 appliance, something that didn’t require a large amount of electrical engineering work or assembly while at the same time working over USB.
I accidentally stumbled upon a product by Adafruit, who seem to be tightly aligned with the Raspberry Pi/Arduino, however USB is USB which means that making it cooperate with Win32 wouldn’t be particularly challenging.
Being the lazy person that I am, I never much care for the idea of having to repeatedly type out control commands through a command line parser to get what I want and quite frankly, getting a NT Command Prompt to reliably pass anything out to a Serial Port is more or less a futile exercise unless you are using Plink or replace the shell entirely with something more robust.
My solution was quite simple, create a O-O VBScript API for running it via CScript that can in turn be called from the NT command line where required.
Buy Adafruit USB Serial RGB Backlight Character LCD Backpack, and other Adafruit components or & help support this site.
More Info
This API does what I require it to do. I have implemented all of the main command syntax from the Adafruit documentation (links below). It is classful and self contained. As long as you can create a FileSystemObject and can find the COM Port, you can make use of it.
[Update 25/04/2019] You can now obtain this code directly from Github.
View: AdafruitUsbSerial on GitHub
' AdafruitUsbSerial Application Programming Interface v1.0.4
' © C:Amie | www.c-amie.co.uk 1996 - 2014
' Not for commercial reproduction without the express permission of the author
' No warranty is offered or implied as a result of downloading or using this APIClass AdafruitUsbSerialprivate m_ForReadingprivate m_SCREEN_OFF
private m_SCREEN_ON
private m_AUTO_SCROLL_ON
private m_AUTO_SCROLL_OFF
private m_CLEAR_SCREEN
private m_SET_STARTUP_SPLASH
private m_SET_CURSOR_POSITION
private m_SET_CURSOR_HOME
private m_SET_CURSOR_BACK
private m_SET_CURSOR_FORWARD
private m_SET_UNDERLINE_ON
private m_SET_UNDERLINE_OFF
private m_SET_BLINK_ON
private m_SET_BLINK_OFF
private m_SET_RGB
private m_SET_CONTRAST
private m_SET_BRIGHTNESSprivate m_iPortNumber
private m_byteCharacterLength
private m_bolDebug
private m_bolAutoScroll
private m_bolUnderlineCursor
private m_bolBlinkCursor
private m_fso private
sub Class_Initialize
m_ForReading = 1
m_SCREEN_OFF = chr(254) & chr(70)
m_SCREEN_ON = chr(254) & chr(66)
m_AUTO_SCROLL_ON = chr(254) & chr(81)
m_AUTO_SCROLL_OFF = chr(254) & chr(82)
m_CLEAR_SCREEN = chr(254) & chr(88)
m_SET_STARTUP_SPLASH = chr(254) & chr(64)
m_SET_CURSOR_POSITION = chr(254) & chr(71)
m_SET_CURSOR_HOME = chr(254) & chr(72)
m_SET_CURSOR_BACK = chr(254) & chr(76)
m_SET_CURSOR_FORWARD = chr(254) & chr(77)
m_SET_UNDERLINE_ON = chr(254) & chr(74)
m_SET_UNDERLINE_OFF = chr(254) & chr(75)
m_SET_BLINK_ON = chr(254) & chr(83)
m_SET_BLINK_OFF = chr(254) & chr(84)
m_SET_RGB = chr(254) & chr(208)
m_SET_CONTRAST = chr(254) & chr(80)
m_SET_BRIGHTNESS = chr(254) & chr(153)
m_iPortNumber = 1
m_byteCharacterLength = 32
m_bolDebug = false
m_bolAutoScroll = true
m_bolUnderlineCursor = false
m_bolBlinkCursor = false
set m_fso = CreateObject("Scripting.FileSystemObject")
end sub
private sub Class_Terminate
set m_fso = nothing
end sub
' PROPERTIES
public property get PortNumber
PortNumber = m_iPortNumber
end property
public property let PortNumber(ByRef iIn)
m_iPortNumber = iIn
end property
public property get CharacterLength
CharacterLength = m_byteCharacterLength
end property
public property let CharacterLength(ByRef byteIn)
m_byteCharacterLength = byteIn
end property
public property get Debug()
Debug = m_bolDebug
end property
public property let Debug(ByRef bolIn)
m_bolDebug = bolIn
end property
public property get AutoScroll()
AutoScroll = m_bolAutoScroll
end property
public property let AutoScroll(ByRef bolIn)
if (bolIn) then
me.write(m_AUTO_SCROLL_ON)
else
me.write(m_AUTO_SCROLL_OFF)
end if
m_bolAutoScroll = bolIn
end property
public property get Underline()
Underline = m_bolUnderlineCursor
end property
public property let Underline(ByRef bolIn)
if (bolIn) then
me.write(m_SET_UNDERLINE_ON)
else
me.write(m_SET_UNDERLINE_OFF)
end if
m_bolUnderlineCursor = bolIn
end property
public property get Blink()
Blink = m_bolBlinkCursor
end property
public property let Blink(ByRef bolIn)
if (bolIn) then
me.write(m_SET_BLINK_ON)
else
me.write(m_SET_BLINK_OFF)
end if
m_bolBlinkCursor = bolIn
end property
' METHODS
public sub clearScreen()
me.write(m_CLEAR_SCREEN)
end sub public sub screenOn()
me.write(m_SCREEN_ON)
end sub
public sub screenOff()
me.write(m_SCREEN_OFF)
end sub
public sub changeSplashScreen(ByVal strIn)
strIn = Left(strIn, m_byteCharacters)
' Force it to be exactly 32 characters by padding
do while (Len(strIn) < m_byteCharacters)
strIn = (strIn & " ")
loop
me.clearScreen()
me.home()
me.write(m_SET_STARTUP_SPLASH)
me.write(strIn)
end sub
public sub backlight(ByRef byteR, ByRef byteG, ByRef byteB)
me.write(m_SET_RGB)
me.write(chr(byteR))
me.write(chr(byteG))
me.write(chr(byteB))
end sub
' Valid Range 0 - 255. Values between 180 and 220 are suggested
public sub contrast(ByRef byteIn)
me.write(m_SET_CONTRAST)
me.write(chr(byteIn))
end sub
' Valid Range 0 - 255.
public sub brightness(ByRef byteIn)
me.write(m_SET_BRIGHTNESS)
me.write(chr(byteIn))
end sub
public sub setCursorPosition(ByRef iX, ByRef iY)
me.write(m_SET_CURSOR_POSITION)
me.write(chr(iX))
me.write(chr(iY))
end sub
public sub home()
me.write(m_SET_CURSOR_HOME)
end sub
public sub back()
me.write(m_SET_CURSOR_BACK)
end sub
public sub goBack(ByRef iIn)
Dim i
for i = 1 to iIn
me.write(m_SET_CURSOR_BACK)
next
end sub
public sub forward()
me.write(m_SET_CURSOR_FORWARD)
end sub
public sub goForward(ByRef iIn)
Dim i
for i = 1 to iIn
me.write(m_SET_CURSOR_FORWARD)
next
end sub
public sub delete()
me.write(m_SET_CURSOR_BACK)
me.write(" ")
me.write(m_SET_CURSOR_BACK)
end sub
public sub write(ByRef strIn)
Dim serialWriter
if (me.Debug) then
wscript.echo strIn
end if
set serialWriter = m_fso.CreateTextFile("COM" & m_iPortNumber & ":",True)
serialWriter.Write(strIn)
serialWriter.Close()
set serialWriter = nothing
end sub
public sub teletype(ByRef strIn, ByRef iDelayMs)
Dim i
Dim iLen
iLen = Len(strIn)
for i = 1 to iLen
me.write(Mid(strIn, i, 1))
WScript.Sleep(iDelayMs)
next
end sub
public function testComPort(ByRef byteNumber)
Dim serialWriter
if (me.Debug) then
wscript.echo "Attempting communications with COM" & byteNumber
end if
On Error Resume Next
set serialWriter = m_fso.CreateTextFile("COM" & byteNumber & ":",True)
serialWriter.Write("Initialising...")
serialWriter.Close()
set serialWriter = nothing
if (err.number = 0) then
testComPort = true
else
testComPort = false
end if
On Error Goto 0
end function
End Class
Copy it into your VBScript project file or into a dedicated class file and include it. Once it is in scope, the example below shows a general usage pattern for the main API.
It is recommended that all projects include and set the first 8 lines shown below, just so that you can ensure that you are tuning your project in the way that you want it. The remainder of the code shows examples of how to use the functions.
As a result of the USB driver allocating COM ports in a fairly dynamic way under Win32, you cannot expect to hard code your COM Port inside the project – particularly if the physical USB port that the backpack is connected to changes. Consequently, you can use testComPort() to attempt to locate the correct port as shown below. The function will terminate on the first port that it finds with an active serial output line available, if you have multiple active serial ports available on your project, the function may find the wrong port.
Finally, Adafruit recommends – at a minimum -adding a 10 millisecond delay between each command, which is not shown below. You should use WScript.Sleep(10) to achieve similar under VBScript. If you don’t, everything shown below with the exception of the executing of the Teletype macro will occur in well under a second.
Dim usbSerial
set usbSerial = new AdafruitUsbSerial
usbSerial.PortNumber = 3 ' Set to COM3
usbSerial.Debug = true ' Inputs will be written back to WScript
usbSerial.CharacterLength = 32 ' 32 is the default
usbSerial.AutoScroll = true ' Enable/Disable Auto Scroll
usbSerial.Underline = true ' Enable Cursor Underline
usbSerial.Blink = true ' Enable Cursor Blink' Find the first live COM Port if you don't know where it is
Dim iComPort
for iComPort = 1 to 30
if (usbSerial.testComPort(iComPort)) then
usbSerial.PortNumber = iComPort
Exit For
end if
next' Write Text
usbSerial.write("some text")' Write on both lines
usbSerial.write("line one" & vblf & "line two")' Clear the screen
usbSerial.clearScreen()
' Screen Off
usbSerial.screenOff()
' Screen On
usbSerial.screenOn()
' Change the Backlight Colour
call usbSerial.backlight(255, 0, 255) ' Sets the RGB values (Fuchsia in this case)
' Set the screen brightness
usbSerial.brightness(180) ' 0 - 255
' Set the screen contrast
usbSerial.contrast(180) ' 0 - 255
' Set the Cursor Position
usbSerial.home() ' Moves to character 1, row 1
usbSerial.back() ' Moves the cursor back 1 character
usbSerial.forward() ' Moves the cursor forward 1 character
usbSerial.goBack(5) ' Steps the cursor back 5 characters
usbSerial.goForward(6) ' Progresses the cursor forward 6 characters
usbSerial.setCursorPosition(5,1) ' Sets the cursor to Character 5 on Row 1
usbSerial.delete() ' Moves the cursor back 1 and clears the previous character
' Teletype (Macro)
call usbSerial.teletype("this will teletype out", 100) ' Write the text, with a 0.1 second character delay
' Change the Adafruit Splash Screen (Auto truncated/padded to usbSerial.CharacterLength)
usbSerial.changeSplashScreen("This is a splash screen message")
' Clean up and free resources
set usbSerial = nothing
Thanks to a structured API it is as easy as that!
View: Adafruit: Command Reference
View: Adafruit: Sending Text
See Also
View: Adafruit
Buy Adafruit USB Serial RGB Backlight Character LCD Backpack, and other Adafruit components from Amazon & help support this site: