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

Increase Modbus Points

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



Joined: 04 Feb 2010
Posts: 37

View user's profile Send private message

Increase Modbus Points
PostPosted: Fri Dec 16, 2011 1:57 am     Reply with quote

Hi,

I work on modbus in these days, maybe it is very simple question but i couldn't figure out how to increase modbus points. It seems only 8 points per type. I wait your answers.

Here is my code:
Code:


#include <18F67J60.h>
#fuses   HS, NOWDT, NOPROTECT, NOFCMEN, PRIMARY, NOETHLED
#use     delay(clock=25M)

#define MODBUS_TYPE                       MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_RX_BUFFER_SIZE      64
#define MODBUS_SERIAL_BAUD                9600
#define USE_WITH_PC                       1
#define POT                               PIN_F3
#define BUT                               PIN_B0
#define LED                               PIN_B4

#ifndef USE_WITH_PC
#define MODBUS_SERIAL_INT_SOURCE          MODBUS_INT_EXT
#define MODBUS_SERIAL_TX_PIN              PIN_C6   // Data transmit pin
#define MODBUS_SERIAL_RX_PIN              PIN_C7   // Data receive pin
//The following should be defined for RS485 communication
//#define MODBUS_SERIAL_ENABLE_PIN          PIN_B0   // Controls DE pin for RS485
//#define MODBUS_SERIAL_RX_ENABLE           PIN_B0   // Controls RE pin for RS485
#else
#define MODBUS_SERIAL_INT_SOURCE          MODBUS_INT_RDA
#endif

#include "modbus.c"

#define MODBUS_ADDRESS 0x01

/*This function may come in handy for you since MODBUS uses MSB first.*/
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()
{

   int8  coils = 0b00000101;
   int8  inputs = 0b00001001;
   int16 hold_regs[40] = {
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800
   };
   int16 input_regs[40] = {
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800,
   0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800
   };
   
   int16 event_count = 0;
   
   modbus_init();
   
   while(TRUE)
   {
     
      while(!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_COILS:    //read coils
            case FUNC_READ_DISCRETE_INPUT:    //read inputs
               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
               {
                  int8 data;
                 
                  if(modbus_rx.func == FUNC_READ_COILS)
                     data = coils>>(modbus_rx.data[1]);      //move to the starting coil
                  else
                     data = inputs>>(modbus_rx.data[1]);      //move to the starting input

                  data = data & (0xFF>>(8-modbus_rx.data[3]));  //0 out values after quantity

                  if(modbus_rx.func == FUNC_READ_COILS)
                     modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
                  else
                     modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
                     
                  event_count++;
               }
               break;
            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;
            case FUNC_WRITE_SINGLE_COIL:      //write coil
               if(modbus_rx.data[0] || modbus_rx.data[3] || modbus_rx.data[1] > 8)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
               else if(modbus_rx.data[2] != 0xFF && modbus_rx.data[2] != 0x00)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_VALUE);
               else
               {
                  //coils are stored msb->lsb so we must use 7-address
                  if(modbus_rx.data[2] == 0xFF)
                     bit_set(coils,7-modbus_rx.data[1]);
                  else
                     bit_clear(coils,7-modbus_rx.data[1]);

                  modbus_write_single_coil_rsp(MODBUS_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8);
                 
                  event_count++;
               }
               break;
            case FUNC_WRITE_SINGLE_REGISTER:
               if(modbus_rx.data[0] || modbus_rx.data[1] >= 8)
                  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]));
               }
               break;
            case FUNC_WRITE_MULTIPLE_COILS:
               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
               {
                  int i,j;

                  modbus_rx.data[5] = swap_bits(modbus_rx.data[5]);

                  for(i=modbus_rx.data[1],j=0; i < modbus_rx.data[1]+modbus_rx.data[3]; ++i,++j)
                  { 
                     if(bit_test(modbus_rx.data[5],j))
                        bit_set(coils,7-i);
                     else
                        bit_clear(coils,7-i);
                  }

                  modbus_write_multiple_coils_rsp(MODBUS_ADDRESS,
                                 make16(modbus_rx.data[0],modbus_rx.data[1]),
                                 make16(modbus_rx.data[2],modbus_rx.data[3]));
                 
                  event_count++;
               }
               break;
            case FUNC_WRITE_MULTIPLE_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
               {
                  int i,j;

                  for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
                     hold_regs[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++;
               }
               break;           
            default:    //We don't support the function, so return exception
               modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
         }
      }
   }
}
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Dec 16, 2011 3:25 am     Reply with quote

Read the code. All you need to know is there.

Try walking through it. Work out line by line what the code does, imagining what will happen with various different values. Try it with different MODBUS addresses.

Here's a hint: you are wondering why it only allows you 8 of each type of item. Try searching for the number 8 in the code, or perhaps 7. Where does it appear? Why does it appear where it does? What would happen if you changed it?

Walkthroughs are one of the the simplest and effective code reading and checking techniques. Use them to improve your understanding of C (and of other code). It will improve the code you write too.

RF Developer
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Dec 16, 2011 5:46 am     Reply with quote

As an additional suggestion, read the MODBUS application protocol specification from modbus.org to understand what the software does.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Sat Jan 07, 2012 8:58 pm     Reply with quote

Hi everyone,

I was successful in implement modbus protocol using function 3 and function 4, i.e holding and input registers. However I'm finding it tricky to implement function 10, i.e write multiple register. Since the input here is 2 bytes I don't know how to work on it.

Code:

case FUNC_WRITE_MULTIPLE_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
               {
                  int i,j;

                  for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
                     hold_regs[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++;
               }
               break;   

How do I proceed ? I want to write data on over this function. Please help.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

problem not yet sorted
PostPosted: Tue Jan 10, 2012 2:16 am     Reply with quote

Hi,

I tried using multiple registers for writing, and the response showed ok.

However, I've only been able to write a single register from the multiple register case.

I did the following modification in the code.
Code:

hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[j],modbus_rx.data[j+1]);


Please help. How should I proceed?

Eagerly awaiting for your response.

SId
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Jan 10, 2012 3:59 am     Reply with quote

In contrast to the reasonable code in your previous post, your writing all data to a single holding register. Why?
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Tue Jan 10, 2012 10:47 pm     Reply with quote

I'm bit confused while figuring out the logic. I don't understand the 'i' variable, it should get the data and and add to the holding register and increment. But that is not happening. Thats when I used
Code:

hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[j],modbus_rx.data[j+1]);

which at least adds the data into an array of holding register. But since 'modbus_rx.data[1]' is one its suppose to add only one value.
Later I tried with
Code:

for(i=0, j=5; i < modbus_rx.data[4]/2; ++i, j+=2)  //changed i=0
                        /*hold_regs[i+8]*/hold_regs[modbus_rx.data[i+8]] = make16(modbus_rx.data[j], modbus_rx.data[j+1]); // j=j+1 and j+1 =j
                        //hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[2], modbus_rx.data[3]);
   
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++;
ax[0]=hold_regs[8];
ay[0]=hold_regs[9];
ax[1]=hold_regs[10];
ay[1]=hold_regs[11];
ax[2]=hold_regs[12];
ay[2]=hold_regs[13];
ax[3]=hold_regs[14];
ay[3]=hold_regs[15];
ax[4]=hold_regs[16];
ay[4]=hold_regs[17];
ax[5]=hold_regs[18];
ay[5]=hold_regs[19];
ax[6]=hold_regs[20];
ay[6]=hold_regs[21];
ax[7]=hold_regs[22];
ay[7]=hold_regs[23];

But again its not working Sad Please help. I'm trying really hard.

Sid
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Wed Jan 11, 2012 1:52 am     Reply with quote

Sorry for the trouble. problem is sorted out of writing on multiple register on modbus.

But now i cant write on eeprom in that case.

Code:

 for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)  //changed i=0
                        hold_regs[i] = make16(modbus_rx.data[j],modbus_rx.data[j+1]); // j=j+1 and j+1 =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++;
                                ax[0]=hold_regs[8];
                                ay[0]=hold_regs[9];
                                ax[1]=hold_regs[10];
                                ay[1]=hold_regs[11];
                                ax[2]=hold_regs[12];
                                ay[2]=hold_regs[13];
                                ax[3]=hold_regs[14];
                                ay[3]=hold_regs[15];
                                ax[4]=hold_regs[16];
                                ay[4]=hold_regs[17];
                                ax[5]=hold_regs[18];
                                ay[5]=hold_regs[19];
                                ax[6]=hold_regs[20];
                                ay[6]=hold_regs[21];
                                ax[7]=hold_regs[22];
                                ay[7]=hold_regs[23];
                                skipFlag[0]=hold_regs[24];
                                skipFlag[1]=hold_regs[25];
                                skipFlag[2]=hold_regs[26];
                                skipFlag[3]=hold_regs[27];
                                skipFlag[4]=hold_regs[28];
                                skipFlag[5]=hold_regs[29];
                                skipFlag[6]=hold_regs[30];
                                skipFlag[7]=hold_regs[31];
                                rs_cpu=hold_regs[32];
                                delay_ms(5);
                  }             
                                if(rs_cpu==0)
                                {
                                    reset_cpu();
                                }
                                int l2=0;
                                for( l2=0;l2<8;l2++)
                                {
                                   write_eeprom(7+offset,alarmflag[l2]);
                                   //delay_ms(5);
                                   temEE=ax[l2]/256;
                                   write_eeprom(8+offset,temEE);
                                   //delay_ms(5);
                                   temEE=ax[l2]%256;                                   
                                   write_eeprom(9+offset,temEE);
                                   //delay_ms(5);
                                   temEE=ay[l2]/256;
                                   write_eeprom(10+offset,temEE);
                                   //delay_ms(5);
                                   temEE=ay[l2]%256;
                                   write_eeprom(11+offset,temEE);
                                   //delay_ms(5);
                                   write_eeprom(16+offset,skipFlag[l2]);
                                   //delay_ms(5);  */
                                }


its not getting written on EEPROM.
but when i do the same outside the function it does get written on the EEPROM
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