How Can Slave Devices Initiate Communication on an RS-485 Network?

  • Thread starter Thread starter kebo
  • Start date Start date
  • Tags Tags
    Communication
AI Thread Summary
The discussion focuses on improving communication efficiency in an RS-485 network with multiple slave devices. The current polling method leads to delays in data logging, prompting a desire for a more event-driven approach where slaves can initiate communication without a master request. Suggestions include implementing a Carrier Sense, Multiple Access (CSMA) protocol, using a timestamping method from the master, or establishing a clear-to-send line for slaves. Concerns about bus collisions and the complexity of implementing these changes are raised, with some participants advocating for minimal modifications to the existing master-slave structure. Overall, the goal is to enhance responsiveness while maintaining the current hardware setup.
kebo
Messages
5
Reaction score
0
Hi all,

I am working on a project that currently uses an RS-485 network with up to 32 slave devices (pic18f's with various IO and a max 483 driver) connected back to a master PC. The system is running fine, but it could be better.

The only time the master needs data from a device is when a change in the device occurs which is as low as every 30-40 seconds but normally is in the range of 10-20 minutes. When the change occurs, I need to log that time the master. To do this I am having the master poll each device in succession continually and as fast as it can (worst case 3-4 seconds/device if a timeout occurs). Based on this, I could be logging event over a minute too late -not good.

Can anyone tell me how I can change my communication protocols so the slaves send data when it changes without first getting a request from the master? Like a slave only network? Does something like this already exist? I would bet so, but I haven't been able to find details about a reliable method of implementation.

I have have hardware in place and would like not change it if at all possible.
thanks
kevin
 
Engineering news on Phys.org
kebo said:
Hi all,

I am working on a project that currently uses an RS-485 network with up to 32 slave devices (pic18f's with various IO and a max 483 driver) connected back to a master PC. The system is running fine, but it could be better.

The only time the master needs data from a device is when a change in the device occurs which is as low as every 30-40 seconds but normally is in the range of 10-20 minutes. When the change occurs, I need to log that time the master. To do this I am having the master poll each device in succession continually and as fast as it can (worst case 3-4 seconds/device if a timeout occurs). Based on this, I could be logging event over a minute too late -not good.

Can anyone tell me how I can change my communication protocols so the slaves send data when it changes without first getting a request from the master? Like a slave only network? Does something like this already exist? I would bet so, but I haven't been able to find details about a reliable method of implementation.

I have have hardware in place and would like not change it if at all possible.
thanks
kevin

Welcome to the PF.

How do you handle your addressing and address-matching currently? What kind of protocol stack are you running in the Master and Slave devices?
 
I am running something like modbus, but without the registers and complexity. In the master (pc) loop through each device and build that comm packet as follows

Preamble byte
Address byte
Function byte
required data byte array
terminator

The master sends the packet and waits for the device at the address to respond. Every function has a response with the slave address in it. If the function doesn't reply there is a 2-3 second timeout in the master.
 
Last edited:
kebo said:
I am running something like modbus, but without the registers and complexity. In the master (pc) loop through each device and build that comm packet as follows

Preamble byte
Address byte
Function byte
required data byte array
terminator

The master sends the packet and waits for the device at the address to respond. Every function has a response with the slave address in it. If the function doesn't reply there is a 2-3 second timeout in the master.

Since it is the time of the event that is important, can you just have the slaves report the time that it occurred? Do the slave nodes have any timekeeping capability? If not, can the master timestamp each packet that it sends, so that all the slaves can update their local version of the absolute time?
 
I had considered putting a RTC in each device, but had not considered the master timestamp approach. Either way I would like to get away from the whole master/slave approach anyway. No matter how I implement it, I am polling a device once every 30 seconds or so looking for an event that occurs once every 10-20 minutes on average. I would really like to move this system to a slave event driven protocol even if I have to make it up.

I have considered adding a clear to send line that all slaves are on, and if it is high, any device could pull it down, send a packet and release it. Given the amount of time sent between slave packets, I think it would be fairly stable and benign.

I have also considered simply letting a device send a packet if the TX bus is clear. By default, each device is listening to the bus for packet from the master. Once something is transmitted, all of the devices get an interrupt and read the packet (standard modbus). I would guess the interrupt could be used as a not clear to send signal and if there is no interrupt it is assumed the buss is clear. Has anyone ever heard of doing this? Do you see any potential pitfalls?
thanks for your time
kevin
 
kebo said:
I had considered putting a RTC in each device, but had not considered the master timestamp approach. Either way I would like to get away from the whole master/slave approach anyway. No matter how I implement it, I am polling a device once every 30 seconds or so looking for an event that occurs once every 10-20 minutes on average. I would really like to move this system to a slave event driven protocol even if I have to make it up.

I have considered adding a clear to send line that all slaves are on, and if it is high, any device could pull it down, send a packet and release it. Given the amount of time sent between slave packets, I think it would be fairly stable and benign.

I have also considered simply letting a device send a packet if the TX bus is clear. By default, each device is listening to the bus for packet from the master. Once something is transmitted, all of the devices get an interrupt and read the packet (standard modbus). I would guess the interrupt could be used as a not clear to send signal and if there is no interrupt it is assumed the buss is clear. Has anyone ever heard of doing this? Do you see any potential pitfalls?
thanks for your time
kevin

For peer-to-peer multidrop networks, you would usually use a Carrier Sense, Multiple Access (CSMA) protocol. That may be a big addition to your software, however. Perhaps the best way to do this without much change in the software is to:

-1- Have the host broadcast the time every minute or so.

-2- Each slave device keeps a local timer running to know how far into the current minute it is.

-3- When a slave has an event to report, it sends it with "acknowledged service" to the master, along with a timestamp for when the event occurred.

-4- The master sends an acknowledgment to the slave for the message, and the slave re-transmits the original packet if it doesn't receive the ack within a reasonable time period.

Would that work?
 
berkeman said:
-3- When a slave has an event to report, it sends it with "acknowledged service" to the master, along with a timestamp for when the event occurred.

Would that work?
Are you saying that when the event occurs, the device sends it immediately or are you saying the devices respond to the master's time synch?

If the device sends it immediately how do you avoid bus collisions with the potential for 2 devices to have events at the same time (albeit probably fairly remote). Also there would be no need for a timing synch because the master (pc) knows when the packet arrived and could log time that way.

If the device responds to the master, then I have something similar to what I am currently using except with the timing mechanism.
 
kebo said:
Are you saying that when the event occurs, the device sends it immediately or are you saying the devices respond to the master's time synch?

If the device sends it immediately how do you avoid bus collisions with the potential for 2 devices to have events at the same time (albeit probably fairly remote). Also there would be no need for a timing synch because the master (pc) knows when the packet arrived and could log time that way.

If the device responds to the master, then I have something similar to what I am currently using except with the timing mechanism.

The ack'ed service is how you avoid losing information to packet collisions, but implementing it is non-trivial. I suppose that staying with the master-slave polling and just adding the timestamps is the easiest way to improve performance with minimal changes...
 
thanks berkeman. The master slave may be the easiest, but in this case it's not the right solution. I think I'll do some testing and see what I can do.
kevin
 
  • #10
Create a master sync command. Each slave has a timeslot after that command to respond. No data means no response and is OK. Each master sync contains the packet number last received (2 bits would work) for each slave. The slave listens after it transmits to be sure the next sync contains the correct packet number, and retransmits if it doesn't.

FRrom the slaves perspective you just wait until you have data, look for a sync, delay until your timeslot, transmit data, and then verify reception by looking at the number in the next sync.

Most of the time there will be no responses by any slaves.

Another way is for any slave to immediately respond to any poll. If a slave responds and is received, the next poll will have the slave number and its sequence number. If it doesn't, the slave waits a random number of polls (since there was probably a collision) and transmits again. Since each slave will probably wait a different amount the second try will get through. This can work well if there is low probability of collision and the slave transmission rate is small. (there is no timeout since the master only waits a short time before polling again)

In both these cases I'm assuming that the master can poll easily (that is, low overhead)
 
Last edited:
  • #11
@kebo -- one of the keys in most of these schemes is for the slaves to "listen before talking" to avoid collisions. Do your slaves have the ability to sense signalling on the RS-485 bus, or do they just see completed packets? CSMA means sensing that there is a transmission in progress, and not transmitting when some other traffic is ongoing on the network...
 
  • #12
actually sensing collisions with rs-485 is problematic in the sense that two slaves may start transmitting at once and neither know the other is transmitting unless you have some sensitive collision sensing circuits. One way to deal with two slaves at once is similar the random backoff algorithm I stated above. The rule becomes:

1. If no one is transmitting, start transmitting, else wait for the in-progress packet to complete, wait a random or assigned time and then if no one is transmitting, start transmitting.
2. If you don't get an immediate ack, wait a random time (or a assigned time)
3. Go to 1

The random or assigned time delay just needs to be in increments of what can be detected by the slaves. For example, If a slave can sense another slave is transmitting in 4 bit times, then the delays can be in increments of 4 bit times. You need to consider the encoding or have a preamble with a guaranteed characteristic. Also, the slaves need to understand the packets enough to understand when the one in progress has actually ended.
 
Back
Top