|
|||
| Did you know...
|
Interfacing the Serial Wombat from QBasic
And people are still using it, most often for its easy access to COM ports on pre-Windows NT OSes. If you look deep on your windows 98 program CD, you'll find it's still there. Below is some sample code which will provide a framework for accessing a Serial Wombat through QBasic. After looking around on the web, I was not actually able to find a program which both read and wrote the COM port in binary. So it took me a while to figure out how to do this. Among the things that complicate this code:
To use this framework, you basically just fill in the area between MainLoop and GOTO MainLoop. I've provided a subroutine TRANSACTION which will stream out whatever 8 bytes are in TXARRAY, and put the received response in RXARRAY. There's a variable RXRESULT which can be checked after TRANSACTION to see what happened. 1 means OK, 2 means a timeout happened, and 3 means the Wombat returned an Error Message. I've written up a couple of simple subroutines which set a pin and read a pin's public data as examples. The example framework simply continously reads the Public data from Wombat Pin 2, which by default starts up as an analog to digital converter measurement pin.
The Code (download it here):
DECLARE SUB SETPin (Pin AS INTEGER, state AS INTEGER)
DECLARE SUB GetPublicData (Pin AS INTEGER, Result AS LONG)
DECLARE SUB TRANSACTION ()
DECLARE SUB RESYNC ()
'Declare an array for storing/passing RX Data
DIM SHARED RXARRAY(8) AS INTEGER
'RXCount is used by the interrupt to keep track of
'The number of bytes received so far. Reset to 0 at the
'Beginning of each transaction
DIM SHARED RXCount AS INTEGER
'RX Result. 0 = In progress, 1=Success, 2 = Timeout
DIM SHARED RXRESULT AS INTEGER
'Array to pass transmit data in
DIM SHARED TXARRAY(8) AS INTEGER
CLS
' Open serial port and surpress all hardware handshaking, set interrupt
OPEN "COM1:9600,N,8,1,BIN,CD0,CS0,DS0,OP0,RS" FOR RANDOM AS #1
ON COM(1) GOSUB RXHANDLER
RXCount = 0
RXRESULT = 0
COM(1) ON
CALL RESYNC
DIM Result AS LONG
MainLoop:
CALL GetPublicData(2, Result)
IF (RXRESULT = 1) THEN
PRINT "Result was "; Result
END IF
GOTO MainLoop
END
RXHANDLER:
DIM rxin AS STRING
n = LOC(1)
rxin = INPUT$(n, 1)
FOR i = 1 TO LEN(rxin)
IF (RXCount < 8) THEN
RXCount = RXCount + 1
RXARRAY(RXCount) = ASC(MID$(rxin, i, 1))
END IF
NEXT
IF (RXCount = 8) THEN
RXRESULT = 1
END IF
RETURN
SUB GetPublicData (Pin AS INTEGER, Result AS LONG)
TXARRAY(1) = ASC("A")
'Convert Pin to ascii
TXARRAY(2) = Pin \ 10 + ASC("0")
TXARRAY(3) = (Pin MOD 10) + ASC("0")
'D for decimal:
TXARRAY(4) = ASC("D")
'Last 4 unused:
TXARRAY(5) = ASC("U")
TXARRAY(6) = ASC("U")
TXARRAY(7) = ASC("U")
TXARRAY(8) = ASC("U")
CALL TRANSACTION
IF (RXRESULT = 1) THEN
Result = 0
Result = Result + RXARRAY(8) - ASC("0")
Result = Result + (RXARRAY(7) - ASC("0")) * 10
Result = Result + (RXARRAY(6) - ASC("0")) * 100
Result = Result + (RXARRAY(5) - ASC("0")) * 1000
DIM TEMP AS LONG
TEMP = RXARRAY(4) - ASC("0")
TEMP = TEMP * 10000
Result = Result + TEMP
ELSE
'Error. Return -1
Result = -1
END IF
END SUB
SUB RESYNC
TXARRAY(1) = 85
TXARRAY(2) = 85
TXARRAY(3) = 85
TXARRAY(4) = 85
TXARRAY(5) = 85
TXARRAY(6) = 85
TXARRAY(7) = 85
TXARRAY(8) = 85
CALL TRANSACTION
END SUB
SUB SETPin (Pin AS INTEGER, state AS INTEGER)
TXARRAY(1) = ASC("P")
'Convert Pin to ascii
TXARRAY(2) = Pin \ 10 + ASC("0")
TXARRAY(3) = (Pin MOD 10) + ASC("0")
IF (state = 0) THEN
TXARRAY(4) = ASC("0")
ELSEIF (state = 1) THEN
TXARRAY(4) = ASC("1")
ELSEIF (state = 2) THEN
TXARRAY(4) = ASC("I")
ELSE
TXARRAY(4) = ASC("U")
END IF
TXARRAY(5) = ASC("U")
TXARRAY(6) = ASC("U")
TXARRAY(7) = ASC("U")
TXARRAY(8) = ASC("U")
CALL TRANSACTION
END SUB
SUB TRANSACTION
'This Subroutine is used to send 8 bytes to The Wombat, and wait for 8
'bytes back. It assumes that this can occur within 1 second (shouldn't
' be a problem). It creates an output string from TXARRAY, and dumps
' it to the serial port. This is necessary because QBasic doesn't have
' a byte type; It's integer type is 16 bits, so to get 8 bytes, you need
' a string of 8 characters.
' After the string is sent to the port ( I assume this is just queuing it
' in the FIFO, but i don't know), the Wombat uses the timer function to
' get the number of seconds since Midnight. It waits for one of two things
' to happen:
' RXResult gets set to 1 by the Receive interrupt
' OR
' Timer changes values twice. This means that between 1 and 2
' Seconds have passed since we first transmitted, So we time out
' The message.
' We could have used the QBasic ON TIMER functionality to do this,
' but since this timeout task is so simple, it seems smart not to
' waste ON TIMER on such a simple task.
DIM TryNumber AS INTEGER
TryNumber = 1
output$ = "UUUUUUUU"
FOR i = 1 TO 8
MID$(output$, i, 1) = CHR$(TXARRAY(i))
NEXT i
TRYAGAIN:
RXRESULT = 0
RXCount = 0
RXARRAY(1) = ASC("X")
RXARRAY(2) = ASC("X")
RXARRAY(3) = ASC("X")
RXARRAY(4) = ASC("X")
RXARRAY(5) = ASC("X")
RXARRAY(6) = ASC("X")
RXARRAY(7) = ASC("X")
RXARRAY(8) = ASC("X")
PRINT #1, output$;
DIM TimechangeCounter AS INTEGER
TimechangeCounter = 0
StartTime = TIMER
WHILE (RXRESULT = 0)
NewTime = TIMER
IF (StartTime <> NewTime) THEN
TimechangeCounter = TimechangeCounter + 1
StartTime = NewTime
IF (TimechangeCounter > 1) THEN
RXRESULT = 2
'Comment out the following code if desired.
PRINT "Timeout!"
END IF
END IF
WEND
IF (RXRESULT = 1 AND RXARRAY(1) = ASC("E")) THEN
' ERROR was received.
RXRESULT = 3
END IF
IF ((RXRESULT <> 1)) THEN
'ERROR State. Send RESYNC, and Try again
IF (TryNumber = 1) THEN
PRINT #1, "UUUUUUUUUUUUUU"
TryNumber = 2
GOTO TRYAGAIN
END IF
END IF
'Print out the TX and RX packets. Comment out if desired.
IF (RXRESULT = 1) THEN
PRINT USING "### "; TXARRAY(1);
PRINT USING "### "; TXARRAY(2);
PRINT USING "### "; TXARRAY(3);
PRINT USING "### "; TXARRAY(4);
PRINT USING "### "; TXARRAY(5);
PRINT USING "### "; TXARRAY(6);
PRINT USING "### "; TXARRAY(7);
PRINT USING "### "; TXARRAY(8);
PRINT USING "### "; RXARRAY(1);
PRINT USING "### "; RXARRAY(2);
PRINT USING "### "; RXARRAY(3);
PRINT USING "### "; RXARRAY(4);
PRINT USING "### "; RXARRAY(5);
PRINT USING "### "; RXARRAY(6);
PRINT USING "### "; RXARRAY(7);
PRINT USING "### "; RXARRAY(8)
END IF
END SUB
|
||
Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.