UBW Tester Liberty Basic Program
General
I wrote this little program in Liberty Basic to illustrate how easy it
is to do a simple GUI in LB that talks to a UBW. This program is for
Firmware C only, and all it does is allow you to turn each bit of Port
B on and off with the buttons on the screen. However, it does
illustrate a simple way to have LB query Windows to find all available
COM ports, then list them in a pull down box. When you select one of
the available ports, it opens it and starts writing the current data
byte to the port. If you connect up LEDs to each of your Port B pins,
then your UBW board can look the same as the green LEDs on the UBW
Tester window!
How It Works
When the app runs, it creates the window, asks Windows about the
available COM ports and puts them in the pull down box, then waits for
you to do something. Each time you click on a ON or OFF button, it
updates the 'current byte' of data. When you select one of the com
ports (use the one that your UBW is on) it opens the port and every
50ms sends the byte to the port. As you change the byte with the ON and
OFF buttons, it sends the new value. It also prints out the byte in hex
and decimal in the output box.
Update (7/17/06)
A new version of Firmware C is now out (v1.0) which sends back a byte
(the current input bits of Port A) every time you send a byte to the
UBW. So you can now use Firmware C for both input and output. Also a
small bug was fixed in the tester application presented here that would
prevent com ports over 10 from appearing in the drop down box. The
tester application has been updated to show the value of the byte going
out to the UBW and the byte coming back (showing the current state of
Port A bits).
Files
A Zip file of all necessary files
(basic source, LED bitmaps, and FreeForm GUI editor file)
Questions? E-mail me at
The Code
'''''''''''''''''''''''''''''''''''''''''''''''''''''
' UBW Tester.bas
'
' Written by Brian Schmalz
' as part of the UBW Project
' http://www.schmalzhaus.com/UBW
' Free for all to use and improve
' 2/20/06
'
' DESCRIPTION:
' This Liberty Basic program will allow you to do a simple
' test with your UBW board (any version) if you have
' Firmware C on it. Firmware C just takes each byte
' of data it receives over the USB and outputs it to
' port B of the PIC.
'
' This application gives you eight on and eight off
' buttons to turn each Port B pin on or off, and allows
' you to select a com port.
'
' NOTE: You must have your UBW pluged in BEFORE you
' run this application. This application, when it is
' first run, will go out and get a list of all available
' COM ports on your PC, and will list them in the drop
' down menu. When you pick one, it opens the port and
' begins to write a byte of data down every 50ms.
' It also prints the byte in hexidecimal and decimal
'
Global
kMaxCOMPorts
' How many com ports do we look at?
kMaxCOMPorts = 40
' Dim all of the arrays
DIM CombComPort$(kMaxCOMPorts) ' Holds strings
for COM port numbers (COM1, COM2, etc.)
' Call out global variables
GLOBAL
bSerialPortOpen '
1 if serial port has been successfully opened
bSerialPortOpen =
0
' Default it to unopened
GLOBAL
PortB
' This is the value we send to the UBW every tick
PortB =
0
' Holds the current byte to output to Port B.
' We don't want the cosole window
nomainwin
'Form created with the help of Freeform 3 v03-27-03
'Generated on Feb 23, 2006 at 14:15:39
[setup.main.Window]
'-----Begin code for #main
WindowWidth = 205
WindowHeight = 430
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
'-----Begin GUI objects code
button #main.button1,"B0 ON",[B0ONClick],
UL, 5, 17, 70, 25
button #main.button2,"B1 ON",[B1ONClick],
UL, 5, 47, 70, 25
button #main.button3,"B2 ON",[B2ONClick],
UL, 5, 77, 70, 25
button #main.button4,"B3 ON",[B3ONClick],
UL, 5, 107, 70, 25
button #main.button5,"B4 ON",[B4ONClick],
UL, 5, 137, 70, 25
button #main.button6,"B5 ON",[B5ONClick],
UL, 5, 167, 70, 25
button #main.button7,"B6 ON",[B6ONClick],
UL, 5, 197, 70, 25
button #main.button8,"B7 ON",[B7ONClick],
UL, 5, 227, 70, 25
button #main.button9,"B0 OFF",[B0OFFClick],
UL, 80, 17, 70, 25
button #main.button10,"B1 OFF",[B1OFFClick],
UL, 80, 47, 70, 25
button #main.button11,"B2 OFF",[B2OFFClick],
UL, 80, 77, 70, 25
button #main.button12,"B3 OFF",[B3OFFClick],
UL, 80, 107, 70, 25
button #main.button13,"B4 OFF",[B4OFFClick],
UL, 80, 137, 70, 25
button #main.button14,"B5 OFF",[B5OFFClick],
UL, 80, 167, 70, 25
button #main.button15,"B6 OFF",[B6OFFClick],
UL, 80, 197, 70, 25
button #main.button16,"B7 OFF",[B7OFFClick],
UL, 80, 227, 70, 25
bmpbutton #main.bmpbutton18, ".\LightOff.bmp",
[bmpbutton18Click], UL, 165, 22
bmpbutton #main.bmpbutton19, ".\LightOff.bmp",
[bmpbutton19Click], UL, 165, 52
bmpbutton #main.bmpbutton20, ".\LightOff.bmp",
[bmpbutton20Click], UL, 165, 82
bmpbutton #main.bmpbutton21, ".\LightOff.bmp",
[bmpbutton21Click], UL, 165, 112
bmpbutton #main.bmpbutton22, ".\LightOff.bmp",
[bmpbutton22Click], UL, 165, 142
bmpbutton #main.bmpbutton23, ".\LightOff.bmp",
[bmpbutton23Click], UL, 165, 172
bmpbutton #main.bmpbutton24, ".\LightOff.bmp",
[bmpbutton24Click], UL, 165, 202
bmpbutton #main.bmpbutton25, ".\LightOff.bmp",
[bmpbutton25Click], UL, 165, 232
TextboxColor$ = "white"
textbox #main.TextboxOutputByte, 5, 282,
175, 25
statictext #main.statictext27, "Output Byte (Hex :
Decimal)", 5, 257, 162, 20
textbox #main.TextboxInputByte, 5, 337,
175, 25
statictext #main.statictext27, "Input Byte (Hex :
Decimal)", 5, 312, 162, 20
statictext #main.statictext28, "COM
Port", 5, 372, 57, 20
ComboboxColor$ = "white"
combobox #main.CombComPort, CombComPort$(),
[CombComPortDoubleClick], 75, 372, 100, 100
'-----End GUI objects code
open "UBW FW C Tester v1.0" for window as #main
print #main, "font ms_sans_serif 10"
'----------------END FREEFORM CODE--------------
'________________DO NOT INCLUDE IN PASTE________
loadbmp "ON", "LightOn.bmp"
loadbmp "OFF", "LightOff.bmp"
print #main, "trapclose [quit.main]"
' Go do TimerTick every 50ms
timer 50, [TimerTick]
' Populate the drop down list of available COM ports
gosub [GetCOMPorts]
[main.inputLoop] 'wait here for input event
wait
[B0ONClick] 'Perform action for the button named 'button1'
print #main.bmpbutton18, "bitmap ON"
PortB = PortB OR 1
wait
[B1ONClick] 'Perform action for the button named 'button2'
print #main.bmpbutton19, "bitmap ON"
PortB = PortB OR 2
wait
[B2ONClick] 'Perform action for the button named 'button3'
print #main.bmpbutton20, "bitmap ON"
PortB = PortB OR 4
wait
[B3ONClick] 'Perform action for the button named 'button4'
print #main.bmpbutton21, "bitmap ON"
PortB = PortB OR 8
wait
[B4ONClick] 'Perform action for the button named 'button5'
print #main.bmpbutton22, "bitmap ON"
PortB = PortB OR 16
wait
[B5ONClick] 'Perform action for the button named 'button6'
print #main.bmpbutton23, "bitmap ON"
PortB = PortB OR 32
wait
[B6ONClick] 'Perform action for the button named 'button7'
print #main.bmpbutton24, "bitmap ON"
PortB = PortB OR 64
wait
[B7ONClick] 'Perform action for the button named 'button8'
print #main.bmpbutton25, "bitmap ON"
PortB = PortB OR 128
wait
[B0OFFClick] 'Perform action for the button named 'button9'
print #main.bmpbutton18, "bitmap OFF"
PortB = PortB AND 254 '11111110
wait
[B1OFFClick] 'Perform action for the button named 'button10'
print #main.bmpbutton19, "bitmap OFF"
PortB = PortB AND 253 '11111101
wait
[B2OFFClick] 'Perform action for the button named 'button10'
print #main.bmpbutton20, "bitmap OFF"
PortB = PortB AND 251 '11111011
wait
[B3OFFClick] 'Perform action for the button named 'button10'
print #main.bmpbutton21, "bitmap OFF"
PortB = PortB AND 247 '11110111
wait
[B4OFFClick] 'Perform action for the button named 'button13'
print #main.bmpbutton22, "bitmap OFF"
PortB = PortB AND 239 '11101111
wait
[B5OFFClick] 'Perform action for the button named 'button14'
print #main.bmpbutton23, "bitmap OFF"
PortB = PortB AND 223 '11011111
wait
[B6OFFClick] 'Perform action for the button named 'button15'
print #main.bmpbutton24, "bitmap OFF"
PortB = PortB AND 191 '10111111
wait
[B7OFFClick] 'Perform action for the button named 'button16'
print #main.bmpbutton25, "bitmap OFF"
PortB = PortB AND 127 '01111111
wait
[bmpbutton18Click] 'Perform action for the bmpbutton named
'bmpbutton18'
[bmpbutton19Click] 'Perform action for the bmpbutton named
'bmpbutton19'
[bmpbutton20Click] 'Perform action for the bmpbutton named
'bmpbutton20'
[bmpbutton21Click] 'Perform action for the bmpbutton named
'bmpbutton21'
[bmpbutton22Click] 'Perform action for the bmpbutton named
'bmpbutton22'
[bmpbutton23Click] 'Perform action for the bmpbutton named
'bmpbutton23'
[bmpbutton24Click] 'Perform action for the bmpbutton named
'bmpbutton24'
wait
[CombComPortDoubleClick] 'Perform action for the combobox
named 'CombComPort'
gosub [OpenSerialPort]
wait
' Come here every tick of the timer.
' Send out our byte, and update the edit field
[TimerTick]
if gSerialPortOpen = 1 then
' This is what does all of
the work - output the byte to port B of
' the UBW board.
print #commHandle,
chr$(PortB);
print
#main.TextboxOutputByte, "0x";dechex$(PortB);" : ";PortB
In$ = input$(#commHandle,
lof(#commHandle))
print
#main.TextboxInputByte, "0x";dechex$(asc(left$(In$, 1)));" :
";asc(left$(In$, 1))
end if
wait
[quit.main] 'End the program
gosub [CloseSerialPort]
close #main
end
''''''''''''''''''''''
' UTILITY ROUTINES '
''''''''''''''''''''''
'
' GetCOMPorts
'
' This subroutine will populate the drop-down list called
#main.CombComPort
' with all of the currently available COM ports. You can change
#main.CombComPort
' to whatever you use in your program.
'
[GetCOMPorts]
' First clear out #main.CombComPort
for Port = 0 to kMaxCOMPorts
CombComPort$(Port) = ""
next Port
CurrentComboIndex = 0
' We're going to loop from 1 to 254 and see if each
port is available
for TestPort = 1 to kMaxCOMPorts
if
IsCOMPortAvailable(TestPort) = 1 then
'
Add this port into #main.CombComPort
CombComPort$(CurrentComboIndex) = "COM" + str$(TestPort)
print "Adding COM" + str$(TestPort)
CurrentComboIndex = CurrentComboIndex + 1
end if
next TestPort
' Now reload the combbox to get the new array values
print #main.CombComPort, "reload"
return
' Helper function for [GetCOMPorts]
' Returns 0 if the Port is not available on this system (either already
opened or doesn't
' exist) and 1 if the port is available.
function IsCOMPortAvailable(Port)
struct lpSecurityAttributes, _
nLength as long, _
lpSecurityDescriptor as
long, _
bInheritHandle as long
lpFileName$ = "\\.\COM" + str$(Port)
dwDesiredAccess = 0
dwShareMode = 1 + 2
dwCreationDisposition = 3
dwFlagsAndAttributes = 128
hTemplateFile = 0
calldll #kernel32, "CreateFileA", _
lpFileName$ as ptr, _
dwDesiredAccess as long, _
dwShareMode as long, _
lpSecurityAttributes as
struct, _
dwCreationDisposition as
long, _
dwFlagsAndAttributes as
long, _
hTemplateFile as long, _
retcode as long
hObject = retcode
' Test the return code to see if the port is
available and free
if retcode = -1 then
IsCOMPortAvailable = 0
else
' If we were able to open
it, then close it and return TRUE
calldll #kernel32,
"CloseHandle", _
hObject as long, _
retcode as long
IsCOMPortAvailable = 1
end if
end function
' Handle opening the serial port
[OpenSerialPort]
oncomerror [ComErrorHandler]
if gSerialPortOpen = 1 then
gosub [CloseSerialPort]
end if
print #main.CombComPort, "contents? ComPort$"
open ComPort$;":9600,8,N,1,RS,DS0,CS0" for random as
#commHandle
gSerialPortOpen = 1
return
' Handle closing the serial port
[CloseSerialPort]
if gSerialPortOpen = 1 then
close #commHandle
end if
gSerialPortOpen = 0
return
' We get here if there is a com error at some point.
[ComErrorHandler]
' Display the com error box
notice "Com Error"; chr$(13); "Some type of com port
error has occured. Your computer may not have a valid com port at COM";
str$(ComPortNumber); " or there might be another error. "; chr$(13);
"Error: "; ComError$; " Port: "; str$(ComPortNumber); " ErrorNo: ";
str$(ComErrorNumber)
gosub [CloseSerialPort]
wait