How to determine 485 network is not busy in half-duplex


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default How to determine 485 network is not busy in half-duplex

    Hello o All-
    I have searched this and other forums in an effort to gain some insight on a consensus may be for collision avoidance in half-duplex 485 networks. Some really interesting items were discovered such as the paper on acoustic networking with applications in underwater communications - pretty cool but not overly helpful.....

    I have been working on a project which when finished will provide a backbone to some level of home automation (everyone needs a hobby). I have several PICs on a common 485 half-duplex network which is opto-isolated. I have base code which uses serial interrupts on the 2 serial ports - Thanks DT! - but I am now trying to figure out the best way to sense if the 485 network is busy and avoid collisions.
    The reason for 2 networks is one is the 'node' network which has the controllers and the other is the 'stub' network which has all the lower-functioning pics that actually turn on/off stuff.
    Essentially, the nodes all talk to each other while the stubs only talk to their respective node. Seems a bit overkill but it keeps the traffic to a minimum, PICs are cheap, and its a hobby.

    I think in general terms, I check to see if my receive buffer has anything in it (RCREG1 or RCREG2) if not, wait some time (address of node times 10uS?), see if my buffer is still empty, if so -> transmit my packet.
    As the nodes are all addressed, any packet which does not have the local node's address in the node byte, the local node just zeros out the variables and waits for another sync byte to be received.

    I am using a PIC18F46K80 running at 64mHz, network speed of 57.6k and at an estimated packet length of no more than 10 bytes, I shouldn't have too much trouble.
    But, as several here in this forum have inspired me to do better, I was curious what others may have done or what they think - without compromising any secrecy......
    Am I on the right track?

    Regards to All.
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517

    Default Re: How to determine 485 network is not busy in half-duplex

    Hi,
    As far as I know a half duplex RS485 bus is used in master/slave type networks where a slave never initiates communications on its own, it only responds to queries from a master. That way there's no risk for collision because the master is "in control" of the bus, it sends and it knows when to expect a response.

    With that said making sure the bus is silent and then simply start sending is about all you can do. There will always be that slight possibillity of two devices doing the same thing at exactly the same time but hey, what can you do.

    Checking if there is a byte in the receive buffer doesn't really say anything because even if the buffer is empty there might be a byte on its way in. And even if you wait x amount of time and again check the receive buffer there's NO guarantee that there's not a byte on its way in THIS time.

    I think you need to poll the actual reciever output and make sure it's idle for at least one bit time and then just take your chanses and fire off the message. If the overall load on the bus low (ie it's silent most of the time), the hardware is designed to survive bus contention and you have some form of error checking (CRC etc) then it might work by implementing some sort of "message received reply" of some sort.

    I've never worked with it but for this sort of application CAN might be a good fit.

    Another way, which I haven't really thought thru yet, might be to have a master continously quering each node in sequence, allowing each one a window of time within which it's allowed to respond. Ie, when a node wants to speak it buffers the message and waits for its turn. Node 1, you've got 2ms of "airtime" - go, Node 2, you've got 2ms of "airtime" - go.

    /Henrik.
    Last edited by HenrikOlsson; - 21st May 2014 at 07:43.

  3. #3
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166

    Default Re: How to determine 485 network is not busy in half-duplex

    Ecoli-557, I use RS-485 for communications with 5 dual axis tracking solar arrays. As Henrik has mentioned in his first sentence, Half duplex RS-485 should have a master to solicit the communications. That way you dont loose data to collisions. If the structure were full duplex,(4 wire) then you could have the slave units request data from the master or even other slaves. This type of communications can be done with half duplex but, you need to seriously think about the protocol to be used.
    Dave Purola,
    N8NTA
    EN82fn

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default Re: How to determine 485 network is not busy in half-duplex

    Half-Duplex RS485 is fully capable of Multi-Master mode.
    The key is a fairly complex Arbitration process.

    There is a description of the arbitration process in the Microchip appnote AN1230.
    I couldn't find it on microchip.com, so I've attached it here.

    One thing not mentioned in the appnote is the RCIDL bit in the EUSART, which indicates when data is being received (even if there's nothing in RCREG yet).
    I think that bit will help in detecting the bus idle state.

    See page 3 for the arbitration process (J1708 NETWORK ACCESS).
    Attached Images Attached Images
    DT

  5. #5
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Re: How to determine 485 network is not busy in half-duplex

    Thanks Henrik, Dave and Darrel!
    I was forlorn late last night - felt a bit better so I thought I would tackle my own idea, only to find out I do NOT have write privileges to the RCREGx register, and as it now seems, that would not be the way to go.
    Darrel, I will read this over and see what I can do with it, I completely missed the RCIDL bit as it was buried in the Baud Rate Generator section, but, sure 'nuff on page 349 of 622 (who REALLY calls these things datasheets any more? I can remember the old 7400 data sheet........) it does say:
    'To assure that no actual data is lost, check the RCIDL bit to verify that a receive operation is not in process.' Dang that Darrel, his frontal lobes must be HUGE! Thanks for that Darrel, I'll try some stuff tonight.

    I am hoping that it can be done effectively using 2 wire, but as its just for me, I can change to 4 wire or use an 'attention' line if need be, just not as cool.

    So, according to the app note, this looks a lot like the forunner to CAN? I have worked with CAN and found it too troublesome - even for work solutions which is why I wanted to use 485 and figure out my own or use someone else's with any changes.

    One thing I had not thought about before reading the app note (Thanks again), it looks like I can set priorities, something I had not thought of - thought the nodes would arbitrate that....... The note's logic is pretty much what I started with, without MIDs and the nifty way of determining message priority delays. The part about determining bus idle is also interesting. This J1708 protocol might just be the ticket.

    Its interesting that the data into the 485 chip goes into the DATA ENABLE while the DATA INPUT is held at ground and the result is apparently NO electrical bus contention.
    I have my 75LBC184 wired in the conventional sense with RE/DE tied together and driven by the proc as a 485 ENABLE and the TX and RX going to their re3spective inputs/outputs.

    So, if I use the 'standard' 485 wiring, I should be able to follow the note as:
    The steps to arbitration are as follows:
    1. Wait for the bus to become Idle.
    2. Wait the required priority delay after the Idle period has started.
    3. Make sure the bus is still Idle. If the bus is not Idle, go back to step 1.
    4. Transmit the device MID (or my address of the node) on the bus.
    5. Receive the transmitted MID and determine that the sent MID matches the received MID.
    6. If the match was successful, we have claimed the bus. Send the packet.
    7. If the match failed, we lost the arbitration. Continue to step 8.
    8. If this was the first collision for this packet, go to step 1.
    9. Wait for the bus to become Idle.
    10. Wait for a pseudo-random number of bit times (between 0-7).
    11. Go to step 3.

    Has anyone else use this? I'll start coding a trial tonight!
    Thanks Guys, this will help!
    -Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  6. #6
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947

    Default Re: How to determine 485 network is not busy in half-duplex

    I have done multi-master RS485 many years back. I found the AN01230 interesting in how they achieve the multimaster operation.

    What I did involved a little an extra 485 chip, but, essentially utilised the same principles.

    I had a main RS485 transmitter and a separate RS485 listener chip on the same board. Whatever goes out the transmit line is visible back again on the input line via the listener chip. So, any data corruption due to a collision can be detected and the transmit process can be re-started. The rest of the arbitration process is essentially the same except I use discrete IDs for each RS485 station like in any such multi-device setup and the system worked very well.

    You can stop transmitting the moment you see a single byte error in your packet - when sent character is not same as received character.

  7. #7
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Re: How to determine 485 network is not busy in half-duplex

    Thanks Jerson. I made the mistake of already having the board made so I would like to try to see if I can do it with just one 485 transceiver. The J1708 looks like it is still being used and if I cannot get a modified J1708 protocol to work with a 485 connected the normal way, then my next try would be to try an actual J1708 transceiver. Maxxim makes one and it look as if it would be a drop-in replacement so I would have the expense of re-doing the board design.
    I think I have base code working but for some reason the 485 enable line sits high - even after the packet should have been delivered..... which tells me the program thinks there is still stuff to transmit...... looking into it now....
    Regards,
    Steve

    Code below:
    Code:
    Node_ErrChk:'-------------------------------------------------------------------
    'Checks the received node packet for data integrity and sends an ACK if good or a NAK if bad
                      NodeWord=Node_Addr+Node_Cmd_Resp+Node_Bd+Node_Port_Dev
                      Node_Sum_temp=NodeWord.byte0 ^ $FF                            'Creates a local temp sumcheck used for comparison
                      if Node_Sum_Temp <> Node_Sum then                             'If the received checksum and the local checksum don't match, then.... 
                         error=1                                                    'Turns ON error LED
                         Node_Cmd_Resp=$03                                          'Form our NAK response
                         Node_Addr=Address                                          'What our local address is
                         Node_Bd=0                                                  'Doesn't matter, we are asking for a retransmit
                         Node_Port_Dev=0                                            'Same as above
                         NodeWord=Node_Addr+Node_Cmd_Resp+Node_Bd+Node_Port_Dev     'Create our checksum
                         Node_Sum=NodeWord.BYTE0 ^ $FF                              'ditto
                         ncts=1                                                     'Enable transmission of 485 interface
    NodeLineBusy2:       if BAUDCON1.6=1 then pauseus (Address*10)                  'Checks to see if the receive operation is idle(1), if it is, pause for address*10 uS for random
                         if BAUDCON1.6=0 then NodeLineBusy2                         'Receive operation is still busy, if not, send packet
                         hserout [sync,Node_Addr,Node_Cmd_Resp,Node_Bd,Node_Port_Dev,Node_Sum]   'Send command
                         while not TXSTA1.1 : wend                                  'Wait for USART to finish xmitting
                         ncts=0                                                     'Places 485 interface back into receive mode
                      else                                                          'OR....... 
                         Status1=1                                                  'Turns ON LED
                         NodePktResp=Node_Cmd_Resp & $0F                            'Strips off high order nibble to check for a NAK, put in local temp var - keeps packet integrity
                         if NodePktResp=$03 then goto Node_ReXmit                   'Got a NAK from the Control Computer so send it again
                         if NodePktResp=$02 then Node_ErrChk_Exit                   'We were ACKd, so just leave it alone
    'Now we have received a node packet, believed to be good, so we will ADD $02 to 
    'the Node_Cmd_Resp byte we received and transmit back to Control PC so the PC 
    'knows everything is OK in our world....... and figure a new Checksum......
                         Node_Cmd_Resp=Node_Cmd_Resp + $02                          'Adds the ACK to the byte for our response
                         NodeWord=Node_Addr+Node_Cmd_Resp+Node_Bd+Node_Port_Dev     'Build our new checksum
                         Node_Sum=NodeWord.BYTE0 ^ $FF                              'ditto
                         ncts=1                                                     'Enable transmission of 485 interface
    NodeLineBusy3:       if BAUDCON1.6=1 then pauseus (Address*10)                  'Checks to see if the receive operation is idle(1), if it is, pause for address*10 uS for random
                         if BAUDCON1.6=0 then NodeLineBusy3                         'Receive operation is still busy, if not, send packet
                         hserout [sync,Node_Addr,Node_Cmd_Resp,Node_Bd,Node_Port_Dev,Node_Sum]   'Send command
                         while not TXSTA1.1 : wend                                  'Wait for USART to finish xmitting
                         ncts=0                                                     'Places 485 interface back into receive mode
                      endif
    Node_ErrChk_Exit:
                      Status1=0                                                     'Turns OFF LED
                      Error=0                                                       'Turns OFF LED if it was ON
                      node_PacketRcvd=0                                             'Zero the switch so we don't send other bytes
                      return
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  8. #8
    Join Date
    Sep 2007
    Location
    Waco, Texas
    Posts
    151

    Default Re: How to determine 485 network is not busy in half-duplex

    Darrel-
    I have studied the J1708 and feel I understand how it works and how I can use it for my own applications. My question (at least for now - grin) is there should be no limitation of 20 devices IF I use 1/4 or 1/8 loading 485 transceivers = correct? The 20 device load was designed when they were heavier on the line I am guessing?
    I also plan on using 57.6k as my speed thus making my bit time 17.3 us for a total bus idle time of 173 us - also shouldn't be a problem?
    Won't be using any PIDs but the MIDs will just be the address on the network - lower numbers get higher priority on arbitration.
    I did also like the message delay priority - might try to use that!
    Lastly, probably use just a simple checksum without the inversion and add 1 - don't think I need it.
    Have you used this for something other than trailers?
    Regards,
    Steve
    "If we knew what we were doing, it wouldn't be called research"
    - Albert Einstein

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default Re: How to determine 485 network is not busy in half-duplex

    I think the limitation of 20 nodes and 9600 baud is related to the huge caps on the A/B lines.
    Trucks have a very noisy electrical environment that would benefit from the reduced slew rate.

    If you are using the diode termination method (no caps) you should be able to get much high baud rates and many more nodes.
    I've run DMX at 250K baud with the diode method. But of course that was a 1 master, many slave arrangement.

    I've never used the full J1708 protocol ... just the arbitration process on a system that only had a max of 5 master nodes.
    DT

Similar Threads

  1. give an address to pic on rs-485 network
    By russellperry in forum Ethernet
    Replies: 2
    Last Post: - 8th February 2014, 23:50
  2. USB CDC serial duplex string example wanted
    By russellperry in forum USB
    Replies: 0
    Last Post: - 31st January 2014, 19:33
  3. PICs in a RS-485 network?
    By atomski in forum mel PIC BASIC Pro
    Replies: 21
    Last Post: - 12th November 2011, 10:52
  4. RS 485 network
    By mychangl in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 25th November 2008, 10:35
  5. Slave Databuffer - RS-485 network
    By DynamoBen in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 1st June 2005, 19:36

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts