Frustrated Modbus


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    Join Date
    Dec 2004
    Location
    nebraska
    Posts
    79

    Default Frustrated Modbus

    Hey,
    I have been working on this too long and thought I had it working. The program below works fine when hooked up to rs 232 but when I hook it up to a rs 485 chip it does not work. It is not a hardware issue I know for a fact that the 485 hardware and hookup are wired properly. I am pretty sure I have a problem with a configuration or something in my program.

    I am using a pic 18F4585 at 20 MHz. I am using hardware rx tx and I have a RTS line for the 485 chip. I know its not called rts on the 485 chip but anyway. My rts line is PORTC.4 and I have a led attached to it to see if it flashes every time a response is made. When I have the tx and rx of the pic tied to 232 chip and the computer everything works fine, the rts led flashes whenever the chip is making a response.
    When I hook the tx and rx up to a 485 chip I get 1 response and 1 flash of the RTS LED and then its done. I had this problem before when I was using Portd.2 pin and thought that maybe it was interrupting off of the compatator and not exiting the interrupt routine. So I switched it to c.4 and it worked, then I lost my code and had to backtrack a little. Now I am stuck and frustrated I missing something simple and stupid but beating my head isn't helping anymore.
    When using the rs232 on the computer I don't actually use any handshaking
    Anyone want to take a look at my messy code and see what they think. Maybe it will pop right out to someone else.
    Thanks
    Shawn
    Attached Files Attached Files

  2. #2
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    966


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    Hi Shawn

    The only place I have some doubts is this
    Code:
     while (PIR1.5 = 1)                          'Write modbus frame to buffer
       buffer[Length] = RCREG
       Length = Length + 1
       if Length = 75 then 
        Length = 0
       EndIf
     wend
    I would rather let the ISR exit immediately after collecting and buffering the character. Keeping it in the while:wend means it will not exit the ISR and also will not be able to keep time in the timer ISR branch. Set length=1 only when you start collecting a newframe. Rest of the time, the ISR will collect a character, increment length, etc

    A strategy I use to check such types of communications

    Repeatedly Send a modbus message to the PC running brayTerm in Hex mode. this will obviate any Tx/Rx timing and baud rate issues

    Once you have this running easy, work on the Rx part where the PC sends a fixed modbus message. the PIC will indicate a proper packet received by a flash of led.

    Done that, now let it run in a command-response format. It's bound to work.

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


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    For starters, you'll need to put a DISABLE INTERRUPT before your readMB ISR.
    Otherwise the Interrupts will keep interrupting the ISR.

    And, the CREN bit (RCSTA.4) needs to be toggled (cleared then set) to clear a OERR or FERR condition.
    Your routine simply turns the receiver off (RCSTA.4 = 0), and no further data will be received.
    DT

  4. #4
    Join Date
    Dec 2004
    Location
    nebraska
    Posts
    79


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    Ok
    Thanks for the help so far. I am breaking the code into different pieces and I am going to test them 1 piece at a time and post them here for you guys to laugh over. This piece is the transmit chunk of the routine. It is hooked to my pc via a rs485 to rs232 converter which uses rts. This code works but do you see anything fishy in it. Its sole purpose is to put out known characters using the rts pin to talk on the 485 network. If you guys don't mind I am going to do this with the whole project and then at the end attach the whole code to the post for anyone looking for modbus rtu code.


    Thanks
    Shawn
    Attached Files Attached Files

  5. #5
    Join Date
    Dec 2004
    Location
    nebraska
    Posts
    79


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    OK
    I just tried to reply and something freaked out. Anyways, I was just reading the posts again. Jerson I actually had been thinking the same thing about the while loop for receiving characters. I want to change it but am not sure how. I will probably have more questions when I get to that bit of the code. Thanks
    Darrel, it just dawned on me what you were saying. In order to clear the rx errors you basically just turn off the receiver. In my code I do that but I never turn it back on. So if there is a rx error I'm done until I reset the PIC. That would explain some goofy things that were happening before. Thanks
    Shawn

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,607


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    Hi Shawn,
    I looked at your TX-routine and the thing that caught my eye was:
    Code:
    Rts = 1
    For B0 = 1 To Length      ' Send the response to Master
      B1 = buffer[B0]
      Gosub charout
    Next B0
    Pause 5
    RTS = 0
    Pause 5000
    Now, you say that it all works and I can possibly see why in this particular example but in your real code do you always put the first byte of the frame at location 1 in the array? Arrays are zero-indexed so the first location of Buffer is Buffer[0] and the 6th location is Buffer[5].

    The reason it works in the example you posted is because PBP doesn't have any boundry checks on arrays so when you do Buffer[6]=6 it's actually writing to the memory location AFTER the last "slot" in the array. In this case there might not BE anything of importance there but in you're real program there's a risk you're actually overwriting another variable.

    Also, in this example you have the Buffer array declared as an array of words, is that what you want? It won't work properly when you try to stuff a 16 bit word into the 8bit TXReg - you'll loose the high byte which isn't a problem in this case but still....

    Finally, you could replace the Pause 5 with something like
    Code:
    While TXSTA.1=0 : WEND
    That should make it wait just long enough for the last bit to go out before turning off your transmitter.

    Well, that's my thoughs...

    /Henrik.

  7. #7
    Join Date
    Dec 2004
    Location
    nebraska
    Posts
    79


    Did you find this post helpful? Yes | No

    Default Re: Frustrated Modbus

    Thanks Henrick,
    I knew better with the array numbering I just dropped the ball. As for the Word sized array I also realize that the Tx register is only 8 bits. It will be taken care of in the function routines.
    While TXSTA.1 = 0 : WEND that rocks thank you.
    Next question, I am switching this project over to 40Mhz and so I need to reconfigure timers. In the Modbus.txt file above, at the end it has a If Then statement that looks for a 10mS delay between Rx interrupts. This delay means that the modbus frame of characters is over. The comment says 10mS but for the life of me I cannot figure out where this comes from. It uses a 20Mhz OSC. It uses tmr2 with a 1:16 prescaler and then a variable that increments 1 time every time PIR1.1 is true. All I should have to do when switching from 20 to 40Mhz is take the 120 x 2 and use that value. But I would like to understand how it is getting 10mS.
    20000000/4=5000000 1/5000000=200nS 200nS*16= 3.2uS and 3.2uS*120=384uS
    Attached Files Attached Files

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