|
|
View previous topic :: View next topic |
Author |
Message |
ZZX Guest
|
RS485 half duplex communication |
Posted: Tue Apr 24, 2007 10:48 am |
|
|
While implementing the RS485 single master/slave arch. i tried and tested using the examples (ex_rs232_485.c, ex_rs485.c) provided, with SN75176b transcievers. there are two questions i need to ask here:
1. The program hung after sending the strings correctly a few times, until i removed the "MULTI_MASTER" statement from #use rs232. it works perfect after this removal from rs485.c
2. I am still not able to receive a back "ACK" from my slave to ensure the half duplex mode. I read somewhere on the forum , that some chips need manual inversion of bus while others are intelligent enough. so how about 75176b?? Moreover with the programs, i dont find anything wrong with the code and have found out that although the first master hangs on to receive (TRUE mode in arguments of receive function) and the slave sends the back "ack" string, its not received properly..
Any suggestions ? |
|
|
Guest
|
|
Posted: Thu Apr 26, 2007 6:10 am |
|
|
Heres the problem and the code chunk. As soon as the slave receives the data and shows on the terminal it sends and ack to the master, which i see by the DE pin transition on the scope. However this aint received on properly by the master:
MASTER reception code:
Code: |
switch(command)
{
case 'S':
if(send_addr == 0 || send_addr > 255)
{
fprintf(PC,"\n\r\n\rEnter send address (1-255): ");
send_addr = PCgetInt();
}
fprintf(PC,"\n\r%d:>", send_addr);
RS485send(PCgetMsg(), send_addr);
fprintf(PC,"\n\r");
fprintf(PC,"\n\rSENT");
if(rs485_get_message(amsg, TRUE))
{
for(i=0; i<amsg> 0)
{
fprintf(PC,"\n\rIN_BUS_WAIT");
rs485_wait_for_bus(FALSE);
fprintf(PC,"\n\rOUT_BUS_WAIT");
while(!rs485_send_message(RS485_DEST_ID, i, amsg))
{
delay_ms(RS485_ID);
}
}
fprintf(PC,"\n\rACK-SENT");
|
Now with a simple network and above code and:
Code: |
RS485_USE_EXT_INT TRUE |
the master transmits but aint able to receive. CAN ANYBODY SUGGEST A GOOD REASON ? ? ? ? |
|
|
ZZX Guest
|
|
Posted: Thu Apr 26, 2007 6:14 am |
|
|
and the slave code:
Code: |
i=6;
if(i > 0)
{
fprintf(PC,"\n\rIN_BUS_WAIT");
rs485_wait_for_bus(FALSE);
fprintf(PC,"\n\rOUT_BUS_WAIT");
while(!rs485_send_message(RS485_DEST_ID, i, amsg))
{
delay_ms(RS485_ID);
}
}
fprintf(PC,"\n\rACK-SENT");
|
|
|
|
ZZX Guest
|
|
Posted: Thu Apr 26, 2007 12:20 pm |
|
|
no suggestion .. still |
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Thu Apr 26, 2007 10:10 pm |
|
|
Can you post your complete code for master and slave?
How about your hardware configuration? the H/F is 0 for full duplex, half duplex for 1 |
|
|
ZZX Guest
|
|
Posted: Mon Apr 30, 2007 6:00 am |
|
|
heres the slave Code: |
#include <16F877A.h>
#device *=16
#fuses HS,NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC)
//#use rs232(baud=9600, xmit=PIN_B3, rcv=PIN_B0, stream=PC)
// Defines the destination's RS485 ID
#define RS485_DEST_ID 1 //0x11
// Defines the device's RS485 ID
#define RS485_ID 1 //0x7F
#define RS485_USE_EXT_INT TRUE
#include <rs485.c>
int8 buffer[40];
int8 next_in = 0;
int8 next_out = 0;
#INT_RDA
//#INT_EXT
void serial_isr()
{
int8 t;
buffer[next_in] = fgetc(PC);
t = next_in;
next_in = (next_in+1) % sizeof(buffer);
if(next_in == next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in != next_out)
int8 bgetc()
{
int8 c;
while(!bkbhit);
c = buffer[next_out];
next_out = (next_out+1) % sizeof(buffer);
return c;
}
void main()
{
int8 i, msg[32];
int8 amsg[]="Aamir";
int8 msg_ack[32]="AlHamduLILLAH";
enable_interrupts(INT_RDA);
//enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
rs485_init();
fprintf(PC,"\n\rSlave");
for(;;)
{
if(rs485_get_message(msg, TRUE))
{
for(i=0; i<msg[1]; ++i)
fputc(msg[i+2], PC);
}
for(i=0; bkbhit && i<sizeof> 0)
{
fprintf(PC,"\n\rIN_BUS_WAIT");
rs485_wait_for_bus(FALSE);
fprintf(PC,"\n\rOUT_BUS_WAIT");
while(!rs485_send_message(RS485_DEST_ID, i, amsg))
{
delay_ms(RS485_ID);
}
}
fprintf(PC,"\n\rACK-SENT");
}
}
|
and this is the masters sending messages to slave and expecting return acknowledgements which arent received properly
Code: |
include <16F877A.h>
#device *=16
#fuses HS,NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC)
//#use rs232(baud=9600, xmit=PIN_B3, rcv=PIN_B0, stream=PC)
#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT TRUE
int8 OUR_RS485_ID = 0;
#define RS485_ID OUR_RS485_ID
#include <rs485.c>
#include <stdlib.h>
int8 in_char = 0;
int8 next_in = 0;
int8 next_out = 0;
int8 msg[64];
int8 amsg[64];
#INT_RDA
//#INT_EXT
void serial_isr()
{
in_char = fgetc(PC);
}
#INT_TIMER1
void timer1_isr()
{
int8 i;
if(rs485_get_message(msg, FALSE))
{
fprintf(PC,"MasterRX");
fprintf(PC,"\n\r%d: ", msg[0]);
for(i=0; i < msg[1]; ++i)
fputc(msg[i+2],PC);
fprintf(PC,"\n\r");
}
}
void RS485send(char* s, int8 id)
{
int8 size;
fprintf(PC,"\n\rIN_RS485send");
for(size=0; s[size]!='\0'; ++size);
fprintf(PC,"\n\rIN_BUS_WAIT");
rs485_wait_for_bus(FALSE);
fprintf(PC,"\n\rOUT_BUS_WAIT");
while(!rs485_send_message(id, size, s))
delay_ms(OUR_RS485_ID);
fprintf(PC,"\n\rOUT_RS485send");
}
char PCgetc()
{
in_char = 0;
while(!in_char);
return in_char;
}
int8 PCgetInt()
{
int8 i, s[3];
for(i=0; (s[i]=PCgetc()) != '\r' && i<3; ++i);
fprintf(PC,"%s",s);
return atoi(s);
}
char* PCgetMsg()
{
int8 i;
for(i=0; (msg[i] = PCgetc()) != '\r' && i<64>= 255)
{
fprintf(PC,"Please choose a network ID (1-255): ");
OUR_RS485_ID = PCgetInt();
}
fprintf(PC,"\n\rYour ID is: %d\n\r\n\rIf you require assistance, press h.\n\r", OUR_RS485_ID);
while(command != 'Q')
{
enable_interrupts(INT_TIMER1);
command = toupper(PCgetc());
disable_interrupts(INT_TIMER1);
switch(command)
{
case 'S':
if(send_addr == 0 || send_addr > 255)
{
fprintf(PC,"\n\r\n\rEnter send address (1-255): ");
send_addr = PCgetInt();
}
fprintf(PC,"\n\r%d:>", send_addr);
RS485send(PCgetMsg(), send_addr);
fprintf(PC,"\n\r");
fprintf(PC,"\n\rSENT");
if(rs485_get_message(amsg, TRUE))
{
for(i=0; i<amsg> 255)
{
fprintf(PC,"\n\r\n\rEnter send address (1-255): ");
send_addr = PCgetInt();
fprintf(PC,"\n\r");
}
break;
case 'I':
OUR_RS485_ID = 0;
while(OUR_RS485_ID == 0 || OUR_RS485_ID >= 255)
{
fprintf(PC,"\n\rPlease choose a network ID (1-255):");
OUR_RS485_ID = PCgetInt();
}
fprintf(PC,"\n\rYour ID is: %d\n\r\n\r", OUR_RS485_ID);
break;
case 'H':
fprintf(PC,"\n\rCommands: (S)end message, (C)hange Send Address, ");
fprintf(PC,"Change (I)D, (H)elp, (Q)uit.\n\r");
break;
default:
if(command != 'Q')
fprintf(PC,"\n\rInvalid command!\n\r");
}
}
}
|
|
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Mon Apr 30, 2007 7:35 am |
|
|
how you verify that the two PICs able to communicate with each other?
What ICs you use for communication? I hope your code is working. I am testing it
anyway, thanks for your code. |
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Mon Apr 30, 2007 7:47 am |
|
|
By the way, your code cannot be compiled. There are errors in slave and master main loop. Can you please verify again?
Thanks for your sharing code. |
|
|
ZZX Guest
|
correct code |
Posted: Fri May 11, 2007 4:20 am |
|
|
The code i posted was working for me (at least one way). May theres some change in header thats giving you the error. Its possible you have an older compiler version;the reason for an error. Probably somebody like PCM Programmer can answer that. For me, i left the whole idea of implementing Rs485, since i couldnt make it work; thanx to lack of help |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri May 11, 2007 7:45 am |
|
|
you may not have checked the
"Disable HTML in post"
Below the input windows for a forum message. This will screw up the code posted. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Fri May 11, 2007 5:20 pm |
|
|
Quote: |
I am still not able to receive a back "ACK" from my slave to ensure the half duplex mode
|
I dont´t see where or who is handling the Tx/Rx enable pin of the SN75176 transciever.
If you enable to transmit tied them to a fixed level, you can transmit but if you do not
change the transceiver control level for Rx listening, you will never receive the answer.
A workaround regarding this is to wire both control pins (2 and 3) to an output PIC
pin and use the option ENABLE in the #use RS232 directive to tell the compiler that
you are using an RS485 transceiver, then let the compiler to generate the appropiate
code to handle the communication direction control.
Humberto |
|
|
ZZX Guest
|
|
Posted: Mon May 14, 2007 3:21 am |
|
|
Quote: |
A workaround regarding this is to wire both control pins (2 and 3) to an output PIC pin and use the option ENABLE in the #use RS232 directive to tell the compiler that you are using an RS485 transceiver, then let the compiler to generate the appropiate code to handle the communication direction control.
|
well, this is whats being done in my case also. But since that part of code is written in RS485.c you couldnt see it in the main code
Code: |
#use rs232(baud=1200, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=9, long_data, errors, stream=RS485)
#use rs232(baud=1200, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=9, long_data, force_sw,errors, stream=RS485_CD)
|
I appreciate that you bothered to have a look at least. Can you find any other error? |
|
|
Guest
|
|
Posted: Mon May 14, 2007 3:26 am |
|
|
By the way, when the slave tries to transmit an ACK, i even see the this pin going high while trasmitting the ACK part; yet its not received by the master |
|
|
ZZX Guest
|
|
Posted: Mon May 14, 2007 3:27 am |
|
|
the above is my comment
ZZX |
|
|
neverlog
Joined: 02 May 2010 Posts: 36
|
|
Posted: Sun Aug 01, 2010 8:51 am |
|
|
hi all,
Does anyone know what is the difference among the following:
1) PBUSM
2) EX_RS485
3) MODBUS
Basically I need to have 16 Slaves and be linked to a PC. The PC will send commands to slave and retrieve data from each slave.
Can anyone help me?
Actually I don't which one to start with... Please help thanks! |
|
|
|
|
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
|