• AVR Freaks

Hot!RS485 miscommunication on PIC32MZ

Page: 12 > Showing page 1 of 2
Author
thermant
New Member
  • Total Posts : 14
  • Reward points : 0
  • Joined: 2019/07/29 09:19:49
  • Location: 0
  • Status: offline
2019/10/30 13:32:45 (permalink)
0

RS485 miscommunication on PIC32MZ

Hello everyone,
I'm currently trying to incorporate a Modbus driver for a Master device (code for the driver was used for a PIC32MK that I made changes to for the PIC32MZ, provided by a company I'm partnering with to use with their devices). I've gotten it to the point where the message is being transmitted over UART as it should be, but the receiver seems to interpret a message as having ended early when it should be continuing. For example, I'm sending an 8 Byte message, it will send 2 Bytes and the slave will respond with a CRC thinking it received something, I believe the CRC is 0x8104 each time. I tested this by connecting the Master device to an RS485-USB transceiver and using pyModSlave to monitor traffic on the bus.
#1

20 Replies Related Threads

    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 13:39:21 (permalink)
    0
    Was getting an access denied message constantly so I had to cut off most of the post, very incredibly frustrating as I have to reupload pictures each time. Now apparently I can't upload pictures, so uploading to imgur.
     
     
    The baud rate is 34000, 1 stop bit, 8 data bits, no parity. PBCLK2 is running at 40MHz (sysclock is 160MHz, divisor of 4), which results in a BRG value of 259. The formatted message should be [10 03 02 01 00 01 D7 33] and the response should be [10 03 02 00 00 44 47], verified by using qModMaster to write the same message to the slave device and checked that the message generated by my driver was a match. That should also rule out some issue with the slave device itself as I was able to communicate with it successfully.
    https://imgur.com/8EcSWGT
    Here's an overview of (most of) the message being sent over a scope. Purple in the middle is the two lines subtracted from each other to show the data line
    https://imgur.com/lriJrpA
    Here is the first byte of CRC being sent (The conversion on the bottom is for RS232 so it doesn't consider half duplex, the Rx is the correct value).
    https://imgur.com/7KbjyPW
    Here is an example of the Slave sending its CRC. The first message being 0x10 from the Master and the second batch being the Slave responding with its CRC. I'm not sure why the Master has such a long period of being high before and after the data, especially in comparison with the Slaves data.
    https://imgur.com/LijBgmc
    https://imgur.com/PjbLwTb
    https://imgur.com/nVgeWcw

    I tried to be as thorough as possible, this is my first foray into RS485 and I'm kinda at my wits end trying to solve this issue. If you have any further questions or if I missed something just let me know and I'll try to respond as quickly as possible, thank you for any help.

     

     
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 15:13:01 (permalink)
    0
    What is your 3.5 Char time?  It should be 1.75 milliseconds.
    Are you resetting the timer after each byte being received?
    The Master should have a 3.5 char delay (or 1.75millisec) minimum between receiving the  from the Slave and sending the Next Packet. 
    #3
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 15:55:28 (permalink)
    0
    Sorry I'm not sure what you mean by 3.5 Char. The issue is that the Slave is responding before the message has fully been sent, it instead reads 2 bytes and then responds. I put a scope on the communication between the RS485-USB transceiver and used qModMaster to send a message to see what it should look like. 
    https://imgur.com/vAPBcLp
     https://imgur.com/ozJ8ydQ
    There is roughly 2ms between the master command and slave response. Clearly a disparity between how qModMaster formats the message compared to how my pic driver
    #4
    ric
    Super Member
    • Total Posts : 24202
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 15:59:36 (permalink)
    0
    Sanity check. You haven't accidentally reversed your A and B wires on the RS485 connection?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 16:14:15 (permalink)
    0
    ric
    Sanity check. You haven't accidentally reversed your A and B wires on the RS485 connection?



    I've been really worried about that so I've probably quadruple checked that at this point, and also just reversed them for an extra layer of sanity checking. I can still see on pyModSlave that I'm receiving the correct data, it's just that something is wrong with the formatting or timing or something that's causing the slave to interpret that correct message as multiple smaller messages. It is also weird that the slave device is responding at all, afaik with rs485 they should ignore messages that don't start with their slave address.
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 16:15:26 (permalink)
    0
    In the Modbus Protocol, if the Master stops sending for more than 3.5 Chars the slave will assume that is the end of the Packet. 
    In your case you have the Additional issue that the Slave is responding to the impossible packet with a CRC error.  The Minimum possible Packet for Modbus RTU is 4 chars.
    #7
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/30 16:31:34 (permalink)
    0
    NKurzman
    In the Modbus Protocol, if the Master stops sending for more than 3.5 Chars the slave will assume that is the end of the Packet. 
    In your case you have the Additional issue that the Slave is responding to the impossible packet with a CRC error.  The Minimum possible Packet for Modbus RTU is 4 chars.

    There's about 4ms between the bus hanging and the Master taking it high again, and about 8ms between each byte of data.
    The slave responding does seem to just be a pyModSlave issue at least, when I put the two devices (my Master board and the slave board I want to communicate with) on the bus the slave doesn't respond at all.
    #8
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/10/31 15:33:08 (permalink)
    0
    The fact your Slave works when connected to a prefect signal does not mean it is truly a correct modBus Device.
    DO any of your Scope pictures  have the Message the Master is transmitting? It should not have any delays between bytes of more than 1.5 Chars  (15 bit times)  If it does the slave should ignore the message.
    The slave should not respond until 3.5 chars after the last byte is sent. (35 bit times OR 2 milliSec witch ever is greater)
    #9
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 11:07:42 (permalink)
    0
    NKurzman
    The fact your Slave works when connected to a prefect signal does not mean it is truly a correct modBus Device.
    DO any of your Scope pictures  have the Message the Master is transmitting? It should not have any delays between bytes of more than 1.5 Chars  (15 bit times)  If it does the slave should ignore the message.
    The slave should not respond until 3.5 chars after the last byte is sent. (35 bit times OR 2 milliSec witch ever is greater)


    Yes I posted the picture here https://imgur.com/lriJrpA
    I'm not sure why there's so much of a delay between bytes being sent, especially when compared to qModMaster here https://imgur.com/ozJ8ydQ I'm not positive about what could be effecting how quickly the bytes are sent out other than the driver itself, it should just be placing it in the TX register and that's that.
    I think I'm going to try a bit of a rewrite of their driver, since as it is now clearly isn't working out and I'm not entirely sure why
    #10
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 12:50:56 (permalink)
    0
    Not Owning your Scope, I am not sure what you Pictures are trying your show.
    What I would expect to see is about 8 bytes, a Gap of about 2 milliseconds then a respond. all on a single Trace.  Your Pictures are hiding that, because of the Mode you are using.
    https://imgur.com/ozJ8ydQ
    What is the Communication that is supposed to be?  ModBus RTU?  is TX the Master?  The TX values are not ModBus RTU  RX could be  slave address 0x10 (16), Function 3 (Read Coil) either a command or a response.
     
    https://imgur.com/lriJrpA
    Is garbage.  Is that the Master?  If it is the Slave should not respond to it.  And the Master is the Problem.
     
    #11
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 13:39:48 (permalink)
    0
    NKurzman
    Not Owning your Scope, I am not sure what you Pictures are trying your show.
    What I would expect to see is about 8 bytes, a Gap of about 2 milliseconds then a respond. all on a single Trace.  Your Pictures are hiding that, because of the Mode you are using.

     
    Sorry if that's hard to read, the yellow and cyan channels on top are the +/-, A/B channels with the middle blue channel being them subtracted from each other to show the actual output. Bottom is a RS232 decoder for both the channels, just doesn't display characters when zoomed out too far.
     

    https://imgur.com/ozJ8ydQ
    What is the Communication that is supposed to be?  ModBus RTU?  is TX the Master?  The TX values are not ModBus RTU  RX could be  slave address 0x10 (16), Function 3 (Read Coil) either a command or a response.

    That's RTU, the decode at the bottom is RS232 (since my scope doesn't have an RS485 mode) and it's checking both channels, so just ignore that it says TX and that line. RX is from the master, the data there is correct. Yes that's correct, it's slave address 0x10, Read Holding Registers, starting at 0x0203, reading 0x0001 registers, and with the CRC of 0x76F3. It's a command.

    https://imgur.com/lriJrpA
    Is garbage.  Is that the Master?  If it is the Slave should not respond to it.  And the Master is the Problem.

    Yeah, I'm aware. That's the issue I'm trying to solve. Slave works fine (although I'm not working on it) but the code for the Slave driver was done by the same company that handled the Master driver that they provided me with. Just wasn't sure why the data was being sent differently, but it must be some sort of timing difference that's causing a delay between when each byte is sent
     
    #12
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 13:59:28 (permalink)
    0
    For the First one you need to expand it to see the entire frame.  You will see the timing.
     
    The second one.
    Assuming this is the Master.  There is a bug in the Code.  It should Not look like that.
    Is that your PIC doing that?
    #13
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 16:27:57 (permalink)
    0
    NKurzman
    For the First one you need to expand it to see the entire frame.  You will see the timing.

    Yeah I had posted it earlier https://imgur.com/vAPBcLp The first message is from the Master (in this case the qModMaster) and the second message is from the Slave, Master is sending the correctly formatted message and slave is responding as it should.

    The second one.
    Assuming this is the Master.  There is a bug in the Code.  It should Not look like that.
    Is that your PIC doing that?

    Yeah this is the issue I was trying to fix, I feel like I've ran through a fairly long list of what potential fixes it could be so I was hoping to pop in here for some other ideas. The program flow is that it goes through a series of functions where it sends a byte and returns the calculated CRC, then sends the next byte and uses the new CRC to calculate the CRC and return it, through each step of the message.

    calculated_crc = putOutByteAndCRCCalc(chIdx, tmpBuffer.Byte_H, calculated_crc);
    calculated_crc = putOutByteAndCRCCalc(chIdx, tmpBuffer.Byte_L, calculated_crc);

    So it is sending them out basically all back to back. Only consideration is that it also checks to see if something else is already being transmitted and if so will add it to a circular buffer, so then when the previous message has sent the TX ISR checks the contents of the buffer and will add it to the register if its not empty. I have yet to see anything actually in that buffer, but it's there nonetheless. I could see if maybe there's too much overhead between transmissions by calculating the CRC all at once and then just sending the bytes all at once.
    #14
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 16:54:05 (permalink)
    0
    What method are you using to calculate the CRC?  bib by bit or Nibbles?  (the two 256 byte tables)  Hardware?
    You can get a quick fix because it is your code. There are dozens of ways to do it.
    But it looks like it is sending the same byte every time. You should be able to debug it.  The Hardware Fifo is 8 bytes are you checking  UTXBF (FIFO is full) Check this while sending.
    OR TRMT  the Transmitter is empty (the entire Message is sent, ).
    #15
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 17:31:59 (permalink)
    0
    NKurzman
    What method are you using to calculate the CRC?  bib by bit or Nibbles?  (the two 256 byte tables)  Hardware?

    They have some table set up that it references, looks like it's 1 256 element table that's 2B each. It's produced the correct values from everything I've seen so far anyways, from comparing it with the output of qModMaster.

    You can get a quick fix because it is your code. There are dozens of ways to do it.
    But it looks like it is sending the same byte every time. You should be able to debug it.  The Hardware Fifo is 8 bytes are you checking  UTXBF (FIFO is full) Check this while sending.
    OR TRMT  the Transmitter is empty (the entire Message is sent, ).

    It isn't sending the same byte every time, maybe just looks that way since it's zoomed out enough to see the whole message. Mainly the issue seems to be that there's such a long period of time between each byte being sent.
    Yes their driver checks if UTXBF is 0 before adding the byte to UTXREG, and also checks if TRMT is 1 and if it is they set their RTS pin low. Currently their driver puts the byte into UXTXREG and then calculates the CRC from that byte and passes it along, I'm working on separating the two right now so it calcs the CRC first and then just writes them all out really quickly, could be there's just too much going on between bytes.
    #16
    ric
    Super Member
    • Total Posts : 24202
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: RS485 miscommunication on PIC32MZ 2019/11/04 23:49:34 (permalink)
    0
    thermant
    ...
     I'm working on separating the two right now so it calcs the CRC first and then just writes them all out really quickly, could be there's just too much going on between bytes.

    That is starting to sound extremely likely.
    Either that, or there's a bug somewhere waiting for the FIFO to empty before writing the next byte.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #17
    thermant
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/07/29 09:19:49
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/05 13:36:27 (permalink)
    0
    ric
    That is starting to sound extremely likely.
    Either that, or there's a bug somewhere waiting for the FIFO to empty before writing the next byte.

    https://imgur.com/PZdogep
    Looks like it was exactly that, I did the CRC calculation first and then used their putchar function but the long gap between sends remained. So I cut all that out and just went with this:

    IEC5bits.U5TXIE = 0;
    IEC5bits.U5RXIE = 0;
    UART5_RTS_Set(); UART5_CTS_Set();
    U5TXREG = devAdd;
    U5TXREG = modbusFUNCTIONCODE_READHOLDINGREGISTERS;
    tmpBuffer.Word = stAdd;
    U5TXREG = tmpBuffer.Byte_H;
    U5TXREG = tmpBuffer.Byte_L;
    tmpBuffer.Word = numOfReg;
    U5TXREG = tmpBuffer.Byte_H;
    U5TXREG = tmpBuffer.Byte_L;
    tmpBuffer.Word = calculated_crc; // order is reversed, send low first
    U5TXREG = tmpBuffer.Byte_L;
    U5TXREG = tmpBuffer.Byte_H;
    if(U5STAbits.UTXEN == 0)
        U5STAbits.UTXEN = 1;
    IEC5bits.U5TXIE = 1;

    And I even receive the message [10 03 02 00 00 44 47] which appears to be correct, now I just need to handle the RX stuff correctly and pull that info out. Their driver seemed to mainly be concerned with handling multiple master/slave channels, but I only have one so I might just gut most of it and see if that eliminates some of the complication.
    Any recommendations on how to handle sending a message larger than the size of the FIFO buffer? I got lucky here at least, that won't last for long though. I figure I can add them to a buffer when I see that it's full and add a part to the TX interrupt to add the next byte to the TXREG when its shown to be done, or maybe just poll it to see when its not full.
    #18
    NKurzman
    A Guy on the Net
    • Total Posts : 17916
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: RS485 miscommunication on PIC32MZ 2019/11/05 13:43:53 (permalink)
    0
    The Table Method should be very Fast.
    You can Check it by driving an unused (or borrowed ) Pin connected to your scope to time it.
    #19
    ric
    Super Member
    • Total Posts : 24202
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: RS485 miscommunication on PIC32MZ 2019/11/05 14:56:08 (permalink)
    0
    thermant
    ...
    Looks like it was exactly that, I did the CRC calculation first and then used their putchar function but the long gap between sends remained. So I cut all that out and just went with this:

    That seems to confirm it.
    What if you code your own putchar function?
    Just wait for the transmit FIFO to have room for at least one character, then write it to U5TXREG and exit immediately.
    That should give you transmissions with no inter character pauses.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5