|
|
View previous topic :: View next topic |
Author |
Message |
ufkyldrm
Joined: 21 May 2018 Posts: 27
|
Modbus RTU communication with OPC server |
Posted: Fri May 25, 2018 10:49 am |
|
|
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
|
Re: Modbus RTU communication with OPC server |
Posted: Fri May 25, 2018 11:01 am |
|
|
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
|
|
Posted: Fri May 25, 2018 11:03 am |
|
|
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
|
|
Posted: Sun May 27, 2018 4:48 am |
|
|
tank u for your effort
I added but nothing is change :( i m not using prote now, I m onboard.
Im using SN75176BP |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun May 27, 2018 5:32 am |
|
|
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
|
|
Posted: Sun May 27, 2018 5:53 am |
|
|
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
|
|
Posted: Sun May 27, 2018 1:38 pm |
|
|
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: 19546
|
|
Posted: Sun May 27, 2018 2:14 pm |
|
|
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
|
|
Posted: Sun May 27, 2018 3:48 pm |
|
|
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, )
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: 19546
|
|
Posted: Mon May 28, 2018 3:46 am |
|
|
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.
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
|
|
Posted: Mon May 28, 2018 8:58 am |
|
|
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.
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
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: 19546
|
|
Posted: Mon May 28, 2018 10:25 am |
|
|
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
|
|
Posted: Wed May 30, 2018 3:49 pm |
|
|
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: 9245 Location: Greensville,Ontario
|
|
Posted: Wed May 30, 2018 4:26 pm |
|
|
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
|
|
Posted: Wed May 30, 2018 4:41 pm |
|
|
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. |
|
|
|
|
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
|