polling the serial port to see if any data is coming in. Pasted
below is an example of the latter procedure; it amounts to a
special purpose driver. Don't expect it to work as such with
your GPS. But hopefully it might give you some leads. By all means
ask the manufacturer of the GPS for information on writing a driver,
if they don't already provide it.
Good luck!
Code:
============================================================ 'STICDRV.BAS 'by E.W. Menzel, Jr. 'September, 1999 'Purpose: Read serial-port data from Measurements Systems Inc. 'force-based joystick. Translate it into X,Y motion, & also 'save data on force. 'Language: PowerBASIC 3.5 DEFINT A-Z DECLARE SUB StickOpenPort(FileNum%) DECLARE SUB StickParseData(RawData$, x%, y%) DECLARE SUB StickUnParse(RawData$,x%,y%) DECLARE FUNCTION ClockTic&() DECLARE FUNCTION StickClearPort$(FileNum%) 'gets everything DECLARE FUNCTION StickData$(FileNum%) 'gets one 3-byte pack DECLARE FUNCTION StickParseCheckOK(x%,y%) 'checks translation of Mouse data $COM 1024 'set size of COM buffer $IF 0 'demo 1... unREM $IF0 & $ENDIF to run demo ff=0 'let SUB StickOpenPort find FREEFILE file handle CALL StickOpenPort(ff) Start&=ClockTic& DO UNTIL INSTAT RawData$=StickData$(ff) IF LEN(RawData$) THEN Sec=(ClockTic&-Start&)/18.20684 'unless Midnight rolls over PRINT Sec; RawData$, END IF LOOP $ENDIF '======= end of demo 1 ================================= $IF 0 'demo2 ... unREM $IF0 & $ENDIF to run demo 'adapted from PowerBASIC manual, under COM(n) statement CLS ff=1 'file handle # for COM ON COM(ff) GOSUB GetComInput 'USE COM1: DIM ComPortInput$(5*1024) 'allocate 5k buffer to store input DIM InputTime(5*1024) as LONG HeadPtr%=0: TailPtr=0 'pointers for the buffer COM(ff) ON 'turn on COM(n) trapping '''$COM 1024 'set up 1k input buffer CALL StickOpenPort(ff) ' this SUB could find a FREEFILE PRINT "Press Esc to quit" WHILE NOT INSTAT IF TailPtr%<>HeadPtr% THEN PRINT ComPortInput$(TailPtr%), InputTime(TailPtr), TIME$ INCR TailPtr% 'step to next spot in buffer END IF WEND CLOSE 'close all open ports... see also COM(n) ON | OFF | STOP END 'Routine to COM port interrupt GetComInput: 'Read 3 bytes from COM port buffer; & get clocktic # ComPortInput$(HeadPtr%)=StickData$(ff) InputTime(HeadPtr%) = Clocktic& INCR HeadPtr% 'advance storage buffer pointer RETURN $ENDIF '============= end of demos ===================================== 'clock tics since midnight '(Exactly equal to ClockTic&=INT(TIMER*18.20648)) 'system clock tick rate = 1,193,180 / 64k 'or 18.20648 times per sec 'in 24 hrs, ticks = 1,573,040 (or &H 1800B0) Function ClockTic& ASM Mov ah, &h00 ASM Int &h1a ASM Mov c%, cx ASM Mov d%, dx if d%<0 then ClockTic&=65536+d%+c%*65536 else ClockTic&=d%+c%*65536 end if End Function 'This Function gets ALL bytes in the COM buffer and does not ' screen any of them for validity. FUNCTION StickClearPort$(FileNum%) DIM RawData as STRING RawData$="" WHILE (LOC(FileNum%)>1) RawData$=RawData$+INPUT$(1, #FileNum%) WEND FUNCTION = RawData$ END FUNCTION 'Open serial port (#1 only) connection to stick; disable hand-shaking 'Note: Depending on the buffer LEN you give it, COM port will hold 'its data & you do not necessarily have to read it constantly. See 'e.g., S.C. Gates & J. Becker, "Laboratory automation for the IBM PC" 'for more details on this & on RS-232C protocol more generally. SUB StickOpenPort(FileNum%) IF FileNum <1 then FileNum=FREEFILE '''$COM 2048 'put this in Main, to set up 2k input buffer OPEN "COM1:1200,N,8,1,rs,cs,ds,cd" for random as #FileNum% OUT &H3F,11 'for COM1... allows for 9th, parity, bit '''OUT &H2FB,11 'for COM2 END SUB 'SUB StickParseData processes ONE valid 3-byte data chunk. 'It will not parse all the data you might get after using SUB 'StickClearPort -- unless you call it repeatedly. SUB StickParseData(RawData$, x%, y%) STATIC DIM byt as BYTE, byt2 as BYTE, byt3 as BYTE DIM xx as BYTE, yy as BYTE L=LEN(RawData$) 'L should always be 3 & 1st char should be 1st byte, 'but let's play it safe IF L<3 then x%=0: y%=0 EXIT SUB 'note: we do not modify RawData$ END IF 'Data from the joy-stick are often repetitious; so... IF RawData$=LastData$ then x%=LastX: y%=LastY: EXIT SUB END IF FOR I=1 to L b$=MID$(RawData$,I,1) 'get 1 byte from Data string byt=ASC(b$) IF BIT(byt,6) THEN 'if we got the 1st byte of 3, then byt2=ASC(MID$(RawData$,I+1,1)) 'get #2 also byt3=ASC(MID$(RawData$,I+2,1)) 'and #3 EXIT FOR END IF NEXT ParseBytes: 'Now translate the above 3 bytes into X,Y values, following 'the protocol of Measurements Systems Inc. document El-312, p. 15 xx=byt2 'bits 0-5 of byt2 are X; bits 6&7 are start & stop bits yy=byt3 'similarly for byt3 & Y 'the 1st byte holds the most signif. digits of both X & Y IF BIT(byt,0) THEN BIT SET xx,6 ELSE BIT RESET xx,6 IF BIT(byt,1) THEN BIT SET xx,7 ELSE BIT RESET xx,7 IF BIT(byt,2) THEN BIT SET yy,6 ELSE BIT RESET yy,6 IF BIT(byt,3) THEN BIT SET yy,7 ELSE BIT RESET yy,7 'Bit 4 of byt is Right Button status; Bit 5 is Left Button... 'xx/yy are "two's complement" numbers. translate that. 'I won't swear this translation is right, but it seems to work. xx=xx-1: yy=yy-1 FOR I=0 to 7 BIT TOGGLE yy,I BIT TOGGLE xx,I NEXT IF xx >127 then x% = 255-xx 'move right ELSE x% = -xx 'move left END IF IF yy>127 then y% = 255-yy 'move down ELSE y% = -yy 'move up END IF 'save for next time LastData$=RawData$ LastX=x% LastY=y% END SUB 'Get ONE 3-byte pack of raw data, making sure first byte ' is valid (cf Measurements Systems Inc. document El-312) FUNCTION StickData$(FileNum%) DIM AllByte as STRING, b AS STRING, byt as BYTE DO WHILE (LOC(FileNum%)>1) b$=INPUT$(1, #FileNum%) byt=ASC(b$) IF BIT(byt,6) then 'first byte has bit 6 = 1 AllByte$=b$+INPUT$(1, #FileNum%)+INPUT$(1, #FileNum%) EXIT DO END IF LOOP FUNCTION = AllByte$ 'exactly 3 bytes END FUNCTION 'SUB StickUnParse is the reverse of StickParseData; 'i.e., it translates xjoy, yjoy to a 3-byte string. 'It leaves x,y unchanged but changes RawData$ 'Primarily for use in translating Mouse data into joystick format SUB StickUnParse(RawData$, x%, y%) DIM byt as BYTE, byt2 as BYTE, byt3 as BYTE DIM xx as BYTE, yy as BYTE 'translate X,Y vals into 3 bytes into X,Y values, following 'the protocol of Measurements Systems Inc. document El-312, p. 15 IF x% >=0 then xx = 255-x% 'move right ELSE xx = -x% 'move left END IF IF y%>=0 then yy = 255-y% 'move down ELSE yy = -y% 'move up END IF 'xx/yy are "two's complement" numbers. translate that. 'I won't swear this translation is right, but it seems to work. FOR I=0 to 7 BIT TOGGLE yy,I BIT TOGGLE xx,I NEXT xx=xx+1: yy=yy+1 'the 1st byte holds the most signif. digits of both X & Y IF BIT(xx,6) THEN BIT SET byt,0 ELSE BIT RESET byt,0 IF BIT(xx,7) THEN BIT SET byt,1 ELSE BIT RESET byt,1 IF BIT(yy,6) THEN BIT SET byt,2 ELSE BIT RESET byt,2 IF BIT(yy,7) THEN BIT SET byt,3 ELSE BIT RESET byt,3 'Bit 4 of byt is Right Button status; Bit 5 is Left Button... BIT SET byt,6 'designates 1st byte of 3 BIT SET byt,7 byt2=xx 'bits 0-5 of byt2 are X; bits 6&7 are start & stop bits byt3=yy 'similarly for byt3 & Y BIT RESET byt2,6 BIT RESET byt3,6 'EWM fudge factors... IF x%>=0 then BIT SET byt2, 7 END IF if y%>=0 then BIT SET byt3, 7 END IF RawData$=CHR$(byt)+CHR$(byt2)+CHR$(byt3) 'WARNING! when x=0 or y=0, byt2 or byt3 are somtimes 128 '& sometimes they are 129. This does not seem to be a serious 'error but it should be corrected if Mouse data are important. END SUB
Leave a comment: