Serial Collision detect

08 Dec 2012

Hello to all. I'm doing a project where I need to check whether serial communication occurs or not a collision. I try to explain (sorry for my english): I have two devices that communicate with the serial port. The first device is the mbed and the second is a pic. Each device sends packets consist of 6 bytes (send one byte at a time). If the device 2 sends a packet and in the meantime the mbed begins to communicate the sequence of 6 bytes from the device 2 is altered. If the sequence of 6 bytes does not arrive in succession the other device can not interpret the information. Currently on the pic is already implemented the system to identify the collision and try to send the entire sequence of 6 bytes after a certain time.

The mbed should do the same thing. If the mbed identifies a collision breaks the communication and try again later to resend the entire sequence of 6 bytes.

Currently I have not found any information about it.

Thanks for your help.

10 Dec 2012

You say you have two devices sending to one serial port. Did you diode-or the electrical interface?

Collision avoidance has to be done by a protocol you write, functionally the same as is done in either TDMA or CSMA/CA systems.

Not hard, but needs a good theoretical basis in design.

It is not common to try this on UART signals as this was not intended. More usually, RS485 is used in such. Or the CAN bus protocol as in automotive data bus multiplexing.

But a two node scheme can be made to work with diode-or'ing.

10 Dec 2012

There's no mention of hardware, so it could quite easily be RS485. Though RS485 isn't guaranteed to "Jam" in the event of a collision.

I guess if there is already a PIC implementation then the poster already has a way of detecting the collision, unless maybe you are using an existing library on the PIC?

Anyway I think the problem is one of reading and writing simultaneously, and on the MBED that seems to entail polling the "readable" and "writable" functions and using byte-by-byte communication e.g. putc and getc.

10 Dec 2012

Thank you all for your answers.

I try to explain the system. I am producing a device for the control of railway plastics (LocoNet protocol).

In the network are connected to different devices, each of which can cominicare at any time. The problem occurs when a device is transmitting the bytes that form the package and a second device begins to communicate. If this happens you have to stop the transmission and resend all the whole package (sent byte by byte).

Unfortunately, the device that uses the pic was not designed by me, so I can not read the source code.

11 Dec 2012

http://www.digitrax.com/static/apps/cms/media/documents/loconet/loconetpersonaledition.pdf Is that it?

It looks as if you need an "open collector" driver, and a collision is detected simply by recognising that the line is low when it should be high. This is done in hardware, though a circuit is not given.

Its not RS232. There is no inversion between the bus and the UART.

11 Dec 2012

As RX and TX are connected to the same line you detect your own collisions by comparing sent data with received data; difference? -> collision. You also need to monitor the line for the CD backoff.

11 Dec 2012

The open collector driver I've already made ​​up and running. I can read the packets sent over the network and I can transmit without problems.

My only problem is the management of resending all the bytes in the case of a collision during the transmission.

Oliver Broad wrote:

collision is detected simply by recognising that the line is low when it should be high

My doubt is: Can I still use the serial library to send and read the packet, or I have to make a timer ISR with management to create a serial?

What I like to do is use the Serial library and add a method for verifying collisions.

thanks to all

12 Dec 2012

You could in fact use the serial library, but you would need to implement some clever protocol and for some features access the corresponding UART registers directly (for the things not covered by the mbed library).

If you must stick 100% to the actual LocoNet protocol, then probably you will have to do the communication by bitbanging.

Otherwise if you can develop your own version, this protocol would for example need messages like "Hello, i want to speak now and am claiming the bus" and "Ok, i finished speaking and am releasing the bus" to be implemented. The claiming message could be a serial break event (line low for at least one serial frame length including stop bits), which can be issued via UART registers. As soon as a node wants to speak, it could set a break condition and set a timer. Then it waits for the break interrupt (break flag set). If the condition occurs too early (before end of frame according to timer value and selected baud rate), then the node knows, that another node has claimed the bus shortly earlier and will reset the break immediately and listen only. The node that wins would release the break condition too and start sending after a make period (line High for at least one frame lenght). All nodes that received a break condition interrupt, which was not their own, will go to listen only mode and will not try to send anything, before the speaking node has finished sending its packets and has sent a bus release message (unique byte frame or combination of frames not present in packet data). Then again all nodes are in idle state, where they are listening or can try sending. If the unlikely case occurs where two or more nodes claim the bus (set the break condition) at almost the same time (indistinguishable timing difference), then a second method should be in place. For this each node has to have a unique identifier (one or more bytes depending of the total number of nodes on the bus) consisting of just one zero bit. This identifier will be the first to be sent in the packet. The sending nodes compare the received identifier to their own. If it's not the same or if a frame error occured, then something must have gone wrong. So they immediately stop sending and after a random (important!) amount of time try to reclaim the bus (another break condition) ... etc.

Best regards
Neni

12 Dec 2012

Thank you all for the answers and for explaining how to proceed. I currently have created the serial pin on p9 (TX) and p10 (RX). the new problem is to write the condition for deciding whether the level of the line is low when instead must be high (in case of collision).

Initially I wanted to change the protocol, but it is not possible because otherwise I would not be compatible with other commercial devices.

18 Dec 2012

I don't think you have to do this on a bit level. It will suffice to compare the byte you have sent with the bytes you receive. Consider using a state machine, after sending a byte you move to state 'wait for echo', when a byte arrives you compare if it is equal to the byte you sent. If equal return to 'idle' and send the next byte, if not equal move to state 'collision' and take appropriate action. When you receive a byte in 'idle' it is a byte from another device on the bus and you add it to the packet buffer.

22 Dec 2012

when I realized the same system based on Arduino I used to find collisions:

# define IS_LN_COLLISION () (((>> LN_TX_PORT LN_TX_BIT) & 0x01) == ((LN_RX_PORT >> LN_RX_BIT) & 0x01))

if ( IS_LN_COLLISION() ) {			 // Collision?
     ......

}

"when a byte arrives you compare if it is equal to the byte you sent" : This method is interesting, but I do not know how to do it. At this moment I do not know how to write this condition.

Happy Christmas and thanks for the help

22 Dec 2012

Isn't that by far the easiest and most straightforward way? You have your TX connected to your open-drain driver input, and RX connected to the drivers output (since there you receive on). Then it is just a matter of putc to write a character, and directly after that you call getc (you must make sure your receive buffer is empty before you call putc). What you get from getc should be the same as what you put on putc. If it isnt, you had a collision.

In that arduino lib I assume a software serial is used? That is of course also possible, then you can detect it direcly if a collision happens, now only after the entire byte has been written.

22 Dec 2012

Of course, this presumes that the bit pattern in the byte just sent cannot be sent by another node.

And.. checking if the receive buffer is empty before sending... won't work due to race conditions.

22 Dec 2012

If the exact same bit pattern is sent by another node is there really a collision? And anyway there is no way to detect that, so no reason to worry about it.

Checking if the receive buffer is empty should work fine, yes of course there could always be a race condition, however then you just get a collision, so not really a problem since you should handle those anyway. It is more that you cant check if the received byte is the same as the sent byte, if there were already 4 bytes waiting in the receive queue.

What I would worry mainly about is how to check if the UART is currently receiving data, a short search in datasheet doesnt give me anything. You can connect it also to another pin which works as interruptin, and checks for UART activity via that, but that isnt ideal. So you need to find something so you dont start sending data when another node is also sending. Granted your collision detection should solve it, but you dont want more collisions than required. Of course due to race conditions you will always have collisions.

27 Dec 2012

All UARTs have two input register buffers; most also have a 16 byte deep FIFO.