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 support@ccsinfo.com

modbus error with pic18f87k90
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

modbus error with pic18f87k90
PostPosted: Tue Jul 28, 2015 11:50 pm     Reply with quote

hi,
when i interface sn75176 IC with pic18f4620, i can do modbus communication. we are using modbus.c file
but when i connect sn75176 with pic18f87k90, in modbus tester, it shows TIME OUT. (status not connected is showing)
i m using the same code for both pic. following the example code given in ccs

but i dont know why it is working in one controller and not in other.

my code is
Code:

#include <18F87K90.h>

#device  ICD=TRUE   
#fuses NOWDT
#fuses MCLR
#fuses HSH
#fuses SOSC_DIG
#fuses NOIESO
#fuses NOBROWNOUT
#fuses NOPLLEN
#use delay (clock=20M) 

#define MODBUS_TYPE                       MODBUS_TYPE_SLAVE                   
#define MODBUS_SERIAL_TYPE                MODBUS_RTU                           
#define MODBUS_SERIAL_INT_SOURCE          MODBUS_INT_RDA                       
                                 
#define MODBUS_SERIAL_BAUD                9600                                 //
 #use rs232(baud=9600, UART1, bits=8, stop=1, parity=N, stream=MODBUS_SERIAL, errors)

#include "modbus.c"
#define MODBUS_ADDRESS                    2                         //Channel_No
#define MODBUS_SERIAL_ENABLE_PIN          Pin_C5   


int16 hold_regs [45] = {0};
int16 input_regs[] = {0};
int16 event_count = 0;

void main()
{
modbus_init();
while(1)
{

output_high(GSM_IND);


  delay_ms( 1000 );

output_low(GSM_IND);


  delay_ms( 1000 );
 hold_regs[0]=1;
          hold_regs[1]=2;                   
          hold_regs[2]=3;
          hold_regs[3]=4;
          hold_regs[4]=5;
          hold_regs[5]=6;
          hold_regs[6]=7;
          hold_regs[7]=8;
          hold_regs[8]=9;
          hold_regs[9]=10;
         
         if(modbus_kbhit())
         {
         
         
         
         //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] >= 22 || modbus_rx.data[3]+modbus_rx.data[1] > 22)
                  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;
             
               case FUNC_WRITE_SINGLE_REGISTER:
               
               if(modbus_rx.data[0] || modbus_rx.data[1] >= 22)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
               else
               {
             
                  //the registers are stored in little endian format
                  hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[3],modbus_rx.data[2]);

                  modbus_write_single_register_rsp(MODBUS_ADDRESS,
                               make16(modbus_rx.data[0],modbus_rx.data[1]),
                               make16(modbus_rx.data[2],modbus_rx.data[3]));
                 
                 hold_regs[modbus_rx.data[1]]=hold_regs[modbus_rx.data[1]]/256; 
               
                 
                 
                 
                 
                 
                 
                 
               }
               break;
             
                     

             
               case FUNC_WRITE_MULTIPLE_REGISTERS:
               if(modbus_rx.data[0] || modbus_rx.data[2] ||
                  modbus_rx.data[1] >= 21 || modbus_rx.data[3]+modbus_rx.data[1] > 21)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
               else
               {
                  int i,j;
                  int8 k;
                  k=modbus_rx.data[1];

                  for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
                     hold_regs[k+i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);

                  modbus_write_multiple_registers_rsp(MODBUS_ADDRESS,
                                 make16(modbus_rx.data[0],modbus_rx.data[1]),
                                 make16(modbus_rx.data[2],modbus_rx.data[3]));
               
                  event_count++;
               }
               hold_regs[modbus_rx.data[1]]=hold_regs[modbus_rx.data[1]]/256;
                 
               
               
               break;         
           
               default:    //We don't support the function, so return exception
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
            }
           
           
         }
       
         }// modbus function ends
         }}




the same working in 18f4620 after changing configuration bit.
in the above code, is there any mistake in configuration bit?

i m using uart 1. (PIN C7 and C6) and C5 as enable pin
i checked the above code with and without #device ICD=TRUE .
but the same result - TIME OUT.

please advise.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: modbus error with pic18f87k90
PostPosted: Wed Jul 29, 2015 1:46 am     Reply with quote

Code:

...
#define MODBUS_TYPE                       MODBUS_TYPE_SLAVE                   
#define MODBUS_SERIAL_TYPE                MODBUS_RTU                           
#define MODBUS_SERIAL_INT_SOURCE          MODBUS_INT_RDA                       
                                 
#define MODBUS_SERIAL_BAUD                9600                                 //
// #use rs232(baud=9600, UART1, bits=8, stop=1, parity=N, stream=MODBUS_SERIAL, errors) // DO NOT define the serial port used by modbus. Modbus.c does that for you. MODBUS_INT_RDA selects UART1.
#define MODBUS_SERIAL_ENABLE_PIN          Pin_C5    // This MUST go before the include of modbus.c. Putting it after will stop the enable working. This is probably the main problem.

#include "modbus.c"

// This is not used by modbus.c and so it can come after the include.
#define MODBUS_ADDRESS                    2                     
...
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Wed Jul 29, 2015 2:30 am     Reply with quote

i changed the code..
Code:

#define MODBUS_TYPE                       MODBUS_TYPE_SLAVE                   
#define MODBUS_SERIAL_TYPE                MODBUS_RTU                           
#define MODBUS_SERIAL_INT_SOURCE          MODBUS_INT_RDA                       
                                 
#define MODBUS_SERIAL_BAUD                9600 
#define MODBUS_SERIAL_ENABLE_PIN          Pin_C5
#define MODBUS_ADDRESS                    2 

#include "modbus.c"
......



then also I'm getting TIMEOUT: status not connected.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jul 29, 2015 3:02 am     Reply with quote

I'm no expert in fuses, but at a glance what you have looks okay.

However, this code waits two seconds in every loop:

Code:
output_high(GSM_IND);


  delay_ms( 1000 );

output_low(GSM_IND);


  delay_ms( 1000 );


That's going to cause a lot of problems, especially if the timeout time is shorter than two seconds.

What are your termination and bias? Have do you know if the slave doesn't receive, or if you are sure it does, does it try to send anything back?
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Wed Jul 29, 2015 3:20 am     Reply with quote

deleted delay_ms( 1000 ) . then also not connected.

termination resistor 120E, and bias is 10K. same hardware successfully communicate with PIC18f4620 and modbus.
i have connected leds in RX and Tx pin of PIC. so if anything receive or transmit, led will blink.
but in this case, led is off.
Sad
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jul 29, 2015 4:06 am     Reply with quote

Your code includes:
Code:
#device  ICD=TRUE
Therefore it is being compiled for debug. I therefore assumed you were using a debugger to single step and breakpoint the code. That would allow you to tell you exactly what was working and what wasn't.

If you are trying to run this code standalone, which is what your most recent comment about LEDs suggests, then yes, of course, it won't work as its debug code, not release (standalone) code.
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Wed Jul 29, 2015 4:33 am     Reply with quote

Quote:
i checked the above code with and without #device ICD=TRUE .
but the same result - TIME OUT.


we are not using debug option.
directly programing using pickit3.

But i dont know why the same code and hardware are working for one controller and not for other.
I checked the uart of pic18f87k90. It is working while connecting to hyperterminal by rs232. But while connecting modbus, TIMEOUT error......
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

solved
PostPosted: Thu Jul 30, 2015 3:32 am     Reply with quote

now its working.......

thank you for your support....

for last 3 days it was showing TIMEOUT. but today, it is working. but some times.. it is showing timeout.
Quote:


...
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA

#define MODBUS_SERIAL_BAUD 9600 //
// #use rs232(baud=9600, UART1, bits=8, stop=1, parity=N, stream=MODBUS_SERIAL, errors) // DO NOT define the serial port used by modbus. Modbus.c does that for you. MODBUS_INT_RDA selects UART1.
#define MODBUS_SERIAL_ENABLE_PIN Pin_C5 // This MUST go before the include of modbus.c. Putting it after will stop the enable working. This is probably the main problem.

#include "modbus.c"

// This is not used by modbus.c and so it can come after the include.
#define MODBUS_ADDRESS 2
...


thank you... it may be the problem...'
but after correcting this also it was showing timeout for 1 day. but now its working...
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Sun Aug 02, 2015 10:51 pm     Reply with quote

again.... it is showing timeout error for last 2 days....

but when i connect another device having 18f4620 controller, modbus is working without any timeout.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Aug 03, 2015 2:26 am     Reply with quote

td wrote:
but when i connect another device having 18f4620 controller, modbus is working without any timeout.


This shows you most likely still have a hardware problem, because it works when some hardware is connected, and doesn't if its not. You also had firmware problems. Some you have fixed, and you may still have some others. What is your circuit, both with and without the 18f4620?
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Mon Aug 03, 2015 5:26 am     Reply with quote

both circuit are similar. only difference microcontroller.
via optocoupler connected to sn75176 IC.

in code, we used
Code:

case FUNC_READ_HOLDING_REGISTERS:
             case FUNC_READ_INPUT_REGISTERS:
               if(modbus_rx.data[0] || modbus_rx.data[2] ||
                  modbus_rx.data[1] >= 16000 || modbus_rx.data[3]+modbus_rx.data[1] > 16000)
                  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;
             


length of holding/input register here we choose as 16000. previously it was 21.
in modbus tester, we select the length above 127, it shows illegal response. in modbus.c driver file , we changed

Code:

struct
{
   unsigned int8 address;                                                                  //
   unsigned int8 len;                       //number of bytes in the message received       
   function func;                           //the function of the message received           
   exception error;                         //error recieved, if any
   unsigned int16 data[MODBUS_SERIAL_RX_BUFFER_SIZE]; //data of the message received         //  changed int8 to 16
} modbus_rx;
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Aug 03, 2015 9:10 am     Reply with quote

td wrote:

Code:

case FUNC_READ_HOLDING_REGISTERS:
             case FUNC_READ_INPUT_REGISTERS:
               if(modbus_rx.data[0] || modbus_rx.data[2] ||
                  modbus_rx.data[1] >= 16000 || modbus_rx.data[3]+modbus_rx.data[1] > 16000)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);



This just isn't going to work. The example code can only work with 256 registers. It assumes the upper bytes of register numbers is assumed to be zero. It can be made to work with more, but it needs to be changed to do that.

Then there is the question of message size. You can't send to many registers in one message. I forget how many it is, but its dependant on message buffer lengths, and its a LOT less than 16000! I think maybe 16 or 32 registers in one message.

Also, Modbus only allows 10000 endpoint of any one kind: holding registers, coils, input registers etc. In fact it is possible to have more, the addressing will actually allow upto 65536 or each type, and some implementations allow it, but the original Modbus only allowed 10000. In general I can't see the need for so many. There are ways of using the registers to access large data sets, for example to use a pair as start address and counts to access larger memory spaces. However you do it, simply making the counts huge won't work.

This code won't work, and will cause strange, unexpected results.
Quote:

Code:

struct
{
   unsigned int8 address;                                                                  //
   unsigned int8 len;                       //number of bytes in the message received       
   function func;                           //the function of the message received           
   exception error;                         //error recieved, if any
   unsigned int16 data[MODBUS_SERIAL_RX_BUFFER_SIZE]; //data of the message received         //  changed int8 to 16
} modbus_rx;



What do you think this does? The data in the buffer is eight bit characters, making the buffer sixteen bit simply wastes memory, and may cause other problems. If you are thinking about changing the CCS supplied Modbus code, then you're doing something wrong, and need to think again.

Are you getting timeouts, or are you getting errors? Which is it? What is the actual problem? You say you have code for an that works, but it doesn't in the 18f87k90, but then you say you've changed the number of registers and messed about with modbus.c. So it isn't the "same code" at all, is it?

I'd start by getting a simple version to work. I might start, in fact and assuming that I knew than code really worked properly, by getting the 18f4620 code working on the 18f87k90. I'd make sure the hardware really was doing what I expected to, and that my modbus comms were rock solid reliable. Only then I might start changing the code to do other stuff. but either way, 16000 holding registers is probably not going to work.
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Wed Aug 05, 2015 12:45 am     Reply with quote

Quote:
Are you getting timeouts, or are you getting errors? Which is it? What is the actual problem?


when i use 18f4620 with modbus register length 21, it was working perfect.
when i use the same hardware circuit with 18f87k90 and modbus register length 21, most of the time, we r getting timeout. but sometimes, it is working.
when it was working, i changed the modbus register lenth. it is working only up to 127.
in our project, we need atleast 2000-3000 locations (holding/input registers).thats why i extended the length of modbus register.

Quote:
What do you think this does? The data in the buffer is eight bit characters, making the buffer sixteen bit simply wastes memory, and may cause other problems. If you are thinking about changing the CCS supplied Modbus code, then you're doing something wrong, and need to think again.


thank you for pointing out my mistakes.

is there any other way to extend the length of modbus registers?
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Aug 05, 2015 2:34 am     Reply with quote

Look, two or three thousand registers, while still a lot, are much easier that sixteen thousand. I still think its too many to do directly as registers, and there's no way you can transfer that many at a time. You'll have to limit the number in a message to, say sixteen, as Modbus messages cannot be very long.

You need to have a look at the Modbus protocol documentation (Look on modbus.org) to understand how Modbus addressing works to increase to a few thousand registers. I've given you one suggestion as to how to implement more - think of it more as a serially driven (e.g. SPI or I2C) memory, and don't access the data directly, but through addressing and access registers.

You've not given any useful details of your circuits, and if it works some of the time then hardware is likely to be the problem, also your main loop, that has or calls the Modbus code, must loop round as fast as possible so that it can catch all incoming messages. Delays, even of a millisecond or so, may result in missed messages. In fact, better yet, don't use delays at all. You've not even told us what compiler version you are using. You've shown you don't know how to debug using the ICSP facilities (hardware debugging). So all in all, there's little more I can do.
td



Joined: 16 Apr 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Wed Aug 05, 2015 4:31 am     Reply with quote

compiler version: 4.119

Our project is a data logger. We used rtc ds1302 to get the date and time. if any events occurs, the data with date and time will be saved in eeprom 24lc16. For each event, we need 10 locations in eeprom. (date&time - 7 locations itself).

At last for displaying the data saved in eeprom, we use modbus.ie, via modbus, we are displaying the saved data. For each event, we need 10 different registers. We need to save at least 200 events.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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