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 Communication
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
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

Modbus Communication
PostPosted: Sun Feb 27, 2011 3:24 am     Reply with quote

Hi,

I'm trying to establish the modbus slave communication using the existing ex_modbus_slave.c
I connected the Tx pin of Rs232 connector to Pin B0 and Rx pin to Pin B1 of microcontroller.
I'm using the modbus scan software to read the values.
however, i'm not sure what other things I need to configure.
till now i have not been able to establish any communication.
Please help me.

Thanks
Sid
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

Connections with modbus
PostPosted: Sun Feb 27, 2011 9:51 am     Reply with quote

I tried running the code making the following connections, the connections is in the link below
http://www.4freeimagehost.com/show.php?i=4d3b0503ee6d.jpg

and I connected the rs485-232 converter to the PC.

I tired viewing the output from the slave device using modbusview but it is coming timeout

the transmit data is as follows:-
[3A][30][31][30][33][30][30][34][30][30][30][34][30][37][43][0D][0A]

and the data I received is as follows:-
[B1][D6][F6][96][F6][F6][76][F6][F6][F6][76][F6][16][96][95][EB][00]

I'm using modbusview as my master and the settings are as follows:-
com:-8
baudrate:- 9600
databit:- 8
Parity:-N
stopbit:-1
Mode:- Binary/RTU
Master/Slave:- Master selected

My code is as follows:-
Code:


#define USE_WITH_PC 1

#include <16f877A.h>
#device *=16
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=40000000)

#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600

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

#include "modbus.c"

#define MODBUS_ADDRESS 0xF7

/*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[] = {0x8800,0x7700,0x6600,0x5500,0x4400,0x3300,0x2200,0x1100};
   int16 input_regs[] = {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);
         }
      }
  }
}


looking forward for some help...I'm out of ideas now..
please help

thanks
Sid
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 9:51 am     Reply with quote

Quote:
the transmit data is as follows:
[3A][30][31][30][33][30][30][34][30][30][30][34][30][37][43][0D][0A]

It's no valid MODBUS RTU data.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 10:06 am     Reply with quote

How do I know what is the transmitted data? I tried to understand the code but it was quite difficult.
Please help. How should I proceed?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 4:45 pm     Reply with quote

Quote:
How do I know what is the transmitted data? I tried to understand the code but it was quite difficult.

You have MODBUSVIEW setup to ASCII instead of RTU and a default address of 01 decimal instead of 0xF7. This can never work. Read MOSBUSVIEW help thoroughly and try to understand the configuration settings.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 12:07 am     Reply with quote

thanks FvM,
It was my mistake not to set it into RTU mode.
Now that I have done the configuration I got the following results:-

Transmitted data:-
[01][03][00][F6][00][64][A4][13]

Received Data:-
[7F][7E][13][37][B7][76]

and still it is poll out error.

I did some modification in the code
Code:

 int8 coils = 0b00000101;
   int8 inputs = 0b00001001;
   int16 hold_regs[] = {0x8800,0x7700,0x6600};
   int16 input_regs[] = {0x1100,0x2200,0x3300,0x4400};


and
Code:

if(modbus_rx.func == FUNC_READ_COILS)
//Bugfix             modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
                     modbus_read_coils_rsp(MODBUS_ADDRESS, 0x01, &data);


according to the forum link
http://www.ccsinfo.com/forum/viewtopic.php?p=98454

and changed the address to #define MODBUS_ADDRESS 123

but still no success..I'm trying very hard to find out the solution.

Please help me.

thanks
Sid
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 12:19 am     Reply with quote

You are still sending to MODBUS address 01, it's the first byte in the telegram. I also wonder, where the received data come from, the slave won't respond. What's the RS485 adapter at the master side, does is set the bus idle level correctly?
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 12:28 am     Reply with quote

I have connected an adapter (Rs-485 to 232) between PC and slave device.
I'm not able to change anything at the master end. Sad
My connections are according to the link I provided

http://www.4freeimagehost.com/show.php?i=4d3b0503ee6d.jpg

What should I do next???
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 1:26 am     Reply with quote

I made the following changes
Code:

#define MODBUS_ADDRESS 0xF7


and the data transmitted was
[F7][03][00][00][00][40][50][AC]

ans received was
[04][7E][FF][FF][7F][5F][A7]

I have a little finding...I don't know if that will work...
the Led of the adapter for tx is blinking after every poll, however Led for receiving at the adapter on continuously.

so I removed the pull up resistor at the rx end. but still no change.
Ideally but the leds should be blinking.

Now I don't know if its the programming error or the connection error.

Please help

Thanks
Sid
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 12:24 pm     Reply with quote

The TX data is O.K.now, the RX data simply garbage. Most likely nothing, that has been send out by the slave.
Check your RS485 adapter, if it has the required pull-up/pull_down resistors at the bus terminals.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 8:52 pm     Reply with quote

Thanks FvM,
I will check the adapter connections (most likely guess they are ok) however can you please confirm if my connection from transceiver to PIC is ok?
And also please tell me if there are any bugs with existing ex_modbus_slave.c file.
Thanks,
sid
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Mar 02, 2011 1:56 am     Reply with quote

I think, there must be a RS485 hardware problem, because you're apparently receiving garbage characters, that haven't been send by the slave. Particularly, the slave won't send permanently. You should be able to check in addition, if the slave is sending anything.

The connection is correct as far as I see, but I'm using a different setup (PIC24 UART with hardware transmitter enable), so I didn't check the correct operation of the respective RS485 related parts of the MODBUS driver.

I think to remember, that I had corrected minor errors in a previous version of the MODBUS slave example, but I don't know, what it was.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Wed Mar 02, 2011 3:15 am     Reply with quote

Thanks FvM,

I will search the forum to find out bugs if any :(
I need to find out some way to establish this communication.
hope I come across something.

thanks,
Sid
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Mar 02, 2011 8:49 am     Reply with quote

I can't retrieve a bug now. I think, you should care for the other points first.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Wed Mar 02, 2011 9:26 am     Reply with quote

I had a card which has 8051 microcontroller on it, which uses modbus protocol. I connected the adapter to it and it was perfectly working fine. So i can conclude that the adapter is ok! So I'm left with nothing but to find out the software bug :-(
Please FvM, help me! I appreciate the effort you've taken till now.
Thanks for your time. Please do something!

Regards,
sid
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