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 communication

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nasbyc



Joined: 27 Apr 2009
Posts: 50

View user's profile Send private message AIM Address

rs485 communication
PostPosted: Thu Nov 01, 2012 8:24 am     Reply with quote

Hi, I used one of the programs posted in the forum and modified it. I tried with 1 master and 2 slave pic. It worked when I try to send data from master to the slave. The problem is to tell the master the program is complete.

Here is the master program:
Code:

#include <18F2480.h>
#use delay(clock=20000000)
#fuses hs, nowdt, nolvp, noprotect
#use rs232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_A1, Errors, STREAM=COM_A)
#byte RCREG = 0x1A

#include <stdlib.h>
#include <string.h>

#byte portB=6
#byte portC=7
#define RX_SIZE 10             // RS232 buffer for serial reception
#define RCV_OFF() {setup_uart(FALSE);}

int RX_Command_Ready;         // TRUE If a receive packet is ready

char RxBuffer[RX_SIZE];       // RS232 serial RX buffer
int Index = 0;                // RS232 RX data IN index

#INT_RDA                      // Interrupt driven RS232 routine
void rs232_isr(void)
{
   char temp;                 // local data storage

   temp = fgetc(COM_A);       // get rx data

   // If we got a '#', then the command is beginning.
   if (temp == '#')
      {
         Index = 0;
         RxBuffer[Index] = temp;
         Index++;
         return;
      }
   // If we got a 'A', then the command is completed.
   if (temp == 65)
      {
         temp = '\0';
         RxBuffer[Index] = temp;
         RX_Command_Ready = TRUE;
         return;
      }

   // Save the character to the receive buffer.
   RxBuffer[Index]=temp;

   // Check for buffer overflow.
   if ( Index >= (RX_SIZE - 1) )
      Index = 0;
   else
      Index++;
}

void main()
{
   char motor[7] = "#5128A";
   char strmotor[3] = "CD";
   char status_motor[3];
   int8 *motorpointer;
   int i,s,iresult;

   iresult = 1;

      printf("\nProgram started...\r\n");

      motorpointer = motor;
      for(i=0; i < 7;i++)
      {
         fputc(*motorpointer,COM_A);
         ++motorpointer;
      }
      do{
            enable_interrupts(INT_RDA);
            enable_interrupts(GLOBAL);
            //fprintf(COM_A,"\nReady to receive data");

            while(RX_Command_Ready == TRUE)
            {
               disable_interrupts(INT_RDA);
               fprintf(COM_A,"\n");
               //fprintf(COM_A,"\nData received");
     
               for(s=0;RxBuffer[s]!='\0';s++)
               {
                  fprintf(COM_A,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
               }

               status_motor[0] = RxBuffer[1];
               status_motor[1] = RxBuffer[2];
               status_motor[2] = '\0';
     
               iresult = strcmp(status_motor,strmotor);
               fprintf(COM_A,"status_motor = %c%c iresult = %d \n",status_motor[0],status_motor[1],iresult);
     
               if(iresult == 0)
               {
                  fprintf(COM_A,"Next sequence please\n");
                  RX_Command_Ready = FALSE;
                  break;
               }
               else
               {
                  fprintf(COM_A,"WRONG!!!!\n");
               }
            }
       }while(1);
}



slave
Code:

#include <16f88.h>
#fuses HS,PUT,NODEBUG,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B2,enable = PIN_A1 ,stream = COM_C)

#include <stdlib.h>
#include <string.h>

#byte portB=6
#byte portC=7

int RX_Command_Ready;         // TRUE If a receive packet is ready

#define RX_SIZE 10             // RS232 buffer for serial reception
#define AN0 0X0E
#define RCV_OFF() {setup_uart(FALSE);}

char RxBuffer[RX_SIZE];       // RS232 serial RX buffer
int Index = 0;                // RS232 RX data IN index

#INT_RDA                      // Interrupt driven RS232 routine
void rs232_isr(void)
{
   char temp;                 // local data storage

   temp = fgetc(COM_C);       // get rx data

   // If we got a '#', then the command is beginning.
   if (temp == '#')
      {
         Index = 0;
         RxBuffer[Index] = temp;
         Index++;
         return;
      }
   // If we got a 'A', then the command is completed.
   if (temp == 65)
      {
         temp = '\0';
         RxBuffer[Index] = temp;
         RX_Command_Ready = TRUE;
         return;
      }

   // Save the character to the receive buffer.
   RxBuffer[Index]=temp;

   // Check for buffer overflow.
   if ( Index >= (RX_SIZE - 1) )
      Index = 0;
   else
      Index++;
}

#byte RCREG = 0x1A
void clear_usart_receiver(void);void MotorFish_CW(); void MotorFish_CCW(); void MotorFish_Stop (); void RCV_ON(void);

void main(void)
{
   int8 strnum1;
   unsigned int8 Desired_Angle;
   int8 idslave = 5;
   char slavenum[2];
   char angledata[4];
   int s,m;

   char motorstatus[5] = "#CDA";
   int8 *motorcomplete;


   //output_high(PIN_A2);
   //delay_ms(1000);

   //output_low(PIN_A2);
   //delay_ms(1000);

   do
   {
      enable_interrupts(INT_RDA);
      enable_interrupts(GLOBAL);

         while(RX_Command_Ready == TRUE)
         {
            disable_interrupts(INT_RDA);
            fprintf(COM_C,"\n");

            for(s=0;RxBuffer[s]!='\0';s++)
            {
               fprintf(COM_C,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
            }

            printf("\n");
            slavenum[0] = RxBuffer[1];
            slavenum[1] = '\0';
            angledata[0] = RxBuffer[2];
            angledata[1] = RxBuffer[3];
            angledata[2] = RxBuffer[4];
            angledata[3] = '\0';

            strnum1 = atoi(slavenum);
            Desired_Angle = atoi(angledata);
            if(strnum1 == idslave)
            {
               output_high(PIN_A2);
               delay_ms(1000);

               output_low(PIN_A2);
               delay_ms(1000);

               motorcomplete = motorstatus;
               for(m=0; m < 5;m++)
               {
                  fputc(*motorcomplete,COM_C);//to tell master the prog complete
                  ++motorcomplete;
               }

            RX_Command_Ready = FALSE;
            break;
            //enable_interrupts(INT_RDA);
            }
         }
   }while(1);
}



the result from master
Code:

Program started...
#5128A


the result from slave
Code:

RxBuffer[0] = #
RxBuffer[1] = 5
RxBuffer[2] = 1
RxBuffer[3] = 2
RxBuffer[4] = 8

#CDA


It can be seen that in master, RX_Command_Ready == TRUE never occurs. So I try to display what data is actually in RxBuffer:
Code:

Program started...
#5128A

RxBuffer[0] =
RxBuffer[1] =
RxBuffer[2] =
RxBuffer[3] =
RxBuffer[4] =
RxBuffer[5] =
RxBuffer[6] =
RxBuffer[7] =
RxBuffer[8] =
RxBuffer[9] =
RxBuffer[10] =
RxBuffer[11] = #
RxBuffer[12] = 5
RxBuffer[13] = 1
RxBuffer[14] = 2
RxBuffer[15] = 8
RxBuffer[16] = A
RxBuffer[0] =
RxBuffer[1] =

So the error is that the master never receive the data send by the slave and RxBuffer is filled with the data send by the master previously. How can I clear the buffer after I send data and make it ready to receive a new data ?
nasbyc



Joined: 27 Apr 2009
Posts: 50

View user's profile Send private message AIM Address

PostPosted: Fri Nov 02, 2012 4:56 am     Reply with quote

Anyone?

I tried setup_uart(False) and setup_uart(True) before and after sending data. however no data been sending out.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Nov 02, 2012 5:39 am     Reply with quote

The buffer _will_ be overwritten as soon as data comes back.
There are several things that are basically 'wrong', but it is also not very obvious what you are doing. Gven your buffer names are the same in the master and the slave, which are you looking at?.

No ERRORS in slave.

Your slave code does send the transmitted data back:
Code:

            for(s=0;RxBuffer[s]!='\0';s++)
            {
               fprintf(COM_C,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
            }

So this data will be in the buffer. It doesn't get there any other way.

Your buffer size in is only 10bytes, but you print 17 bytes.....

You have statements like:
Code:

#byte portB=6
#byte portC=7

Which are fundamentally 'wrong'. These are the addresses for a PIC16, you are using a PIC18.....

You are also mixing using putc to a stream, and and without a stream name. With only one stream these go to the same place.

I'm afraid it is not plain from what you post, what you want to happen, what you think will happen, what is actually happening, etc. etc.. The code is a mess. You have obviously taken part of a routine, and not correctly patched it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Nov 02, 2012 8:03 am     Reply with quote

Looking at this again, look at some of the threads about RS485. Ideally you want to disable the RX buffer when you transmit, or the master will receive every byte it sends. You also then want to bias the data output of the receive buffer to +5v, so when the data is being sent, the receive part sees the line as idle. This is done by wiring the two enable pins together, and to the CPU enable pin.
I don't think you are turning the bus round correctly.

Best Wishes
nasbyc



Joined: 27 Apr 2009
Posts: 50

View user's profile Send private message AIM Address

PostPosted: Fri Nov 02, 2012 10:39 am     Reply with quote

I'm using max481 as a driver. I also had wired re and de pin together to pic. Is it necessary to turn on /off receiver when transmitting data ? I successfully transmit #1128A from master to slave. I know this because the led attached to the slave on/off accordingly. The problem is when to tell to master that the slave already received the data. So that the master can send another #5127A (for example with same length) to id another slave pic.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Nov 02, 2012 3:16 pm     Reply with quote

You are turning the receiver off if you operate both RE and DE. But you do need a pull up resistor on the RX input of the PIC, so it doesn't see garbage when the receiver is turned off. Something like 10KR.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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