|
|
View previous topic :: View next topic |
Author |
Message |
Orcino
Joined: 07 Sep 2003 Posts: 56
|
Modbus Slave - function 3 |
Posted: Fri Dec 30, 2016 6:21 am |
|
|
Hello guys,
First of all I thank the people who helped me with this project of communication with modbus Protocol.
It's almost 100%, but it's with an error.
I am sending some values to the master, but sometimes go with error.
See below in red lines.
Also below, the code I am using for testing.
Can anyone help ?
[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[FF][01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
[01][03][00][00][00][08][44][0C]
[FF][01][03][10][00][00][00][01][00][00][00][00][00][02][00][00][00][00][00][03][85][19][00]
Code: |
#include <24FJ128GA204.h>
//#device ICD=TRUE
#FUSES NOOSCIO
#FUSES PR
#FUSES HS
#FUSES NOWDT // No Watch Dog Timer
#FUSES NOJTAG // JTAG disabled
#FUSES NOCKSNOFSM // Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOIESO // Internal External Switch Over mode disabled
#FUSES NOWPFP // Write/Erase Protect Page Start/End Location, set to page 0
#FUSES NOBROWNOUT // No brownout reset
#FUSES NODSBOR // BOR disabled in Deep Sleep
#FUSES NODSWDT // Deep Sleep Watchdog Timer disabled
#FUSES NODS // Deep Sleep operation is always disabled
#use delay(clock=20MHz, crystal)
#use FIXED_IO( C_outputs=PIN_C4,PIN_C1,PIN_C5,PIN_C7,PIN_C8 )
#pin_select U2TX=PIN_C0
#pin_select U2RX=PIN_C2
#define MODBUS_BUS SERIAL
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA2
#define MODBUS_SERIAL_ENABLE_PIN PIN_C1
#define MODBUS_SERIAL_RX_ENABLE PIN_C1
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
//#define MODBUS_PARITY NONE
#define MODBUS_TIMER_USED MODBUS_TIMER_T2
#define MODBUS_TIMER_UPDATE MODBUS_TIMER_ISR
#include <modbus.c>
#define MODBUS_ADDRESS 0x01
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()
{
unsigned int16 hold_regs[8] = {0,0x01,0,0,0x02,0,0,0x03};
unsigned int16 input_regs[8] = {0,0,0,0,0,0,0,0};
unsigned int16 event_count = 0;
setup_adc_ports(NO_ANALOGS);
modbus_init();
while(TRUE)
{
while(!modbus_kbhit());
delay_us(50);
//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] >= 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;
default: //We don't support the function, so return exception
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
}
}
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Dec 30, 2016 6:33 am |
|
|
I don't use MODbus but those [FF] could be the data an idle line would be if read. If so, that might indicate a 'timing' issue.
Since all the other data are correct, it wouldn't be a 'speed' error(IE: tx at 9600, rx at 9601) more likely the 'time' between readings or perhaps the CE of the RS485 chip is 'slow' or you've got a delay_xx(yy) 'somewhere' that is just marginally correct.
Hopefully someone who uses the MODbus will pinpoint the solution.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 30, 2016 7:07 am |
|
|
According to this Modbus thread,
http://control.com/thread/1337684268
he says:
Quote: |
#3) lack of line bias on RS-485, which means when the master stops
sending & before the slave starts responding, the RS-485 lines float which
means you likely might see some garbage 0xFF or 0xFE bytes at the
start of the response.
|
Post a link to your RS-485 circuit schematic. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Dec 30, 2016 1:27 pm |
|
|
As I said in the thread the same poster had about Modbus a few days ago:
Quote: |
You should also have a pull-up resistor on the RX line out of the buffer (otherwise you can get spurious 'garbage' received when it is not receiving). Similarly, have you got the bus properly biased when idle?. This wouldn't cause a problem sending simple messages each way, but will with Modbus.
|
|
|
|
Orcino
Joined: 07 Sep 2003 Posts: 56
|
|
Posted: Fri Dec 30, 2016 3:43 pm |
|
|
Thank you all.
I put a resistor 120R in the PIC and one in the Master (PC).
I removed the resistor from the MASTER and is now working 100% without any error.
Now I can go to the new year's party.
Happy new year to all. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Dec 31, 2016 11:26 am |
|
|
You need termination at both ends of the 485 bus.
However the termination should be as shown here:
<https://en.wikipedia.org/wiki/RS-485>
Also the pull-up resistor I'm talking about is on the line between the buffer and the PIC. This line floats when the receiver is off, can lead to garbage being seen. Only something like 4K7R. |
|
|
|
|
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
|