you are here: home bare essentials barefoot blog RS485 collision avoidance on PIC24s

RS485 collision avoidance on PIC24s

February 2012

I had an interesting technical conundrum recently - how to stop several devices on an RS485 network from all trying to transmit their packets at the same time.

Collision avoidance works by virtue of a device detecting that the network is busy, and then waiting for some random amount of time before trying again. Without the random element, devices of identical hardware and software will repeatedly try to do the same thing at the same time...

The problem was that all of these devices were based on the Microchip PIC24, with no immediately obvious source of random numbers. Unlike devices from the PIC18 and 16 families, all PIC24 processor registers have precisely defined power-on/reset values as far as I can see.

After some research, I happened across a suggestion on the Microchip forums to use data memory as a source of undefined data. I disabled C's usual initialisation of RAM on start-up (MCC30 linker option -Wl,--no-data-init), power-cycled a box, and sure enough, RAM is undefined on power-up. Contents seem to vary little between successive power-cycles, but crucially do vary between processors.

Excellent, getting somewhere. Now for a prototype implementation.

First step was to create a random number generator in C. I allocated four bytes of RAM as a 'long forward shift register', and of course these four bytes are well-seeded with 'random' data due to RAM's undefined POR state. I then reworked Tom Wiltshire's assembler LFSR implementation into a C routine that produces a new random byte on each call.

Second step was to introduce randomness into RS485 transmission attempts. I created a state machine that first samples the PIC24 UART 'bus busy' status for a random time frame 1-64ms. If the bus is clear throughout, great, the packet is transmitted. If the bus is busy at any point during the sampling phase, a new random time frame 1-64ms is picked, and the state machine waits for this period. When the wait expires, the state machine enters a new bus sample phase.

Using a test rig where one box broadcasts a request, and everyone else replies (notionally at the same time), initial trials on a network of 10 devices were entirely collision-free. But scaling up to 40-odd devices was less successful, so the bus sample and back-off states were changed to pick random time frames 1-128ms. Much better results were achieved.

I'm very pleased. RS485 network collisions successfully fixed.

See also:-
Last Updated on Wednesday, 12 December 2012 13:23

navigate to...