RS485 home network with a maximum of 64 terminals.
Published in issue 316, December 2002
Elektor project page.
The backbone of the system is a complete serial bus that uses its own protocol. Data is sent
to and received from a maximum of 64 terminals over long distances using an RS485 interface.
The hardware of the system consists of a simple RS232 to RS485 converter and a microprocessor driven terminal. Of the latter you will obviously need to build as many as are required. The software consists of a program for the PC and one for the 'terminal processor'.
The terminal processor is also sold ready programmed.
This program works with every Pentium-based PC. The PC software runs under Windows 95, 98, ME, NT and XP comes with an example program that controls the inputs and outputs of every terminal, as well as send the 2 x 20 characters that are displayed on the terminals.
For the Elektor article, PCB laout and more: RS485 home network with a maximum of 64 terminals.
The starting point of the system is a program that controls the
serial port of the PC (baud rate = 115,200 bits/s). At the other
end of the serial port sits an RS232 to RS485 converter. This is
done with a fairly simple circuit, which has a MAX232 and a
SN75LBC184 as the most important components.
Then there is an RS485 bus (peer-to-peer) that can have 64 terminals connected to it.
Each terminal contains a compact circuit, using an AT90S8515 processor, a 4021 and again a SN75LBC184. Next there is an eight-bit input port, an eight-bit output port and a connector for a two-line LCD module. Each terminal can be given an address in the range 0 to 63. The 'terminal processor' runs a program that takes care of a number of tasks: communicating with the PC, driving the outputs, reading the inputs, sending text to the display and reading its address that has been set with its jumpers.
So how have the communications been implemented?
The program in the PC (master) can select a terminal (slave) with a certain address, then set the state of its eight outputs, followed by the transmission of data for the display, and finally request the state of its eight inputs. The total time taken for these three functions is approximately 25 ms.
The same procedure is then used for the next terminal. If the same terminal has to be selected again, then this takes an extra 0.8 s, because the data on the display needs to be refreshed first.
When a network needs to transfer small blocks of information over
long distances, RS-485 is often the interface of choice.
The network nodes can be PCs, microcontrollers, or any devices capable of asynchronous serial communications.
Compared to Ethernet and other network interfaces, RS-485's hardware and protocol requirements are simpler and cheaper.
The RS-485 standard is flexible enough to provide a choice of drivers, receivers, and other components depending on the cable length, data rate, number of nodes, and the need to conserve power.
The interface popularly known as RS-485 is an electrical specification for multipoint systems that use balanced lines. RS-485 is similar to RS-422, but RS-422 allows just one driver with multiple receivers whereas RS-485 supports multiple drivers and receivers.
The specification document (TIA/ EIA-485-A) defines the electrical characteristics of the line and its drivers and receivers.
There are brief suggestions relating to terminations and wiring, but there's no discussion of connector pinouts or software protocols.
An RS-485 network can have up to 32 unit loads, with one unit load equivalent to an input impedance of 12k. By using high-impedance receivers, you can have as many as 256 nodes.
An RS-485 link can extend as far as 4000´ and can transfer data at up to 10 Mbps, but not both at the same time. At 90 kbps, the maximum cable length is 4000´, at 1 Mbps it drops to 400´, and at 10 Mbps it drops to 50´. For more nodes or long distances, you can use repeaters that regenerate the signals and begin a new RS-485 line.
Although the RS-485 standard says nothing about protocols, most RS-485 links use the familiar asynchronous protocols supported by the UARTs in PCs and other computers. A transmitted word consists of a start bit followed by data bits, an optional parity bit, and a stop bit.
Two ways to add RS-485 to a PC are on an expansion card and by attaching an RS-485 converter to an existing port. Converters for RS-232 are widely available. On microcontrollers, you can connect an RS-485 transceiver to any asynchronous serial port.
Many network circuits also require a port bit to control each transceiver's driver-enable input. Ports designed for RS-232 communications can use the RTS output.
The main reason why RS-485 links can extend so far is their use of balanced, or differential, signals. Two wires (usually a twisted pair) carry the signal voltage and its inverse. The receiver detects the difference between the two. Because most noise that couples into the wires is common to both wires, it cancels out.
In contrast, interfaces like RS-232 use unbalanced, or single-ended, signals. The receiver detects the voltage difference between a signal voltage and a common ground.
The ground wire tends to be noisy because it carries the return currents for all of the signals in the interface, along with whatever other noise has entered the wire from other sources. And noise on the ground wire can cause the receiver to misread transmitted logic levels.
The datasheets for interface chips label the noninverted RS-485 line as line A and the inverted line as line B. An RS-485 receiver must see a voltage difference of just 200 mV between A and B. If A is at least 200 mV greater than B, the receiver's output is a logic high. If B is at least 200 mV greater than A, the output is a logic low. For differences less than 200 mV, the output is undefined.
At the driver, the voltage difference must be at least 1.5 V, so the interface tolerates a fair amount of non-commonmode noise and attenuation.
RS-485 is designed to be wired in a daisy-chain or bus topology. Any stubs that connect a node to the line should be as short as possible. Most links use twisted pairs because of their ability to cancel magnetically and electromagnetically coupled noise.
Figure 1.An example of an RS485 network.
Each node has a SN75176B transceiver that interfaces between RS-485 and TTL logic levels.
The chip has a two-wire RS-485 interface, a TTL driver input and receiver output, and TTL enable inputs for the driver and receiver.
The circuit has two 120-W terminating resistors connected in parallel,at or just beyond the final node at each end of the link. One end of the link also has two 560-W biasing resistors.
The terminations reduce voltage reflections that can cause the receiver to misread logic levels. The receiver sees reflected voltages as output switches, and the line settles from its initial current to its final current. The termination eliminates reflections by making the initial and final currents equal.
The initial current is a function of the line's characteristic impedance, which is the input impedance of an infinite open line. The value varies with the wires' diameters, the spacing between them, and the insulation type.
For digital signals (which consist mainly of frequencies greater than 100 kHz), the characteristic impedance is mostly resistive; the inductive and capacitive components are small. A typical value for twisted pair is 120 W.
The final current is a function of the line termination, the receivers' input impedance, and the line's series impedance. In a typical RS-485 line without a termination, the initial current is greater than the final current because the characteristic impedance is less than the receivers' combined input impedance.
On a line without a termination, the first reflection occurs when the initial current reaches the receiver. The receiver's input can absorb only a fraction of the current. The rest reflects back to the driver. As the current reverses direction, its magnetic field collapses and induces a voltage on the line. As a result, the receiver initially sees a greater voltage than what was transmitted.
When the reflected voltage reaches the driver, which has a lower impedance than the line, the driver absorbs some of the reflection and bounces the rest back to the receiver. This reflection is of opposite polarity to the first reflection and causes the receiver to see a reduced voltage. The reflections bounce back and forth like this for a few rounds before they die out and the line settles to its final current. If the line terminates with a resistor equal to the line's characteristic impedance, there are no reflections. When the initial current reaches the termination, it sees exactly what it was expecting-a load equal to the line's characteristic impedance. The entire transmitted voltage drops across the load. In a network with two parallel terminations, the drivers drive two lines with each ending at a termination.
The biasing resistors hold the line in a known state when no drivers are enabled. Most RS-485 transceivers have internal biasing circuits, but adding a termination defeats their ability to bias the line. A typical internal circuit is a 100-kW pullup from line A to V+, and a 100-kW pulldown from line B to ground.
With no termination and when no drivers are enabled, the biasing resistors hold line A more positive than line B. When you add two 120-W terminations, the difference between A and B shrinks to a few millivolts, much less than the required 200 mV. The solution is to add smaller resistors in parallel with the internal biasing so that a greater proportion of the series voltage drops across the termination. The size of the biasing resistors is a tradeoff. For a greater voltage difference and higher noise immunity on an idle line, use smaller values. For lower power consumption and a greater differential voltage on a driven line, use larger values.
When the receiver is disabled, the receiver's output is high impedance. If the output doesn't connect to a input with an internal pullup, adding a pullup here ensures that the node doesn't see false start bits when its receiver is disabled.
To comply with the specification, all of the nodes must share a common ground connection. This ground may be isolated from earth ground. The ground wire provides a path for the current that results from small imbalances in the balanced line. If the A and B outputs balance exactly with equal, opposite currents, the two currents in the ground wire cancel each other out and the wire carries no current at all. In real life, components don't balance perfectly; one driver will be a little stronger and one receiver will have a slightly larger input impedance.
Without a common ground, the circuit may work, but the energy from the imbalance has to go somewhere and may dissipate as electromagnetic radiation.
The RS-485 specification recommends connecting a 100-W resistor of at least 0.5 W in series between each node's signal ground and the network's ground wire, as Figure 1 shows. This way, if the ground potentials of two nodes vary, the resistors limit the current in the ground wire.
A better hardware solution.
Figure 2. The RS232 to RS485 converter built round the SN75LBC184 transceiver is superbly simple.
The circuit that converts the signals from RS232 to RS485 follows a very simple design, as shown in Figure 2. The voltage levels of the serial port first have to be adapted for use with the SN75LBC184 and for this we use a MAX232 (IC1). Electrolytic capacitors C4 to C7 are required by the internal DC/DC converter of the MAX232. The specially designed transceiver IC SN75LBC184 (IC3) takes care of the transmission and reception of data. A 75176 may also be used for this transceiver; but this part does not have ESD protection.
Because pin 2 of this IC is connected to ground, any data on the bus is always received. Pin 3 is connected to pin 7 of the serial port (RTS), via the MAX232. The RTS signal of the serial port will be used via the software to enable and disable the transmitter. Jumper 1 is used to connect the terminating resistor. Resistors R1 and R3 that can be connected via jumpers 2 and 3 to the positive supply and ground respectively, make sure that the voltage on the bus is stable when no drivers are active. Since the converter is at the start of the bus we need to use all three jumpers.
A standard 9 V mains adapter can be connected to K3 for the supply. No special demands are made of the mains adapter, because IC3 (7805) provides a properly stabilised voltage of 5 V.
DIFFERENTIAL TRANSCEIVER WITH TRANSIENT VOLTAGE SUPPRESSION
- Integrated Transient Voltage Suppression
- ESD Protection for Bus Terminals Exceeds:
- 30 kV IEC 61000-4-2, Contact Discharge
- 15 kV IEC 61000-4-2, Air-Gap Discharge
- 15 kV EIA/JEDEC Human Body Model
- Circuit Damage Protection of 400-W Peak (Typical) Per IEC 61000-4-5
- Controlled Driver Output-Voltage Slew Rates Allow Longer Cable Stub Lengths
- 250-kbps in Electrically Noisy Environments
- Open-Circuit Fail-Safe Receiver Design
- 1/4 Unit Load Allows for 128 Devices Connected on Bus
- Thermal Shutdown Protection
- Power-Up/-Down Glitch Protection
- Power-Up/-Down Glitch Protection
- Each Transceiver Meets or Exceeds the Requirements of TIA/EIA-485 (RS-485) and ISO/IEC 8482:1993(E) Standards.
- Low Disabled Supply Current 300 µAMax
- Pin Compatible With SN75176
- Industrial Networks
- Motor Control
- Utility Meters
Figure 3. The complete diagram of a terminal circuit. The AT90S8515 controller plays a major part.
The complete circuit diagram for the terminal is shown in Figure 3. Nearly all the work is performed by the AT90S8515 from Atmel (IC2). This microcontroller contains the software that controls the proper functioning of the terminal.
The clock frequency is set to 3.6864 MHz by crystal X1. At this frequency the baud rate generated by the microcontroller is exactly the same as that used in the PC.
For standard crystal frequencies, the most commonly used baud
rates can be generated by using the UBRR settings in Table 1.
UBRR values that yield an actual baud rate differing less than 2% from the target baud rate are boldface in the table.
However, using baud rates that have more than 1% error is not recommended. High error ratings give less noise immunity.
UBRR Settings at Various Crystal Frequencies
The transceiver (IC4) sits between the RXD/TXD lines of the microcontroller and the sub-D connectors (K3 and K4) that are provided for the connection to the bus.
The setting of DIP-switch S1 is read with the help of a shift register (IC1). Switches 1 to 6 determine the address of the terminal. When all six are in an open position, the terminal address will be 63. When all six switches are closed, the terminal address is 0. In total there are therefore 64 terminals that can be connected to the bus. Take care never to put two terminals with the same address on the bus, because both terminals would try to respond at the same time, thereby corrupting the data on the bus!
Switches 7 and 8 in S1 are not used at this stage and can be used to provide extra functions to the terminal. The software for the microcontroller has to be modified for this, of course.
LED D11 indicates that the AT90S8515 is ready to receive data. During the time the terminal is active (receiving or transmitting data), LED D9 is lit. LED D10 and LED D12 are not used, but are provided for any future developments.
Pins 32 to 39 of the microcontroller function as outputs and drive LEDs D1 to D8. The outputs are also connected to a header (K2), to provide an interface with the outside world. The inputs go to pins 21 to 28; these have pull-up resistors (array R6) and header K1 provides an external interface.
The reset pulse is generated by a TL7705 (IC3). Electrolytic capacitor C1 determines the timing of the pulse. As can be seen, the reset pulse for the microcontroller is taken from the inverting output of IC3.
That leaves only the connection of a 2 by 20 character LCD display. This is what header K5 is for. The contrast can be adjusted via P1. Display control lines RS and E are driven by INT1 and INT0 respectively. Pin 5 of the display (R/W) is connected to ground, so it is only possible to send data to the LCD.
A simple 9-V mains adapter, as used for the transceiver board, can again provide the supply for the circuit. This adapter is connected to K6.
8-bit AVR Microcontroller with 8K Bytes In-System Programmable Flash
- Utilizes the AVR® RISC Architecture
- AVR - High-performance and Low-power RISC Architecture
- 118 Powerful Instructions - Most Single Clock Cycle Execution
- 32 x 8 General-purpose Working Registers
- Up to 8 MIPS Throughput at 8 MHz
- Data and Nonvolatile Program Memory
- 8K Bytes of In-System Programmable Flash
- Endurance: 1,000 Write/Erase Cycles
- 512 Bytes of SRAM
- 512 Bytes of In-System Programmable EEPROM
- Endurance: 100,000 Write/Erase Cycles
- Programming Lock for Flash Program and EEPROM Data Security
- Peripheral Features
- One 8-bit Timer/Counter with Separate Prescaler
- One 16-bit Timer/Counter with Separate Prescaler
- Compare, Capture Modes and Dual 8-, 9- or 10-bit PWM
- On-chip Analog Comparator
- Programmable Watchdog Timer with On-chip Oscillator
- Programmable Serial UART
- Master/Slave SPI Serial Interface
- Special Microcontroller Features
- Low-power Idle and Power-down Modes
- External and Internal Interrupt Sources
- Low-power, High-speed CMOS Process Technology
- Fully Static Operation
- Power Consumption at 4 MHz, 3V, 25°C
- Active: 3.0 mA
- Idle Mode: 1.0 mA
- Power-down Mode: <1 µA
- I/O and Packages
- 32 Programmable I/O Lines
- 40-lead PDIP, 44-lead PLCC and TQFP
- Operating Voltages
- 4.0 - 6.0V (AT90S8515-8)
- 2.7 - 6.0V (AT90S8515-4)
- Speed Grades
- 0 - 4 MHz (AT90S8515-4)
- 0 - 8 MHz (AT90S8515-8)
The AT90S8515 is a low-power CMOS 8-bit microcontroller based on the AVR RISC architecture.
By executing powerful instructions in a single clock cycle, the AT90S8515 achieves throughputs approaching 1 MIPS per MHz, allowing the system designer to optimize power consumption versus processing speed.
INTERFACE PIN CONNECTIONS.
|PIN No||Symbol||Level||Pin description||Functions|
|2||Vdd||-||Supply volltage for logic||5V± 5%|
|3||Vo||Contrast adjustment||Decision by user system|
|4||RS||H/L||Register selection||H:Data input L: Instruction code input|
|7||DB0||H/L||Data bit 0|
|8||DB1||H/L||Data bit 1|
|9||DB2||H/L||Data bit 2|
|10||DB3||H/L||Data bit 3|
|11||DB4||H/L||Data bit 4|
|12||DB5||H/L||Data bit 5|
|13||DB6||H/L||Data bit 6|
|14||DB7||H/L||Data bit 7|
Figure 6 shows how three terminals should be connected to
the bus and where the terminating resistors are to be placed.
As mentioned earlier, the address of the terminal is set using the first six switches of DIP-switch S1. The example in Figure 7 shows an address of 12 (binary value 4 + 8 = 12). Jumpers JP1 and JP2 in the terminal circuit are for use at the start of the bus (parallel resistors of 470 ohm to 5 V and GND respectively). Jumper JP3 is used to connect the 120 ohm terminating resistor; in Figure 6 terminal 12 is at the end of the bus, so it has this jumper closed.
Figure 6. A practical example of a bus with three terminals.
Figure 7. The terminal address has been set to 12 using DIP switch S1.
When the supply (a standard 9 V mains adapter) is connected, LED D9 will light up after a short period. This indicates that the IC is ready to receive or transmit data. If a liquid crystal display has been connected to the terminal, the following text will appear: 'DCI-BUS Addr: 12' 'waiting for data.U'
The number 12 is the value of the address that has been set for that terminal. The 'U' at the end of the second line is the version number of the software in the microcontroller.
After the hardware has been connected and the software started, the correct port has to be set up. Click on 'Select port' from the 'Ports' menu and choose the required serial port. Now click on 'Open port' from the 'Ports' menu and a dialogue box should appear stating that the port has been opened successfully. When a port has been selected that doesn't exist then the message 'The system cannot find the file specified' appears. Next click on 'Run' from the 'Bus' menu and the program will be in RUN-mode (see Figure 8).
Figure 8. A screenshot of the program in RUN mode.
Next to each 'SetStation' button is an up/down component that can be used to select a terminal number. Then click on the 'SetStation' button and the terminal will be on-line; to the left of the button the number of the selected terminal will appear. From now on the text that is in the two text boxes will appear on the display of the selected terminal and the outputs that have been ticked will be set. At the same time the state of the inputs is also shown. The software can be used to control up to four terminals simultaneously.
The 'adjust bus' up/down button is used to set the so-called 'critical section' to a time between 0 and 20 ms. A value between 3 and 6 works well on a Pentium 400 and 475. This option is probably more useful with the current generation of PCs, which are much faster. Because a program running under Windows doesn't work in real-time, there is a possibility that errors can occur on the bus.
This can be seen clearly in the diagram in Figure 9.
Figure 9. The RTS signal has to be 'low' when a terminal transmits data back, otherwise the data will be lost.
If the RTS signal at the serial port is not 'low' before a terminal returns data, then this data will be lost. This can happen when the operating system (Windows) deems it necessary to use all processing time for a different process, such as starting other software, dealing with a newly inserted CD, screen saver, anti-virus software, etc. Because of this, the RTS signal will sometimes not go 'low' in time.
This can be avoided by adding an error-checking routine to the software that prevents erroneous readings of the terminal inputs. This has been implemented as follows:
- The transmit-enable output of all terminals will be 'low'.
- The PC sets its RTS signal to 'low'.
- The PC transmits 2 x ASCII-code 10 on the bus.
- The PC puts the address of the terminal to be accessed on the bus.
- The PC puts the value for the outputs of the terminal on the bus.
- The PC sets its RTS signal to 'high'.
- The terminal with the correct address sets its transmit-enable to 'high'.
- The terminal puts its address on the bus.
- The terminal puts the status of its inputs on the bus.
- The terminal puts its address on the bus again.
- The terminal with the correct address sets its transmit-enable to 'low'.
- The PC software checks that the first byte received is equal to the address that has been transmitted.
- The PC software stores the value of the second byte (state of the inputs).
- The PC software checks that the third byte received is equal to the address that has been transmitted.
- If checkpoints 11 and 13 return the correct result, the PC uses the value returned in step 12 as the new state of the inputs. If either check failed then the software will wait for a cycle that has no errors.
In this way we can be certain that the inputs will always be read
correctly. Every time an error occurs, a message is shown with
the number of the terminal that caused the error. When we use the
software to enable a terminal that is not present on the bus then
this error message will also appear.
When our simple RS232 to RS485 converter is replaced by a microcontroller version with a data buffer, the whole communication problem will no longer be an issue. Such a converter is therefore a likely candidate for a future project.
Now for some general information about the software:
The accompanying software for this project comes on a disk (EPS010113-11), which can also be downloaded from the Elektor website. Apart from the PC program it also comes with the source code, written in C++ (Builder 4). The source code and HEX listing for the microcontroller are also on this disk. With these the system can be adapted as much as the user requires.
When modifying the software you should take into account that the terminal requires about a second to refresh the data on its display. Consequently there has to be a delay of one second before the same terminal can be selected again. This delay has to be programmed into the software of the PC!
Furthermore, it is not permitted to include the character with ASCII-code 10 in the text for the LCD, since this character is used to initiate the selection of a terminal!
The Busmstr.exe program contains a simple COM (Component Object
Model) server interface. This allows an external program, such as
Excel or Visual Basic, to start the Busmstr.exe program and use
it to drive the hardware
As an example:
- First start the Busmstr.exe program and then close it.
- Start Excel, open the file 'Client.xls' and start the 'Visual Basic Editor' (Alt + F11).
- From the 'View' menu select the 'Object Browser' (F2).
- Place the mouse pointer over the 'Object Browser' pane and click on it with the right-hand mouse button.
- Click on 'References' in the pop-up menu.
- Choose 'Browse' from the 'References' dialogue and choose as file type 'Executable Files ("*.exe,*.dll")'.
- Navigate to the folder where Busmstr.exe is and choose Busmstr.exe and click on 'Open'.
- In the 'Classes' window there should now be an object with the name 'TBusServer'. Click on this and the members of the TBusServer object appear in the right-hand window. These should be 'About', 'InputGet', 'LCDTxt' and 'OutputSet'.
- Return to Excel and click on the 'INFO' button.
- The Busmstr.exe program is then started automatically. Choose the correct serial port, open it and start the bus.
- Click on 'Server mode' in the 'Options' menu.
- Set a terminal to number 4 and start it using the 'SetStation' button.
- Go back to Excel and close the dialogue box containing Info about the Busmstr.exe program.
- Now click on the 'Refresh' button. The number in box C4 represents the state of the inputs to terminal 4. The text in box C8 appears on the LCD of terminal 4 and the number entered in box C6 is copied to the outputs of terminal 4. The text in box C8 must not exceed 40 characters in length.
- Now go back to the 'Visual Basic Editor' window and select 'Design Mode' from the 'Run' menu.
- Return to Excel and click with the right-hand mouse button on the 'Refresh' button and choose the option 'View Code'.
Dim BusCOMServer As New TBusServer
Dim a As Integer
Private Sub CommandButton1_Click()
Dim S As String * 40
Dim x As Long
Range("c4").Value = BusCOMServer.InputGet(Range("a4").Value)
Range("c10").Value = BusCOMServer.InputGet(Range("a10").Value)
BusCOMServer.OutputSet Range("a4").Value, Range("c6").Value
BusCOMServer.OutputSet Range("a10").Value, Range("c12").Value
' set lcd text
S = Range("c8").Text
BusCOMServer.LCDTxt Range("a4").Value, S
S = Range("c14").Text
BusCOMServer.LCDTxt Range("a10").Value, S
Private Sub CommandButton2_Click()
Dim S As String
S = BusCOMServer.About()
Response = MsgBox(S)
- Now the code can be edited. This should be studied with a view of possibly automating the Excel worksheet further.
1. If the Busmstr.exe program has been started via Excel, it will be closed every time 'Design Mode' is entered.
2. Never close the server program (Busmstr.exe) while the client program (Excel in this case) is still running!