previous page next page reference home emBASIC home page

9 Stream communication

While emBASIC centers on message based communication, there’s still a lot of local stream communication with RS232-devices such as LCD-Terminals, weigh scales or other laboratory equipment, label printers etc.

9.2 Stream I/O

emBASIC uses numbered channels for stream communication. This allows channel redirection and tunneling through a network like for instance BITBUS or Ethernet. By default, all data goes to the channel that is defined by the system variable @console and is also referenced as stdout.

9.4 Configuration

mCAT’s SerDrv offers a number of additional features on receive like programmable start character, programmable end characters (1 or 2), standard character set filtering or user supplied filter etc. To access these, the following array of the system structures can be used. These arrays are indexed by the serial channel number.

 
@SER[channel].SPEED

Set speed in units of bit/s. Allowable values are:

$comBR76800
$comBR57600
$comBR38400
$comBR19200
$comBR9600
$comBR4800
$comBR2400
$comBR1200
$comBR300

 
  @SER[channel].MODE

Select between 7 and 8 bits per character transmission. The console channel requires 8 bits.

com7BPC
com8BPC

  @SER[channel].HANDSHAKE

$comNOHS
$comRTS
$comXON

No handshake
RTS handshake
Software handshake

  @SER[channel].PARITY comNONE
comEVEN
comODD
comMARK
comSPACE
  @SER[channel].STATUS Reading this system variable returns information about the state of the serial line. In the return variable there are flags for character available, character can be sent, DCD active, CTS active, end of file, and input timeout.
Setting @SERSTATUS [channel] = 0 clears waiting INPUTs and INCHARs. INPUTs with timeouts specified continue with the ELSE clause while other INPUTs and INCHARs simply continue with the next instruction.

### SerDrv Handler setting

4.4 The PRINT statement

The PRINT statement is used to output character data through a serial line. It has the following basic syntax:

PRINT [expression [“,” expression . . .] ]

The result of the expression is printed to the standard output (the channel that is set in the system variable @CONSOLE), followed by a carriage return, line feed (CRLF) sequence. If an object is not a string, it is first converted to a string using the rules for string conversions. The (resulting or original) string is then written. More than one expression can be output in one statement by separating the expressions with commas. In the output stream , the expression results are separated with TAB characters (char(9)) with a CRLF following the last expression result. This makes it easy to capture the output for postprocessing in a database or word processor using the log function of your terminal program - just set the import options to field separation by TAB and record separation by CRLF.

In order to suppress the TABs and CRLFs use a semicolon instead of the comma:

PRINT 2;
PRINT "FAST";

would print 2FAST.

The AT() clause

On terminals or terminal programs that support ANSI/VT100 cursor positioning the AT(line,column) extension of the PRINT statement can be used to position the output at a certain line and column on the screen.

PRINT AT(4,20) "5th line, 21st column"

The cursor positioning sequence is written to the standard output channel prior to any other output of the statement except the optional CLEAR keyword:

PRINT AT(10,1) CLEAR, "Hi!"    - or:
PRINT CLEAR, AT(10,1) "Hi!"

Please note the CLEAR likes to be followed by a comma. The positions of the AT(y,x) are integers and the line is the first parameter. Upper left corner is 1,1.

 

Channel selection

With the ON (channel) clause emBASIC allows to switch stream communication (i.e. serial character data transported by PRINT, INPUT and INCHAR) between different output ports.

PRINT ON “(“ channel “)” [expression [“,” expression . . .] ]

Usually, these will be different serial lines but they might also be virtual channels transported by network messaging.

PRINT ON(1) "This goes through SER1"

Usually SER0 is assigned the console and SER1 is open for local peripherals such as a barcode reader, a label printer, or an LCD. See the hardware specific leaflet for details on port assignments.

 

Print formatting

If the expression has a USING(format_string) clause, emBASIC evaluates this expression using the format string before writing the resulting object.

PRINT USING("%###"), 123

would print ###

For the possible format specifiers, please see "Format Specification".

4.5 The INPUT statement

The input statement is used for reading a string from an input channel.

input_line = INPUT [ prompt ] ON( expression )

a = INPUT

would print a “?” at the terminal and wait forever until characters are entered at the console's keyboard followed by a terminating ENTER. The line buffer input is copied to variable a.

Do not use INPUT statements in a TASK as this is likely to produce overrun conditions. A SEQUENCE waiting for an INPUT is in the $STATE_WCHAN as seen from the @<taskname>.STATUS system variable. It yields the processor to other processes until an ENTER (CR) is encountered by the serial line interrupt handler.

There are some options to INPUT:

toolsize = INPUT "Enter tool size: "

prints the string following the INPUT keyword at the standard output channel and waits for the answer to be entered - and terminated by ENTER.

If you are not sure an operator is available at the terminal, you might set up a timeout to be able to handle this situation.

value = INPUT "Number of packages: " MAX 10
   <statements>
ELSE
   value = INPUT CHR$(7), "Enter no. of pckgs - assuming 100 if not entered within 30 seconds now: " MAX 30
   ELSE value = 100
   END
END

### check implementation

This would wait for the operator to enter something within 10 seconds, otherwise it would ring the bell, issue a warning and continue to wait for another 30 seconds before proceeding with the default value.

 

The INCHAR statement

If your terminal does not have an ENTER key or you want to react to each character entered, you may use the INCHAR statement:

char = INCHAR

It optionally takes a channel parameter if INPUT is to be taken from another but the default channel:

char = INCHAR(1)

The SEQUENCE that executes the INCHAR statement indefinitely waits until a character is entered. The only way out is setting @SER[ch].STATUS to 0 which clears waiting INPUTs and INCHARs. INCHAR simply executes the line thereafter found in its SEQUENCE.

 

The INKEY statement

INKEY has the same structure and options as INCHAR with the only difference that it returns immediately regardless of whether a character is entered or not. Hence, to get a character ist must have been entered at the line before the statement is executed.

c = INKEY
IF c=="" THEN PRINT "Nothing entered"