9
\$\begingroup\$

I have several boards that communicate together with Rs485. They have ATMega series microcontrollers such as atmega168p or atmega8. Each board is free to send data at any time and I have limitation that lead to I Cant use Modbus. The number of boards can range from 5 to 10.

My problem is: How can a board find if the UART line is free to send data, and if it detects that the bus is busy, wait until bus is free and then send own data?

Is there e special flag or register that could automatically or manually change it and let the other board find that Line is Busy?

\$\endgroup\$
3
  • 4
    \$\begingroup\$ Situations like this would be one of many reasons why RS485 is getting phased out in favour of CAN. \$\endgroup\$
    – Lundin
    Commented Jul 7, 2017 at 13:59
  • 1
    \$\begingroup\$ You should have used CAN bus. Now you have to keep track of layer 2 bus state. \$\endgroup\$
    – Jeroen3
    Commented Jul 7, 2017 at 14:02
  • \$\begingroup\$ how do you About 9bit communication in this case \$\endgroup\$ Commented Sep 29, 2020 at 9:30

8 Answers 8

23
\$\begingroup\$

Welcome to the biggest challenge with half-duplex communications systems.

RS-485 is not a protocol, it's a standard which defines the electrical properties for a half-duplex(*) differential link. There is nothing in the specification about how data is to be sent over that link, or in fact how the link is used.

As such RS-485 transceivers have no automatic "line is busy" signal/flag/whatever, nor will microcontrollers which have built in RS-485 drivers, nor ones which use a UART core connected to an external transceiver.

All implementation of flow control and direction control is left to whatever protocol you use. There exist several well known protocols which use RS-485 drivers, such as Modbus. You can also implement whatever protocol you can think of.

To help you along, these are a couple of ideas for protocols:

  1. You have a master-slave type protocol. In this there is a master node which coordinates the bus, and slave nodes which each have some unique identifier.

    The slave nodes are not allowed to send any data until the master node specifically sends commands addressed to them. Once a slave is addressed, it can then respond to any command in some predefined way - say a fixed length response packet.

    In this case you avoid issues of multiple devices wanting to talk at the same time because the master is there to coordinate everything.

  2. You could use some form of scheduling whereby each device on the bus has a fixed slot in which to send data to any other device. Once its slot runs out it must stop sending and allow the next device to talk.

    The scheduling could be done by the devices themselves without external coordination. The first device talks, and then sends a message saying it is done. The next device (e.g. the one with next higher ID) would know then that it could go. In case a device is not responding you could then have some timeout whereby each subsequent device in the schedule would be able to say - well I haven't heard from the device before me for a while, so it must be my turn.


(*) I believe it also defines a full-duplex version using two differential links.

\$\endgroup\$
6
  • \$\begingroup\$ I think in a multimaster setup as the OP has the biggest challenge is to get newly/reconnected stations in sync with the existing ones, including a possible netsplit. \$\endgroup\$
    – Janka
    Commented Jul 1, 2017 at 23:24
  • \$\begingroup\$ Thanks Tom...I think your 2 suggested way lead to 1 thing... Master Slave approach...its good way if the sender and receiver have enough resource..while using an atmega8 microcontroller, i think its lead to instability on device performance \$\endgroup\$
    – Ali
    Commented Jul 2, 2017 at 6:22
  • 1
    \$\begingroup\$ But i think if use SOF and EOF for a flag to notify to all of board that the line is busy , it could help. but must put a destination board ID to say to a special board that the packet It Is For You , Whats your openion? \$\endgroup\$
    – Ali
    Commented Jul 2, 2017 at 6:27
  • \$\begingroup\$ @combo_ci you can use packet markers (e.g. a byte added to the start to indicate SOF, and a byte at the end for EOF), that helps keep everyone notified that the bus is in the middle of a frame. But you also have to add error/timeout handling to say - well I got a SOF a few seconds/minutes/years ago, but I haven't got an EOF yet. You also need to find a way to make sure two devices don't try to talk at the same time. \$\endgroup\$ Commented Jul 2, 2017 at 9:34
  • \$\begingroup\$ _You also need to find a way to make sure two devices don't try to talk at the same time. _ its my question :) i think there is no standard way to find that .maybe must impliknet by myself \$\endgroup\$
    – Ali
    Commented Jul 2, 2017 at 10:09
9
\$\begingroup\$

It's very similar to radio communication of the military or the police. A protocol is required. Master slave is easy and good for most cases. But another option is to do it like humans do:

  1. Listen.
  2. If someone speaks- wait.
  3. If you think no one speaks- you can speak.
  4. Wait for confirmation.
  5. If no confirmation received- speak again.
  6. If you want to broadcast, ask all stations to confirm listening.
  7. If you want to talk to someone who can't hear you, ask if there is someone else who can relay.

And so on. May be very interesting to implement. Good luck!

\$\endgroup\$
8
  • \$\begingroup\$ This is also used for networking: en.m.wikipedia.org/wiki/… \$\endgroup\$
    – Chara
    Commented Jul 2, 2017 at 4:49
  • \$\begingroup\$ this is good way but have a problem that if (for any reason) a board could nit say I am done the bus is busy for ever ...and if use a timer for detect no busy its force an extra overhead to microcontroller, do you have a way for solve this problem? \$\endgroup\$
    – Ali
    Commented Jul 2, 2017 at 6:35
  • 1
    \$\begingroup\$ There is also a chance that a brutal boy will hammer your device into pieces. Sorry, i didn't say everything is solvable. \$\endgroup\$
    – user76844
    Commented Jul 2, 2017 at 10:31
  • \$\begingroup\$ 😊 By the way thans alot Gregory \$\endgroup\$
    – Ali
    Commented Jul 2, 2017 at 18:51
  • \$\begingroup\$ Interesting way to think about the problem, particularly routing. \$\endgroup\$
    – downbeat
    Commented Jul 7, 2017 at 3:03
3
+25
\$\begingroup\$

Here are a couple of possibilities to solve your dilemma.

  1. Implement a token passing system. When a device has the token, it is allowed to transmit for a limited period of time. It then passes the token to the next device. Provisions for missing nodes that cannot receive and pass the token must be made.
  2. Look at the receive line. If it is busy, generate a random delay and try again. The random delay helps ensure that no one node can monopolize the transmit windows. Collisions can still occur but a check sum feature can determine if the received packet is intact. If it is not intact, the receiver can request a retransmission.
\$\endgroup\$
3
  • \$\begingroup\$ for start number 1 way, a token must send from a board that work as Master ...on a single bus all board receive token, how could a token hold on a board? \$\endgroup\$
    – Ali
    Commented Jul 8, 2017 at 12:11
  • \$\begingroup\$ @combo_ci you can designate a master or you can negotiate the originator of the token by determining the lowest bus address or similar. \$\endgroup\$
    – Glenn W9IQ
    Commented Jul 10, 2017 at 0:44
  • \$\begingroup\$ @combo_ci you could try passing it to a particular device on the line, one you establish the network \$\endgroup\$ Commented Jul 10, 2017 at 14:52
2
\$\begingroup\$

How can a board find if the UART line is free to send data,

the general answer is that without some kind of a protocol, it cannot do so reliably. you typically rely on a controller or arbitrator to see if a line is busy or not. One simple one would be a OD pin pulling an indicator line down before transmission and releasing it afterwards. By reading that line a transmitter can determine if the bus is available or not.

a less reliable but simpler system is to integrate the bus voltage (via a r/c network for example).

and if it detects that the bus is busy, wait until bus is free and then send its own data?

the general approach is to wait a random period of time and retry.

\$\endgroup\$
2
\$\begingroup\$

I solve this problem with my designs such as this way:

instead using 2 pins for comm, I use 3 pins. Within short distances it works. The 3rd pin is line busy indicator. This pin is pulled up from master side. When someone (MCU or whatever) wants to talk:

  • checks this pin state (INPUT).
  • if the pin is HIGH then makes pin low (OUTPUT)
  • and talks.
  • When message is transferred releases the pin (INPUT) (high-impedance) then pin goes high.
  • If the pin is low then waits for some time then goes back to check pin cycle.

This is an implementation of Gregory Kornblum's answer.

\$\endgroup\$
2
\$\begingroup\$

You could use the open source BACnet protocol stack for microcontroller communication on RS485 if you don't want to use modbus. Essentially, it just passes a token around that tells each device when it can send, similar to token-ring topology and Ethernet. Here are a couple of links to get you started:

http://www.chipkin.com/bacnet-mstp-installation-rs485-and-cables/ http://bacnet.sourceforge.net/

\$\endgroup\$
2
\$\begingroup\$

Software flow control

Both software and hardware flow control need software to perform the handshaking task. This makes the term software flow control somewhat misleading. What is meant is that with hardware flow control, additional lines are present in the communication cable which signal handshaking conditions. With software flow control, which is also known under the name XON-XOFF flow control, bytes are sent to the sender using the standard communication lines.

Using hardware flow control implies, that more lines must be present between the sender and the receiver, leading to a thicker and more expensive cable. Therefore, software flow control is a good alternative if it is not needed to gain maximum performance in communications. Software flow control makes use of the datachannel between the two devices which reduces the bandwidth. The reduce of bandwidth is in most cases however not so astonishing that it is a reason to not use it.

Two bytes have been predefined in the ASCII character set to be used with software flow control. These bytes are named XOFF and XON, because they can stop and restart transmitting. The bytevalue of XOFF is 19, it can be simulated by pressing Ctrl-S on the keyboard. XON has the value 17 assigned which is equivalent to Ctrl-Q.

Using software flow control is easy. If sending of characters must be postponed, the character XOFF is sent on the line, to restart the communication again XON is used. Sending the XOFF character only stops the communication in the direction of the device which issued the XOFF.

This method has a few disadvantages. One is already discussed: using bytes on the communication channel takes up some bandwidth. One other reason is more severe.

Handshaking is mostly used to prevent an overrun of the receiver buffer, the buffer in memory used to store the recently received bytes. If an overrun occurs, this affects the way newcoming characters on the communication channel are handled. In the worst case where software has been designed badly, these characters are thrown away without checking them. If such a character is XOFF or XON, the flow of communication can be severely damaged. The sender will continuously supply new information if the XOFF is lost, or never send new information if no XON was received.

This also holds for communication lines where signal quality is bad. What happens if the XOFF or XON message is not received clearly because of noise on the line? Special precaution is also necessary that the information sent does not contain the XON or XOFF characters as information bytes.

Therefore, serial communication using software flow control is only acceptable when communication speeds are not too high, and the probability that buffer overruns or data damage occur are minimal.

high speed CSMA

For high speed like ethernet CSMA carrier sense, multiple access, collision detect/avoidance, with random backoff timers have been analyzed for stochastic probability thruput for optimization.

\$\endgroup\$
-1
\$\begingroup\$

I like the 3 pins approach, but if 2 masters pull the 3rd line low at the same time (which has a low probability but is not impossible over a large number of messages), they will not see that a collision is occuring. Maybe we can pull the line low accross a resistor, and sample the signal level : for instance : VCC/2 => 1 master wants to talk, VCC/4 : 2 masters want to talk... As soon as 2 or more masters are detected during a communication, the sending of the message is considered as unsuccessful, and a retry is done after a random time. The inconvenient of this approach is, it needs 2 pins on the microcontroller : one for pulling the line low, and another one for sampling the analog level of the line.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.