RS485 Master.txt

Warning: if you clip this code into your program, look out for possible html code slipping in.

REM   Simple master program for testing RS485 networking with an SBC2000-074.
REM
REM   Copyright 1998 Vesta Technology, Inc.
REM   All rights reserved.
REM
REM   This program will "poll" several slaves, and display the responses on the
REM   LCD. Each slave's display will consist of a pair of numbers on the top
REM   line of the LCD (the slave's station number and its count of messages),
REM   and one number on the second line of the LCD (the master's count of failures
REM   communicating to that slave).


REM   We will set up for a maximum of 5 slaves, numbered 0-4

CONSTANT max_slaves AS INTEGER = 5


REM   This bit will be set when the COM port is idle, and clear when the
REM   COM port is busy.

GLOBAL XMTR_EMPTY AS BIT = 0x98,1


REM   Set up a subroutine to control the Push-To-Talk signal going to the RS485
REM   board. We are using pin 1 of the DIO connector, which is bit 4 of port D.

SUBROUTINE PTT(state AS INTEGER)
STATIC PTT_BIT AS BIT = 8,4
	PTT_BIT = state
END


REM   When an INPUT statement fails because no response was received in time,
REM   we need to detect that fact and clear the error. If we don't, subsequent
REM   INPUT statements will fail because of the error, even if they have
REM   received input. Note that if you compile with debug, you can replace the
REM   address 0x3B with the name IDE_Error_Code.

VITAL SUBROUTINE ErrHandler(errtype AS INTEGER)
	IF errtype = 88
		POKE(0x3B, 0)	: REM   Clear error code if it's "timeout"
	ENDIF
END


REM   We are going to simulate an array in RAM, because the "failures" array
REM   could cause excessive writing to the EEPROM if we used a normal array.
REM   We will build our simulated array by setting a base address counting
REM   backwards from the end of global RAM. Note that we will not get any
REM   warnings from the compiler if these addresses are used by other variables.

FUNCTION failures(which AS INTEGER) AS INTEGER
	IF IDE_Board() = 2
		failures = 126
	ELSE
		failures = 158
	ENDIF
	failures = failures - 2 * which
END


REM   Declare the variables we need.

GLOBAL slave AS INTEGER
GLOBAL j AS INTEGER
GLOBAL slv_num AS INTEGER, response AS INTEGER

CONSTANT CR AS STRING = "\013"


REM   Initialize the failures array

FOR j = 0 TO 4
	DPOKE(failures(j), 0)
NEXT j


REM   By default, INPUT will wait forever. We don't want this, because that
REM   would mean that a missing slave or other problem could cause this
REM   application to hang forever. Therefore, we set up a limit on how long
REM   INPUT will wait before aborting with an error.

POKE(0x29, 50)		: REM   Set up timeout of about 1/2 second


REM   Now execute the main loop of the application. We will send a slave's
REM   ID number, then wait for a response from the slave.

DO WHILE 1
	FOR slave = 1 TO max_slaves
		PIPE PRINT COMM0
		PTT(1)				: REM   Assert push-to-talk
		PRINT slave, CR			: REM   Address the slave

		REM   A minor delay to allow the last character to complete
		REM   before releasing push-to-talk.
		DO
			REM
		LOOP UNTIL XMTR_EMPTY
		PTT(0)

		INPUT slv_num
		INPUT response

		REM   Check to see if we got a good response from the slave

		IF slv_num <> slave
			DPOKE(failures(slave), DPEEK(failures(slave))+1)
		ENDIF


		REM   Print information about what's going on.
		REM   Along the top line of the LCD, print the latest response
		REM   from each slave.

		PIPE PRINT LCD

		LCD_Command(0x80+8*(slave-1))
		PRINT slv_num, response
		LCD_Display("   ")

		REM   Along the second line of the LCD, print the count of
		REM   failed responses from each slave.

		LCD_Command(0xC0+8*(slave-1))
		PRINT DPEEK(failures(slave))
		LCD_Display("   ")

		REM   Delay to allow the slave time to release push-to-talk
		FOR j = 0 TO 10
			REM
		NEXT j

	NEXT slave
LOOP