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

Reg: Pic communication with PLC

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



Joined: 09 Apr 2012
Posts: 19
Location: Salem

View user's profile Send private message

Reg: Pic communication with PLC
PostPosted: Thu May 23, 2013 12:07 am     Reply with quote

Hi,

I am using pic 16f877a for communicating with PLC. The PLC is using Modbus RTU (RS485) protocol. I have connected it with PC and using Rs232 hexcom tool. I have checked the communication. It is successful.

I have tried with these given address and values, And PLC has replied like given below,

transmitted code:010300060001640b then enter
010302015979EE

Then i interfaced the PLC with microcontroller (RS485 to UART). I used the following code,
Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
//use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=DOM,errors)
//#use rs232(baud=9600,parity=N,xmit=PIN_B0,rcv=PIN_B1,bits=8,stream=LED)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <lcd.c>

char ct[]={0x01,0x03,0x00,0x06,0x00,0x01,0x64,0x0B};
char st[]={0x01,0x03,0x00,0x0A,0x00,0x01,0xBD,0x47};
char cn[]={0x01,0x03,0x00,0x14,0x00,0x01,0xCA,0x41};

int counter = 0;
char a[7] = {0};
int1 flag = 0;

/*#int_RDA
void  RDA_isr(void)
{
 
   a[counter] = getc();
   counter ++;
   
}*/


void main()
{
   int i;
   lcd_init();
   delay_ms(5000);
   lcd_init();
   printf(lcd_putc,"WELCOME");
  // enable_interrupts(INT_RDA);
  // enable_interrupts(GLOBAL);
   while(1)
   {
   
   for(i = 0; i < 8; i++)
   {
      putc(ct[i]);
      delay_us(1000000/19200);
   }
   printf("\r");
   for(i = 0; i < 7; i++)
         lcd_putc(getc());
 
      counter = 0;
      flag = 0;
     
         
      delay_ms(5000);
      lcd_init();
      delay_ms(5000);
 
   
 
   
   }

   // TODO: USER CODE!!

}



The LCD displayed only 0103 character and stopped there itself. Is there any suggestion to get the proper values ?

I don't want to use modbus.c because i need only 3 values from the PLC.
_________________
Embedding Innovation
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 23, 2013 12:59 am     Reply with quote

What is your compiler version number?

ALWAYS add the 'errors' keyword to the #rs232 line, unless you have strong reasons to handle the errors situations yourself. The hardware UART will stop working when the receive buffer overflows, that is after receiving the 3rd byte without you reading from the FIFO. The effect is that you can only read 3 bytes and then on the next call to getc() the program waits forever.
When you add the 'errors' keyword the compiler will add code to clear the error bits and start the UART again (you can still loose data but at least new data will be received).

This looks very much like what is happening in your program, except that you receive 4 characters instead of the 3 that fit into the FIFO buffer.
varadharaj



Joined: 09 Apr 2012
Posts: 19
Location: Salem

View user's profile Send private message

compiler version number
PostPosted: Thu May 23, 2013 1:05 am     Reply with quote

4.074 is my version.

I used errors in the #use Rs232 line, but no change.
Thanks for your quick reply.
_________________
Embedding Innovation
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Thu May 23, 2013 2:38 am     Reply with quote

There is something fundamentally 'odd' about what you are doing/showing.

If the two lines shown with the PC comms, are hex displays of the data, then the the first byte reply will not be displayed as 01 on the LCD, but would be control code 01, which is the SOH character, and would not display as 01 on the LCD. However if they are ASCII displays of the data, then the sequence you are sending from the PIC, is not the same as the one from the PC.

0x1, is the character 1. the character '1' (ASCII), is 0x31.

Are you using RTU, or Modbus ASCII?.
If RTU, then your display code, needs to be:

printf(lcd_putc,"%02x",(getc());

since otherwise you are sending ASCII control codes to the LCD, not text.
Conversely, if it is Modbus ASCII, then your transmission is wrong, and needs to use:

printf("%02x",ct[i]);

One or the other is wrong.....

Best Wishes
varadharaj



Joined: 09 Apr 2012
Posts: 19
Location: Salem

View user's profile Send private message

communication
PostPosted: Thu May 23, 2013 3:21 am     Reply with quote

Sorry @telmah,

the origal line is,

printf(lcd_putc,"%x",getc());

I am using modbus RTU

Any delay should be given for sending and receiving. My baudrate is 19200..

thank you
_________________
Embedding Innovation
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Thu May 23, 2013 4:33 am     Reply with quote

Doesn't give great confidence, when you say "I used the following code", and then obviously didn't....
Done a modified version. See whether this works:
Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)

#include <lcd.c>

const char ct[]={0x01,0x03,0x00,0x06,0x00,0x01,0x64,0x0B};

#define BUFFER_SIZE 16
char rx_buffer[BUFFER_SIZE];
int next_in = 0;
int next_out = 0;
#define bkbhit (next_in!=next_out)

int16 wait_for=0;

#int_RDA
void  RDA_isr(void)
{
   int t;

   rx_buffer[next_in]=getc();
   t=next_in++;
   if (next_in == BUFFER_SIZE) next_in=0;
   if(next_in==next_out)
     next_in=t;           //overflow - throw data
}

char bgetc(void)
{
   char c;
   while(!bkbhit) ;
   c=rx_buffer[next_out];
   if (++next_out == BUFFER_SIZE) next_out=0;
   return(c);
}
#define BYTE_TIME (1000000/1920) //ten bits per byte time

#INT_TIMER2
void tick(void)
{
   //Timer called 125*/sec
   if (wait_for>0) --wait_for;
}

//This does nothing, except stop the compiler warning when ERRORS is enabled.
void dummy(void)
{
   int r;
   r=RS232_ERRORS;
}

void main()
{
   int i;
   lcd_init();
   delay_ms(1000);
   lcd_init();
   printf(lcd_putc,"WELCOME");
   setup_timer_2(T2_DIV_BY_16,249,10); //125Hz tick
   
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER2);
   delay_ms(1000); 
   while(TRUE)
   {
       //Must delay for 3.5 byte times before transmission
       delay_us(BYTE_TIME*3.5);
       for(i = 0; i < SIZEOF(ct); i++)
       {
          putc(ct[i]);
       }
       //Modbus RTU does _not_ have a CR at the end.
       //Only modbus ASCII has this
       //Now wait for reply.
       wait_for=5;
       while (wait_for);
       lcd_putc('\f');
       while (bkbhit)
       {
          //print any reply
          printf(lcd_putc,"%02x",bgetc());
       }
   }
}
varadharaj



Joined: 09 Apr 2012
Posts: 19
Location: Salem

View user's profile Send private message

Thanks
PostPosted: Thu May 23, 2013 7:27 am     Reply with quote

Thank you very much Ttelmah,

The code which you have posted is really helpful for me to understand about the delays at start and end.

I changed your code little bit for my application. And it is working perfectly.

Thanks to you and cliestra for helping ...
_________________
Embedding Innovation
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