Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Communication Problem:: RS-485 (MASTER) and RS-485(SLAVES)

Status
Not open for further replies.

subspace

Newbie level 5
Newbie level 5
Joined
Mar 5, 2006
Messages
8
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,395
Hi,

I am working on a project of interfacing PIC uP (MASTER) to Multiple PIC uP (SLAVES) through the use of half-duplex RS-485 chips.

I am using daisy chain topology for my network.

Hardware configurations:
-----------------------------
all of the RS-485 chips are connected as follow to the PIC uP:

RS-485 pin PIC16F876
------------- -------------
RO RC7(RX)
RE' RC5
DE RC5
DI RC6(TX)

120ohm termination resistor on the Master side




Software Configurations:
-----------------------------
Compiler: HT-PIC C

I am using rs232 subroutines, except that before I call my subroutine, I switch on and off RC5 accordingly to what ever operation I am currently trying to implement.

that is if I am trying to transmit, I set RC5 to 1 and then I call putchar() subroutine. then once I have finished transmitting I set RC5 to 0 before I call getchar() subroutine.


The following is the software code:
====================================


1: /*==========================================================================*/
2: /* Send 8-bit char using USART and Interrupt handler */
3: /*--------------------------------------------------------------------------*/
4: void putchar (unsigned char data_out)
5: {
6: serial_time = 10; // format timeout value for serial comm
7:
8: while (!TXIF && serial_time) // Wait until transmit reg empty using interrupt flag: TXIF
9: {
10: line_error();
11: }
12:
13: TXREG = data_out; // Write to Transmiter register
14:
15: return; // Resume PIC normal operation
16: }
17:
18: /*==========================================================================*/
19: /* receive 8-bit char using USART and Interrupt handler */
20: /*--------------------------------------------------------------------------*/
21: bit getchar(unsigned char *data_in)
22: {
23: serial_time = 10; // format timeout value for serial comm
24:
25: while (!RCIF && serial_time) // Wait until character is received using Interrupt flag: RCIF
26: { // Loops until user send info.
27:
28: line_error();
29: }
30:
31: if (!serial_time)
32: {
33: return (FALSE);
34: }
35:
36: *data_in = RCREG; // assign incoming data to DATA_IN.
37:
38: return(TRUE); // Resume PIC normal operation
39: }
40:
41: //==============------------- MAIN PROGRAM ---------------==================
42:
43: /*========================================================================*/
44: /* The Main Program */
45: /*------------------------------------------------------------------------*/
46: main(void)
47: {
48: unsigned char bydata; // counter variable
49: unsigned char sData[3]; // outgoing buffer from MASTER to SLAVES
50: unsigned char sData2[3]; // incoming buffer from SLAVES to MASTER
51:
52:
53: InitProc(); // Initialize uP and registery
54: serial_init(31,1); // Init. serial port
55:
56: sData[0] = 0x01; // SLAVE device address
57: sData[1] = 0x0C; // Poll command
58: crcValue = 0xFF; // initialize crcValue;
59:
60: sData2[0] = 0x00; // Clear Incoming buffer.
61: sData2[1] = 0x00;
62: sData2[2] = 0x00;
63:
64:
65: while(1)
66: {
67: bydata = 0x00; // reset counter
68:
69: RS_485_crc_CALC(sData, 3); // Calculate crcValue
70:
71: sData[2] = (255 - crcValue); // append crc value to outgoing buffer
72:
73: crcValue = 0xFF; // Reset crcValue
74:
75: // Prepare the MAster to transmit data to slaves
76: //-----------------------------------------------
77: RC5 = 1; // enable RS-485 driver (transmitter)
78: TXEN = 1; // enable transmitter
79: CREN = 0; // disable receiver
80:
81: for (bydata = 0; bydata < 3 ; bydata++)
82: {
83: putchar(sData[bydata]); // Send out the data to slaves
84: }
85:
86: // Prepare the master to receive data from slave
87: //------------------------------------------------
88: TXEN = 0; // Disable Transmitter
89: CREN = 1; // Enable Receiver
90: RC5 = 0; // Enable RS-485 Receiver
91:
92: for (bydata = 0; bydata < 3; bydata++)
93: {
94: getchar(&sData2[bydata]); // receive incoming data from slaves
95: }
96:
97: // Heart Beat Indicator :: inidicate that the pic has reached the end of code cycle.
98: if (!LEDTime) // Check Countdown
99: {
100: RA4 = (RA4 == FALSE);
101: LEDTime = TIMER1_LED_DELAY; // Restart
102: }
103:
104: CLRWDT();
105:
106: }
107:
108: }
109:

The above code does not work.


But if you insert the following lines:

for(i=0; i<95; i++); between lines :: 83 and 84.
for(i=0; i<5000; i++); between lines :: 103 and 104.


The slave successfully receives the poll command, but still the MASTER can not receive the response back from the slave.


IS THIS A SOFTWARE ISSUE?
IS THIS A TIMING ISSUE?
 

did you tried to wait a bit after you switched your 485 chip to TX? check your datasheet
 
The receiver probably contains garbage from when the RS-485 receiver when from the previous enable to disabled. I would flush the UART receive buffer BEFORE re-enabling the RS-485 receiver. I am not familiar with how to do that on a PIC, on an AVR, I just read the buffer register and discard the result.

How long are your interconnect cables? Does it work with shorter cables? In a daisy chain topology, the lines should be terminated at the end-points only. However, this is often difficult. I have run RS-485 over cables at low baud rates without terminations at all. Instead, we put weak pullups on the non-inverting inputs and we put weak pulldowns on the inverting inputs. This helps to stablize the lines when the transmitter is turned off and no one is driving.
 

    subspace

    Points: 2
    Helpful Answer Positive Rating
Re: Communication Problem:: RS-485 (MASTER) and RS-485(SLAVE

When I've used RS-485 for long distances, I have not used terminators (works bad with them, especially when there are more than two devices connected to the line), but rather weak pullups on D+ and weak pulldowns on D- (about 100k). Two devices worked well on 1000 meter cable. The connection speed was 9600 bit/s.

Also, as say banjo, flush the uart....

Regards.
 

    subspace

    Points: 2
    Helpful Answer Positive Rating
Re: Communication Problem:: RS-485 (MASTER) and RS-485(SLAVE

Thank you guys for your help.

By the way, I think I forgot to mention the following parameters of my system:

1. Baud rate = 38,400 bits/sec

2. Max. Number of allowable slaves is 4.

3. Connection of about 1000 meter cable (maybe shielded twisted pair)

4. Since I have not tested my devices for a long range, so I could not tell you if my termination is working or not. I am using 120 ohm termination resistors. None the less I think I will use weak pull-up and pull down resistors, just to maintain stability at all time.

5. I thought that by enabling and disabling the transmitter on the PICs, you would be flushing the USART. I will read the manual again for PIC and see if this is true.


91_1179933028.jpg

This picture shows the control Line RC5 (CH2), and the outgoing data on line A (CH1).

85_1179933072.jpg

This picture shows the Control line RC5 (CH2), and incoming data on RC7 (RX)
[MASTER side].

29_1179933090.jpg
 

From your red and green dots, I would guess that the Master is not enabling the receive side of the RS485 chip or at least not fast enough. I would trigger the scope on the transmit side of the slave and then look at the RC5 pin of the master during the time that the slave is driving. Has the master switched into receive mode when the slave is taking?

Also, are you connecting together the grounds between the master and slave? Contrary to what alot of data sheets imply, this is a three wire interface. A twisted differential pair and a ground.
 

Re: Communication Problem:: RS-485 (MASTER) and RS-485(SLAVE

the slave obtains its gnd and power off the Master PCB board. thus the power and the ground are the same for both MASTER and Slave.

twisted shield pair cable will be used for A and B lines.


by the way, the track length for line A and B from the MASTER RS-485 chip to the SLAVE RS-485 chip is about 7 inches.
 
dont know pic , on avr there are 2 interrupts for uart , check that same on pic - one for transmit buffer empty second for transmit completed. Are you using both ?
(for fast interfacing both are mandatory, for slow the latter is a must ). If not using interrupts after the last byte loaded into transmit buffer (upon checking flag that transmit buffer is empty), wait at least one byte transfer time multiplied by 2 as there are 2 bytes to transfer (dont forget to count stop bits and start bits as well and add some additional time to ensure all data has been transmitted ), then switch to reception mode. On slave side switch to transmit mode with guard delay equal to same of master switch time (just to be sure that slave is in its slot) and then transmit data .

To check whether it is hardware issue - using simplex mode transfer in one way independently both slave to master and master to slave , Then you will be sure that drivers are OK.
For software ... check above.
 

Re: Communication Problem:: RS-485 (MASTER) and RS-485(SLAVE

have you put a pullup resitor on rc7?, why in the photo of scope rc5 is high during rx signal testing?
 

Re: Communication Problem:: RS-485 (MASTER) and RS-485(SLAVE

You don't change the direction of data flow. DE is active high, and RE is active low. When you are transmitting, you need to drive pin rc5 high. When you are receiving data, drive pin rc5 low (not tristate, but drive).
On the scope pin rc5 is high in both situations: when you transmitting and receiving data....
 

the best way is ground the RE pin. and u handle the DE pin with your master or slave what ever it is.

is the 120 ohm resistor is there on the slave side or not?

if not pls put the 120 ohm resistor there also for impedence matching.
 

I think it might just be a software issue. THe SAE J1708 are using RS485 as a multi-master network. (that's a system with echo though, the echo has been used for bus arbitration)

If I remember right, most of 485 interface has a different trigger on RE and DE pin, so I assume the circuit posted here is a non-echo design.

There is a small chance you might lose hand-shake when both micro try to talk. So please double check your timeing for the master/slave layout.
 

There is no reason, AFAIK, to disable your receiver. This has been mentioned.

In fact, the best way to determine when to release your drive, is when you
receive your own last character!

Also, the weak pullup/pulldown advice is good so that the lines don't simply float
when all drives are disabled. This is actually key to the operation of RS485 for J1708.

Rufus
 

How you have implemented the transmit enable/disable logic for RS-485 comms, because may be the receiver is not able to detect the start bit from the transmitter side. Its better to implement the control using hardware.

---------- Post added at 10:50 ---------- Previous post was at 10:30 ----------

First of all i would like to suggest not to use weak pull-up or pull-down for failsafe biasing because weak pull-ups are prone to noise , and the susceptibity of system to noise decreases.

Now using 120R termination resistor in parallel give 60R of impedence considering 50mV of noise in the system it is required to have at least 200+50mV of signal to be developed accros A(+) and B(-) to keep the system in stable condition when no comms. i.e. around 4mA of current should flow accross. If using 5V supply then the total fail safe resistance value would come around 1.2K

1.2K /2 gives around 600R on each side. This is equivalent fail safe value for 4 devices is 600R on each side, so each devices should have at least 2.4K of pull-up and pull-down. I think first of all the design should again be analysed of putting 100K.

Secondly i suggest to provide a hardware control Enable/disable signal for perfect matching of signals at such high baud rates.
This can simply be done using 555 timer or simply by an NPN transistor in switching mode.
Thirdly please verify for the characteristic impedence and Propogation velocity of the cable of you ae using, does the specification specifies CI to be of 120R.
 

Hello Everyone,
I am aware this is an older thread but I am having the same issues listed here so I thought I would ask the experts. I am using a PIC 24F device and a Max485 transceiver. The code I am using is adapted from
**broken link removed**
At the moment I have 3 Slave nodes and a Master built on breadboards just sending commands to light LEDS and respond and return a small amount of data. Every four or five commands the data is lost and not communicated. This is driving me crazy and I have tried the suggestions above I have tried pull ups and terminating resistors but get better results with nothing connected to the lines. I have tried using crystals to drive the PIC clocks to improve the timing without any real improvements. The specifications call for around 30 slave nodes so I am keen to improve the design before go ahead with PCB builds so any suggestions gratefully received.
John
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top