Detect ongoing UART reception

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I'm using the ATtiny1614's UART with a half-duplex RS-485 driver to connect multiple devices on a shared bus. To avoid data collisions, I'd like to determine whether the UART is currently receiving data before starting to send data myself. This is only a best-effort solution, nothing like the robustness of CAN. But if the device can see data currently coming in, it shouldn't start shouting against that (enabling the driver), knowing better that this won't help anybody.

 

I've found the start frame detection feature, but it's documented to work only in standby/sleep modes, not when active.

 

Is there another way to find out whether the UART currently receives data, before the reception is complete and the Receive Complete interrupt (RXCIF) is set?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

use an edge detect to spot the start of the Start bit ... ?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Usual for 485 is to use TXC. Only switch to output when transmitting then use the TXC interrupt to know when the very last bit has gone down the line then switch back to receive. You cannot really do any more than that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Usual for 485 is to use TXC. Only switch to output when transmitting then use the TXC interrupt to know when the very last bit has gone down the line then switch back to receive. You cannot really do any more than that.

 

I know that the driver must only be enabled during sending. That's already in place, and here covered by the UART's RS-485 mode and XDIR out pin. My device can send and receive so that works.

 

But I still have a choice when I actually start sending. I'm currently trying to test the method suggested above, to watch the RX pin for changes. Setting up an experiment now. I'm not sure I can read the RX input pin while it's used by the UART receiver, but I'll see.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 But if you have an additional spare I/O pin you can also attach it to the USARTs Rx pin, and then use the "extra" receiver monitor pin to monitor for incoming traffic.

 

You don't use the extra Rx pin to capture and decode the incoming traffic, you just use it to see if there is traffic on the bus.

 

Since you know the baud rate, you could also use a timer/counter to tell when, after the last activity on the pin was detected, it is safe to assume that that transmission has completed.

(Of course another transmission could be just about to start..., but that is a harder process to detect, if you don't have a Master telling them when to transmit their data)

 

JC

Last Edited: Sat. Dec 28, 2019 - 03:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ygoe wrote:
Is there another way to find out whether the UART currently receives data, before the reception is complete and the Receive Complete interrupt (RXCIF) is set?
Yes if auto-baud (BDF - Break Detected Flag)

BREAK, SYNC, data

ATTINY1614 - 8-bit Microcontrollers

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you implementing a "speak when spoken to approach"...so the only unit that should be attempting to send a reply is the unit that was just queried?  If you can get away with that, it offers a low probability of contention. Of course, there can be noise, resets & so forth that can impact the sanctity of this approach-so some error handling/recovery must be included.  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies suggestion is very closely related to "token passing" - only the device that has the token can talk. Networks vary widely on how the token is managed. In some cases, there is a master that hands out tokens (e.g. talk permission). In other cases, it is passed from device to device. With care, this can be very effective. 

 

In some wireless networks (e.g. ham packet radio), carrier-sense multiple access (CSMA) is used. One way to do this in general networks is as follows:

 

1) Do NOT send if a message from somewhere else is in progress. This is the carrier sense part. In a wired network without a real "carrier", edge detection can substitute.

 

2) Any sender message REQUIRES an acknowledgement within a specific time slot after the completion of the message.

 

3) If a sender originates a message and no ack is received, then it is assumed that there was either a fault at the destination or there was a collision from another device sending at the same time. 

 

4) Lacking an ack, a quasi-random holdoff time is executed. If there was a collision, then the other device(s) will do the same but, in theory, have different hold-off times. 

 

5) The first holdoff to expire will start its message. Others will not transmit because of the detected in-progress message.

 

6) Other devices desiring to send will wait a random time after the last activity (carrier). This will avoid collisions from two waiting devices trying to send at the same time.

 

Jim

 

 

 

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk, that (the CSMA thing) is what I was thinking of. I'm building a network of nodes that can be spoken to by the network master and will reply each message they receive, but that can also speak to the master on any event, like when the human has pushed a button or something else has happened and needs to be reported immediately, like water has been detected, or motion, or light. The master must also reply to each of these "reverse commands". In theory, a slave node can also speak directly to another slave node (I need an addressing scheme anyway), but I'm not going to use this for now. The master should always know the slaves' state and coordinate any actions.

 

Additionally to your list, it needs to be thought of what happens when the ACK message is lost. The sender cannot distinguish whether the command or the response was lost, and will resend the command. In this case, the command must be idempotent, so the same command sent twice will not change the state any further. And since the master knows the desired state of each slave, it can safely request that multiple times, until the desired state changes due to some decision. Then, a different command will be sent.

 

It's going to be interesting what happens should I introduce some form of global or group broadcast addressing… ;-)

Last Edited: Sun. Dec 29, 2019 - 12:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and needs to be reported immediately, like water has been detected, or motion, or light. 

Take care here, since what seems immediately in our world is a looong time in the AVR world, even when sending tokens around.  If you say 1/3 of a second...that's a long time & give you plenty of processing time to handle things. 

 

You could prob have 20 nodes & query each 25 times/sec to see if they have anything to report or to request...that would be "immediate" in terms of responding to a water alarm.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!