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:
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.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
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:
If reading into a string you can read exactly the number of characters waiting: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
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%
CONTENTS |
CONTINUE |