CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Modbus Slave - function 3

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Orcino



Joined: 07 Sep 2003
Posts: 56

View user's profile Send private message

Modbus Slave - function 3
PostPosted: Fri Dec 30, 2016 6:21 am     Reply with quote

Hello guys,

First of all I thank the people who helped me with this project of communication with modbus Protocol.

It's almost 100%, but it's with an error.

I am sending some values to the master, but sometimes go with error.

See below in red lines.

Also below, the code I am using for testing.

Can anyone help ?

[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[FF][01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[FF][01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]


Code:

#include <24FJ128GA204.h>

//#device ICD=TRUE

#FUSES NOOSCIO
#FUSES PR
#FUSES HS
#FUSES NOWDT                    // No Watch Dog Timer
#FUSES NOJTAG                   // JTAG disabled
#FUSES NOCKSNOFSM               // Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOIESO                   // Internal External Switch Over mode disabled
#FUSES NOWPFP                   // Write/Erase Protect Page Start/End Location, set to page 0
#FUSES NOBROWNOUT               // No brownout reset
#FUSES NODSBOR                  // BOR disabled in Deep Sleep
#FUSES NODSWDT                  // Deep Sleep Watchdog Timer disabled
#FUSES NODS                     // Deep Sleep operation is always disabled

#use delay(clock=20MHz, crystal)

#use FIXED_IO( C_outputs=PIN_C4,PIN_C1,PIN_C5,PIN_C7,PIN_C8 )

#pin_select U2TX=PIN_C0
#pin_select U2RX=PIN_C2

#define MODBUS_BUS SERIAL
#define MODBUS_TYPE                     MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE              MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE        MODBUS_INT_RDA2
#define MODBUS_SERIAL_ENABLE_PIN        PIN_C1
#define MODBUS_SERIAL_RX_ENABLE         PIN_C1
#define MODBUS_SERIAL_BAUD              9600
#define MODBUS_SERIAL_RX_BUFFER_SIZE    64

//#define MODBUS_PARITY                   NONE

#define MODBUS_TIMER_USED               MODBUS_TIMER_T2   
#define MODBUS_TIMER_UPDATE             MODBUS_TIMER_ISR

#include <modbus.c>
#define MODBUS_ADDRESS                  0x01


int8 swap_bits(int8 c)
{
   return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
          |((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}

void main()
{
 

unsigned int16 hold_regs[8]  = {0,0x01,0,0,0x02,0,0,0x03};
unsigned int16 input_regs[8] = {0,0,0,0,0,0,0,0};
unsigned int16 event_count = 0;

   setup_adc_ports(NO_ANALOGS);
   
   modbus_init();

   while(TRUE)
   {
 
     while(!modbus_kbhit());

     delay_us(50);

     //check address against our address, 0 is broadcast
     if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0)
      {
         switch(modbus_rx.func)
         {               
            case FUNC_READ_HOLDING_REGISTERS:
           
            case FUNC_READ_INPUT_REGISTERS:
               
               if(modbus_rx.data[0] || modbus_rx.data[2] ||
                   modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
                   modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
               
               else
                 {
                 if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS)
                     modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]);
                  else
                     modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]);

                  event_count++;
                  }
             
               break;
               
            default:    //We don't support the function, so return exception
               modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
          }
       }
     }
 }
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Dec 30, 2016 6:33 am     Reply with quote

I don't use MODbus but those [FF] could be the data an idle line would be if read. If so, that might indicate a 'timing' issue.
Since all the other data are correct, it wouldn't be a 'speed' error(IE: tx at 9600, rx at 9601) more likely the 'time' between readings or perhaps the CE of the RS485 chip is 'slow' or you've got a delay_xx(yy) 'somewhere' that is just marginally correct.

Hopefully someone who uses the MODbus will pinpoint the solution.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 30, 2016 7:07 am     Reply with quote

According to this Modbus thread,
http://control.com/thread/1337684268
he says:
Quote:

#3) lack of line bias on RS-485, which means when the master stops
sending & before the slave starts responding, the RS-485 lines float which
means you likely might see some garbage 0xFF or 0xFE bytes at the
start
of the response.

Post a link to your RS-485 circuit schematic.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Dec 30, 2016 1:27 pm     Reply with quote

As I said in the thread the same poster had about Modbus a few days ago:
Quote:

You should also have a pull-up resistor on the RX line out of the buffer (otherwise you can get spurious 'garbage' received when it is not receiving). Similarly, have you got the bus properly biased when idle?. This wouldn't cause a problem sending simple messages each way, but will with Modbus.
Orcino



Joined: 07 Sep 2003
Posts: 56

View user's profile Send private message

PostPosted: Fri Dec 30, 2016 3:43 pm     Reply with quote

Thank you all.

I put a resistor 120R in the PIC and one in the Master (PC).

I removed the resistor from the MASTER and is now working 100% without any error.

Now I can go to the new year's party.

Happy new year to all.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Dec 31, 2016 11:26 am     Reply with quote

You need termination at both ends of the 485 bus.
However the termination should be as shown here:

<https://en.wikipedia.org/wiki/RS-485>

Also the pull-up resistor I'm talking about is on the line between the buffer and the PIC. This line floats when the receiver is off, can lead to garbage being seen. Only something like 4K7R.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group