Serial and patallel ports can only be accessed by one application at a time, so if a port is currently in use by another program, BBC BASIC will not be able to open it (the OPENUP function will return the value zero).
Because BBC BASIC automatically appends a ".bbc" extension to a filename, by default, you will need to add a "." suffix to suppress this:
device$ = "COM3:" : REM Windows device$ = "/dev/ttyACM0" : REM Linux device$ = "/dev/cuACM0" : REM MacOS port% = OPENUP(device$ + ".")
A complication is that in Linux-based Operating systerms it is necessary to set the serial parameters before opening the device but in Windows it is done after opening the device. The following code takes account of this and sets the baud rate to 9600:
CASE @platform% AND &F OF
WHEN 1: REM Linux
OSCLI "stty -F " + device$ + " 9600 -echo raw"
WHEN 2: REM MacOS
OSCLI "stty -f " + device$ + " 9600 -echo raw"
ENDCASE
port% = OPENUP(device$ + ".")
IF port% = 0 THEN REM Handle failure to open device
CASE @platform% AND &F OF
WHEN 0:
IF @platform% AND &40 f%% = ](@hfile%(port%)+56) ELSE f%% = !(@hfile%(port%)+28)
DIM cto{d%(4)}
SYS "SetCommTimeouts", f%%, cto{} TO res%
SYS "PurgeComm", f%%, &F TO res%
DIM dcb{d%(6)}
SYS "BuildCommDCBA", "9600,n,8,1", dcb{}
SYS "SetCommState", f%%, dcb{} TO res%
ENDCASE
For setting additional parameters (parity, number of stop bits, handshaking etc.) see the description of the
mode command
in Windows and the stty command in Linux or MacOS.
The above code appends a Carriage Return (&0D) to the string, to suppress that use:PRINT #port%, mydata$
BPUT #port%, mydata$;
To avoid your program 'hanging up' while waiting for data on a serial port, you can use the EXT# function to discover how many characters (if any) are waiting to be read. If you read only that number of characters you can guarantee that your program will never be waiting a long time for data to arrive:
REPEAT
chars% = EXT#port%
IF chars% THEN
FOR count% = 1 TO chars%
mydata& = BGET#port%
REM. Do something with the data
NEXT
ENDIF
REM. Do something useful here
UNTIL FALSE
If reading into a string you can read exactly the number of characters waiting:
REPEAT chars% = EXT#port% IF chars% THEN mydata$ += GET$#port% BY chars% UNTIL FALSE
The EOF# function and the PTR# pseudo-variable are not meaningful in the case of a port, and if used will result in the Invalid channel error.CLOSE #port%
|
CONTINUE
|