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 RTU communication with OPC server
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
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

Modbus RTU communication with OPC server
PostPosted: Fri May 25, 2018 10:49 am     Reply with quote

Hi guys.


I need communicate with pic to Modbus pool program. But somehow my code doesn't work. Modbus pool is master device and pic is slave.

Can you help me, what is problem. :(

My code:
Code:
#include <16F877A.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=20000000)   // osilatör hızı
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU     //use MODBUS_ASCII for ASCII mode
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600

#ifndef USE_WITH_PC
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#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_A3   // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE   PIN_A3 // Controls RE pin for RS485
#endif

#include <modbus.c>

#define MODBUS_ADDRESS 3

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;

   setup_adc_ports(NO_ANALOGS);

   modbus_init();

   while(TRUE)
   {

    hold_regs[0]=100;
   
//!    input_regs[1]=0xAA;
//!    input_regs[2]=0xAA;
  //  hold_regs[0]=0x55;
//!    hold_regs[1]=0x55;
//!    hold_regs[2]=0x55;
   
      while(!modbus_kbhit());
      //check address against our address, 0 is broadcast
       delay_us(50);
      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
               {
                  if(modbus_rx.data[2] == 0xFF)
                     bit_set(coils,modbus_rx.data[1]);
                  else
                     bit_clear(coils,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
               {
                  hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[2],modbus_rx.data[3]);

                  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],modbus_rx.data[j+1]);

                  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);
         }
      }
  }
}


Modbus tool program settings.

https://ibb.co/fXwyqo
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Modbus RTU communication with OPC server
PostPosted: Fri May 25, 2018 11:01 am     Reply with quote

ufkyldrm wrote:

#include <16F877A.h>
#device ADC=16

#FUSES NOWDT //No Watch Dog Timer

#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=20000000) // osilatör hızı

You're missing the oscillator fuse. You need to add the HS fuse.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 25, 2018 11:03 am     Reply with quote

In fact, in a previous thread, you had a similar problem with fuses:
http://www.ccsinfo.com/forum/viewtopic.php?t=57205

One place where fuses don't matter is in Proteus Isis simulator.
You know we don't like Proteus problems.
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Sun May 27, 2018 4:48 am     Reply with quote

tank u for your effort Smile

I added but nothing is change :( i m not using prote now, I m onboard.

Im using SN75176BP
temtronic



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

View user's profile Send private message

PostPosted: Sun May 27, 2018 5:32 am     Reply with quote

The 75176 is an RS485 device if I'm thinking right. If so what are the pullup, pulldown and termination resistors values you're using? Have you got A to A, B to B and not A to B, B to A ?

This is assuming the PIC does run at the correct speed of course...
Jay
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Sun May 27, 2018 5:53 am     Reply with quote

temtronic wrote:
The 75176 is an RS485 device if I'm thinking right. If so what are the pullup, pulldown and termination resistors values you're using? Have you got A to A, B to B and not A to B, B to A ?

This is assuming the PIC does run at the correct speed of course...
Jay


I'm using this hardware
http://elektrotasarim.com/UARTtoRS485_Breakout.html
datasheet
http://elektrotasarim.com/UARTtoRS485_Breakout.pdf

Everything good with this hardware on arduino platform, İ controlled it. But I want to use on pic.

I'm using A B and GND terminals.


No response from pic.

https://ibb.co/jPeUi8
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Sun May 27, 2018 1:38 pm     Reply with quote

I guess my code is stuck on while(!modbus_kbhit());


please help me Ttelmah, PCM programmer. You are my idoll :(

I scope data transmit pin and pc send datas very good but there is no answer. TX pin everytime on high mode.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sun May 27, 2018 2:14 pm     Reply with quote

I don't see where you are telling the driver what port pins and interface to actually use for the RS232?.
Are you actually using C6/C7/A3?. Double checked the wiring?.
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Sun May 27, 2018 3:48 pm     Reply with quote

Ttelmah wrote:
I don't see where you are telling the driver what port pins and interface to actually use for the RS232?.
Are you actually using C6/C7/A3?. Double checked the wiring?.


I'm using this below component. It has rx tx and enable pins. I joined these pins with pics related pins.

http://elektrotasarim.com/UARTtoRS485_Breakout.html

and with this component i send data to computer with RS485 to USB converter.


pic wiring (16F877A)
https://ibb.co/eHNWyJ

General wiring.
https://ibb.co/hXCpJJ
(I'm using arduino just get 5V and gnd, Smile )


My purpose is send data from slave devices to OPC Server (Kepware) with rs485 protocol.

Do you have any suggestion? :/ Do you think my code has no fault? So you said control your wiring?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon May 28, 2018 3:46 am     Reply with quote

A suite of separate things:

First this is horrific layout. No sign of decoupling adjacent to the PIC pins. Long supply wires going to different points on the power rails. I'm amazed it actually runs. The old 877 is a forgiving chip, and you are relying on this to get anything working.... It's difficult to do any worthwhile checking of the layout on what is posted. I can't see for sure what pin anything actually goes to. Sad

Then biasing. The RS485 bus _requires_ biasing so that it given zero out when idle. Especially with a first generation transceiver like the 176. Pull slyt514.pdf from Texas, which describes this. This is essential.
Then biasing again. The RX input to the PIC requires a pull-up resistor to 5v so it idles high. There is a resistor location on the breakout board which may be to provide this, but the pictures show this as unpopulated. This again is essential.
Then termination. There appears to be a location for a termination resistor on the RS485 bus on the board but this again is shown as unpopulated. For short lengths you may well be able to work without termination, but the system will work better with it.

Realistically you need to start one step at a time. Get RS485 comms working between the PIC and the PC before making any attempt to try to get Modbus working. Walk before running.
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Mon May 28, 2018 8:58 am     Reply with quote

Ttelmah wrote:
A suite of separate things:

First this is horrific layout. No sign of decoupling adjacent to the PIC pins. Long supply wires going to different points on the power rails. I'm amazed it actually runs. The old 877 is a forgiving chip, and you are relying on this to get anything working.... It's difficult to do any worthwhile checking of the layout on what is posted. I can't see for sure what pin anything actually goes to. Sad

Then biasing. The RS485 bus _requires_ biasing so that it given zero out when idle. Especially with a first generation transceiver like the 176. Pull slyt514.pdf from Texas, which describes this. This is essential.
Then biasing again. The RX input to the PIC requires a pull-up resistor to 5v so it idles high. There is a resistor location on the breakout board which may be to provide this, but the pictures show this as unpopulated. This again is essential.
Then termination. There appears to be a location for a termination resistor on the RS485 bus on the board but this again is shown as unpopulated. For short lengths you may well be able to work without termination, but the system will work better with it.

Realistically you need to start one step at a time. Get RS485 comms working between the PIC and the PC before making any attempt to try to get Modbus working. Walk before running.



Thank uuuuuu :=) I'm noob, i try to do my best.

I ll do what u are said then, I'll write here. I took my lessons Smile


Any advice for RS485 terminal instead of SN75176 component ? I heard MAX485 any other?


Ttelmah wrote:

Realistically you need to start one step at a time. Get RS485 comms working between the PIC and the PC before making any attempt to try to get Modbus working. Walk before running.


How I can control PIC and PC RS485 communication without these component? U mean i need to RS232 communication?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon May 28, 2018 10:25 am     Reply with quote

Read the application note I suggested. You can only get away without termination if both transceivers are types that give an idle output for an undriven bus. 99.9% of transceivers _will_ require bus biasing. It is better to always have it. The MAX485 still requires biasing.
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Wed May 30, 2018 3:49 pm     Reply with quote

Ttelmah wrote:
Read the application note I suggested. You can only get away without termination if both transceivers are types that give an idle output for an undriven bus. 99.9% of transceivers _will_ require bus biasing. It is better to always have it. The MAX485 still requires biasing.


I did everything u say. I used bias, terminal resistor and rx to pull up resistor,... But nothing changed. I guess my code has fatal fault. I wanna die anymore.

I control every wire...

My code is stuck on while(!modbus_kbhit()) and enable pins don't do their job, Every time it is off mode.

In transmitter rx pin being high and low.

but because of enable pins, tx is high everytime, it is waiting enable pins.

I controlled transmitter on Arduino platform and it is work well with it.

I tried debug program with LCD...

My code is

Code:
#include <16F877A.h>
//#device ADC=10
#define USE_WITH_PC 1
#fuses HS,NOWDT
//,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(crystal=20M)
//--------------------------40 pin MCU PIN_diagram
//                        _____________
//MCLR/VPP----------------|1         40|-------RB7/PGD
//RA0/AN0-----------------|2         39|-------RB6/PGC
//RA1/AN1-----------------|3         38|-------RB5
//RA2/AN2/VREF-/CVREF-----|4         37|-------RB4
//RA3/AN3/VREF+-----------|5         36|-------RB3/PGM
//RA4/T0CKI/C1OUT---------|6         35|-------RB2
//RA5/AN4/SS/C2OUT--------|7         34|-------RB1
//RE0/RD/AN5--------------|8         33|-------RB0/INT
//RE1/WR/AN6--------------|9         32|-------VDD
//RE2/CS/AN7--------------|10        31|-------VSS
//VDD---------------------|11        30|-------RD7/PSP7
//VSS---------------------|12        29|-------RD6/PSP6
//OSC1/CLKI---------------|13        28|-------RD5/PSP5
//OSC2/CLKO---------------|14        27|-------RD4/PSP4
//RC0/T1OSO/T1CKI---------|15        26|-------RC7/RX/DT
//RC1/T1OSI/CCP2----------|16        25|-------RC6/TX/CK
//RC2/CCP1----------------|17        24|-------RC5/SDO
//RC3/SCK/SCL-------------|18        23|-------RC4/SDI/SDA
//RD0/PSP0----------------|19        22|-------RD3/PSP3
//RD1/PSP1----------------|20        21|-------RD2/PSP2
//                        |____________|

#define MODBUS_BUS SERIAL
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_SERIAL_ENABLE_PIN PIN_B7
#define MODBUS_SERIAL_RX_ENABLE PIN_B7
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_OUR_ADDRESS 10
#include "modbus.c"

//#use fast_io(a)
//#use fast_io(b)
//#use fast_io(c)
//#use fast_io(d)
//#use fast_io(e)



#define LCD_ENABLE_PIN  PIN_D1
#define LCD_RS_PIN      PIN_D2
#define LCD_RW_PIN      PIN_D3
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7

#include "lcd.c"

#define MODBUS_ADDRESS 0x05

#define OUT1   PIN_C0
#define OUT2   PIN_C1
#define OUT3   PIN_C2
#define OUT4   PIN_C3

int8 coils = 0b00000000;
int8 inputs = 0b00000000;
int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 input_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 event_count = 0;


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);
}

#zero_ram
void main()
{

   //set_tris_a(0xFF);
   //set_tris_e(0b111);
   //set_tris_b(0x00);
   //set_tris_c(0b10000000);
   //set_tris_d(0x00);
   
   modbus_init();
   lcd_init();
   delay_ms(1000);
   
   lcd_gotoxy(1,1);
   delay_ms(100);
   lcd_putc("ASLAN UFUK");
   delay_ms(100);



   while(TRUE)
   {
      if (bit_test(coils,0) == 1)
         OUTPUT_HIGH(OUT1);
      else
         OUTPUT_LOW(OUT1);
         
      if (bit_test(coils,1) == 1)
         OUTPUT_HIGH(OUT2);
      else
         OUTPUT_LOW(OUT2);
         
      if (bit_test(coils,2) == 1)
         OUTPUT_HIGH(OUT3);
      else
         OUTPUT_LOW(OUT3);
         
      if (bit_test(coils,3) == 1)
         OUTPUT_HIGH(OUT4);
      else
         OUTPUT_LOW(OUT4);
        hold_regs[0]=12;
     lcd_gotoxy(1,2);
     printf(lcd_putc,"%4LX",hold_regs[0]);
   
      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_coils_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
               {
                  if(modbus_rx.data[2] == 0xFF)
                     bit_set(coils,modbus_rx.data[1]);
                  else
                     bit_clear(coils,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
               {
                  hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[2],modbus_rx.data[3]);

                  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],modbus_rx.data[j+1]);

                  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);
         }
      }
  }
}


So I try to send and get data with master pool program but cant receive data.
:(((((((((((((


Last edited by ufkyldrm on Thu May 31, 2018 4:10 am; edited 1 time in total
temtronic



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

View user's profile Send private message

PostPosted: Wed May 30, 2018 4:26 pm     Reply with quote

hmm. perhaps you can put the MODBUS code aside and code for a simple RS485 echo program ? CCS may have one in the examples folder ?

Use one PIC as a 'master', the other the 'slave'. Have the master send 'M' to the slave, then the slave sends 'S' to the master.

I have zero experience with the CCS MODBUS driver however where your program gets 'hung' could either be hardware or software so getting a simple RS485 program to work would eliminate the 'bad hardware' possibility.

On the software side, is your 'master' device sending to the correct MODBUS address ? I think I saw '5' as the slave, so be sure the master transmits to '5'.

just some ideas.
Jay
ufkyldrm



Joined: 21 May 2018
Posts: 27

View user's profile Send private message

PostPosted: Wed May 30, 2018 4:41 pm     Reply with quote

temtronic wrote:
hmm. perhaps you can put the MODBUS code aside and code for a simple RS485 echo program ? CCS may have one in the examples folder ?

Use one PIC as a 'master', the other the 'slave'. Have the master send 'M' to the slave, then the slave sends 'S' to the master.

I have zero experience with the CCS MODBUS driver however where your program gets 'hung' could either be hardware or software so getting a simple RS485 program to work would eliminate the 'bad hardware' possibility.

On the software side, is your 'master' device sending to the correct MODBUS address ? I think I saw '5' as the slave, so be sure the master transmits to '5'.

just some ideas.
Jay


Yes it is send to 5 as the slave. :( I've used this modbus program for other devices many times. It works good.
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