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 CCS Technical Support

RS485 half duplex communication
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
ZZX
Guest







RS485 half duplex communication
PostPosted: Tue Apr 24, 2007 10:48 am     Reply with quote

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








PostPosted: Thu Apr 26, 2007 6:10 am     Reply with quote

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







PostPosted: Thu Apr 26, 2007 6:14 am     Reply with quote

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







PostPosted: Thu Apr 26, 2007 12:20 pm     Reply with quote

no suggestion .. still Crying or Very sad
funmix



Joined: 27 Mar 2007
Posts: 33

View user's profile Send private message

PostPosted: Thu Apr 26, 2007 10:10 pm     Reply with quote

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







PostPosted: Mon Apr 30, 2007 6:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 30, 2007 7:35 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 30, 2007 7:47 am     Reply with quote

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
PostPosted: Fri May 11, 2007 4:20 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Fri May 11, 2007 7:45 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 11, 2007 5:20 pm     Reply with quote

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







PostPosted: Mon May 14, 2007 3:21 am     Reply with quote

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








PostPosted: Mon May 14, 2007 3:26 am     Reply with quote

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







PostPosted: Mon May 14, 2007 3:27 am     Reply with quote

the above is my comment
ZZX
neverlog



Joined: 02 May 2010
Posts: 36

View user's profile Send private message

PostPosted: Sun Aug 01, 2010 8:51 am     Reply with quote

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!
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