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

Help with RS485_get_message

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



Joined: 21 Aug 2009
Posts: 15
Location: Texas

View user's profile Send private message

Help with RS485_get_message
PostPosted: Fri Aug 21, 2009 4:16 pm     Reply with quote

Hi,

I am trying to set up a simple communication between two PIC18f252 using two MAX487. I was able to transmit data but I am unable to receive it using the RS485_get_message function from the RS485.c library (If I use getc() I can see the data I was transmitting). I'm sure its a matter of how I'm setting it up. Any help is appreciated. Also I am using Proteus ISUS to simulate the PIC to PIC communication. My receiver code is as follows.

Thanks

Code:

#include <18f252.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use    delay(clock=10000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, stream=PC)

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B1
#define LCD_ENABLE_PIN  PIN_B2
#define LCD_DATA0       PIN_B4
#define LCD_DATA1       PIN_B5
#define LCD_DATA2       PIN_B6
#define LCD_DATA3       PIN_B7   

#include <lcd2.h>

#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT FALSE
#define  RS485_ID             0x09

#define RS485_ENABLE_PIN      PIN_C5
#define RS485_TX_PIN       PIN_C6
#define RS485_RX_PIN       PIN_C7

#include <rs485.c>
#include <stdlib.h>

void LCD_CHECK();

int8 msg[32];

void main()
{
   set_tris_b(0x00);
   set_tris_c(0x80);
   output_low(RS485_ENABLE_PIN); 
      rs485_init();
   lcd_init();
   LCD_CHECK();

   while(true)   
   {
      rs485_get_message(msg, TRUE);
      printf(lcd_putc, "%d ", msg);
   }
}

void LCD_CHECK()
{
   lcd_gotoxy(1,1);
   printf(lcd_putc, "System Ready");
   delay_ms(500);
   printf(lcd_putc,"\f");
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2009 4:23 pm     Reply with quote

Quote:
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, stream=PC)

The #use rs232() library code has an "ENABLE=pin #" feature, where
you can specify the enable pin, in the same way as the xmit and rcv pins.
See this CCS driver file for an example:
Quote:
c:\program files\picc\drivers\rs485.c
arloedx



Joined: 21 Aug 2009
Posts: 15
Location: Texas

View user's profile Send private message

PostPosted: Mon Aug 24, 2009 10:37 am     Reply with quote

I added the "enable = pin_c5" PCM programmer suggested but still I have problems. I will provide my transmitter source code, the reciever source code and the schematics to show the entire picture...

Master Transmitter Code:
Code:

#include <18f252.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use    delay(clock=10000000)

#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7)

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B1
#define LCD_ENABLE_PIN  PIN_B2
#define LCD_DATA0       PIN_B4
#define LCD_DATA1       PIN_B5
#define LCD_DATA2       PIN_B6
#define LCD_DATA3       PIN_B7   

#include <lcd2.h>

#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT FALSE

#define  RS485_ID             0x01
#define  RS485_DEST_ID        0x09
#define RS485_ENABLE_PIN      PIN_C5
#define RS485_TX_PIN       PIN_C6
#define RS485_RX_PIN       PIN_C7

#include <rs485.c>
#include <stdlib.h>

void LCD_CHECK();
void state(unsigned char s);
void frequency(unsigned char frc);

void LCD_CHECK()
{
   lcd_gotoxy(1,1);
   printf(lcd_putc, "System Ready");
   delay_ms(500);
   printf(lcd_putc,"\f");
}
int8 size=1;
int i, max = 5 ;
int8 bufsend[5] = {'A','B','C','D','E'};
int *pointer;

void main()
{
      set_tris_b(0x00);
   set_tris_c(0x80);
   output_high(RS485_ENABLE_PIN);
      rs485_init();
   lcd_init();
   LCD_CHECK();
   while(true)
      {
      for(i=0; i<max; i++)
      {
         pointer = &bufsend[i];
         rs485_wait_for_bus(TRUE);     
               rs485_send_message(RS485_DEST_ID, size, pointer);       
          printf(lcd_putc,"\fSent: %c", bufsend[i]);
          delay_ms(400);
      }
      delay_ms(1000); 
   }
}



Slave Receiver Code:
Code:

#include <18f252.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use    delay(clock=10000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, enable = PIN_C5, stream=PC)

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B1
#define LCD_ENABLE_PIN  PIN_B2
#define LCD_DATA0       PIN_B4
#define LCD_DATA1       PIN_B5
#define LCD_DATA2       PIN_B6
#define LCD_DATA3       PIN_B7   

#include <lcd2.h>

#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT FALSE
#define  RS485_ID             0x09

#define RS485_ENABLE_PIN      PIN_C5
#define RS485_TX_PIN       PIN_C6
#define RS485_RX_PIN       PIN_C7

#include <rs485.c>
#include <stdlib.h>

void LCD_CHECK();

int8 msg[32];

void main()
{
   set_tris_b(0x00);
   set_tris_c(0x80);
   output_low(RS485_ENABLE_PIN); 
      rs485_init();
   lcd_init();
   LCD_CHECK();

   while(true)   
   {
      rs485_get_message(msg, FALSE);
      printf(lcd_putc, "%d ", msg[1]);
                delay_ms(400);
   }
}

void LCD_CHECK()
{
   lcd_gotoxy(1,1);
   printf(lcd_putc, "System Ready");
   delay_ms(500);
   printf(lcd_putc,"\f");
}


This outputs the following in the simulation:

There are a couple of things wrong with this...the first being for some reason the Master is transmitting "AH" instead of just "A" I dont know why this is happening but that is not important right now. The focus of this post in on the receivers side. As we can see a 0 is being received.

If I use
Code:

i = getc();
printf(lcd_putc, "%d ", i);


We get "9 1 72" on the receiver LCD as shown in the second picture, where 9 is the slave_id, 1 is the size of tranmission, and 72 is the ascii value for "H"



To my understanding rs485_get_message is supposed to be able to interpret the incomming data but It has not worked for me so far. Any help would be awesome. Thanks in advance.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 24, 2009 11:43 am     Reply with quote

I made a mistake on that. The enable is handled in the #use rs232()
statement inside rs485.c and it's set by the line in bold:
Quote:

#define RS485_ID 0x01
#define RS485_DEST_ID 0x09
#define RS485_ENABLE_PIN PIN_C5
#define RS485_TX_PIN PIN_C6
#define RS485_RX_PIN PIN_C7
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 24, 2009 1:36 pm     Reply with quote

I just looked at your schematic. I'm not sure why you need the PC
stream at all. You have LCDs for status messages. You don't
use the "PC" stream. You can delete these two lines:
Quote:

#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, stream=PC)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, enable = PIN_C5, stream=PC)



Quote:
void main()
{
set_tris_b(0x00);
set_tris_c(0x80);


You're using Standard i/o mode. (It's the default mode of the compiler,
if no mode is defined). In that mode, the compiler sets the TRIS for you.
The library code sets the TRIS, and the output_high() and output_low()
functions (etc.) set the TRIS. You don't have to do it. I suggest that
you delete both of those lines (in both the Master and Slave code).
arloedx



Joined: 21 Aug 2009
Posts: 15
Location: Texas

View user's profile Send private message

PostPosted: Mon Aug 24, 2009 2:26 pm     Reply with quote

PCM Programmer,

Thank you for responding. I tried your suggestions but that still does not solve the problem. I don't understand if my problem is with the way i'm transmitting, the way the HW is set up, or the way i'm using the rs485_get_message function. Personally I think its rs485_get_message function and I have looked at the examples provided by PICC and implemented the function as shown in the examples but I never receive data properly.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 24, 2009 2:41 pm     Reply with quote

Quote:

while(true)
{
rs485_get_message(msg, FALSE);
printf(lcd_putc, "%d ", msg[1]);
delay_ms(400);
}

I think there is a problem in the way you are calling that routine.
Here is the description of the routine, within the rs485.c file:
Quote:

// Purpose: Get a message from the RS485 bus and store it in a buffer
// Inputs: 1) A pointer to a buffer to store a message
// 2) TRUE - wait for a message
// FALSE - only check if a message is available
// Outputs: TRUE if a message was received
// FALSE if wait is FALSE and no message is available
// Note: Data will be filled in at the pointer as follows:
// FROM_ID DATALENGTH DATA...
int1 rs485_get_message(int* data_ptr, int1 wait)

You're not checking to see if a message was actually received. You're
immediately jumping into printf with the contents of the 2nd byte in the
msg array, regardless of whether a message has been received or not.

I think it would be better to test the return value of the routine, and
only call printf() if it returns 'TRUE'). Example:
Code:

while(true)   
   {
    if(rs485_get_message(msg, FALSE))
       printf(lcd_putc, "%d ", msg[1]);
   }

I didn't look at your transmit code yet. I just looked at your receive code.
arloedx



Joined: 21 Aug 2009
Posts: 15
Location: Texas

View user's profile Send private message

PostPosted: Tue Aug 25, 2009 8:09 am     Reply with quote

Quote:

Code:


while(true)   
   {
    if(rs485_get_message(msg, FALSE))
       printf(lcd_putc, "%d ", msg[1]);
   }




When I try this It would appear I never receive a message. I don't understand why though. Thanks again for any help and future help.
arloedx



Joined: 21 Aug 2009
Posts: 15
Location: Texas

View user's profile Send private message

PostPosted: Tue Aug 25, 2009 9:33 am     Reply with quote

I think i have isolated the problem.

From the RS485.c file I am calling two routines: rs485_init() and rs485_get_message(). When simulating my code I have discovered that it is getting stuck at the part in the rs485_get_message routine where:

Code:

 if(rs485_ni == rs485_no)
      return FALSE;


rs485_ni and rs485_no are both initialized to equal 0 in the rs485_init() routine and are never updated before getting to the get_message function. Is this a flaw in the rs485.c file, am I supposed to modify it or am I missing something? I am sure I am receiving data as I can see it on an oscilloscope. Please help. Thanks.
shashank27187



Joined: 28 Jul 2009
Posts: 13

View user's profile Send private message

PostPosted: Tue Sep 01, 2009 3:55 am     Reply with quote

As said above to check whether data is received or not using the code:
Code:

while(true)   
   {
    if(rs485_get_message(msg, FALSE))
       printf(lcd_putc, "%d ", msg[1]);
   }


I wish to say that I have tried this thing out and made a change in the program. Actually it is like this:
Code:

void main(){

rs485_init();
rs485_no=1;    /// change made as per the definition in driver file to update the value
lcd_init();
output_low(LCD_RW);

output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);

while(1){
  lcd_putc('\f');
  printf(lcd_putc, "abv gt msg");
  delay_ms(500);
   //
             
  if(rs485_get_message(data, FALSE))
   {
     lcd_putc('\f');
     printf(lcd_putc, "a=%d ", data[0]);
     delay_ms(1000);

I found that the slave node receives something. It prints the value of "a"
which should be data[0] but the value printed does not equals the value sent.

My sample code is here:
http://www.ccsinfo.com/forum/viewtopic.php?t=40022&highlight=rs485

When I am sending a data of length say 3 then I receive the data but what is displayed in LCD is not what is being sent.... some numerical garbage.

Any help will be appreciated....Thanx...
duongnc



Joined: 30 Nov 2010
Posts: 1

View user's profile Send private message

cs stand for checksum
PostPosted: Tue Nov 30, 2010 9:15 pm     Reply with quote

The problem you face is the check sum byte of the Protocol. You can look down into rs485_send_message function
Code:
      for(i=0, cs=rs485_id^to^len; i<len; ++i) {
         cs ^= *data;
         fputc(*data, RS485_CD);
         ++data;
      }


cs stand for checksum and it is 1 byte.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Aug 18, 2014 4:01 pm     Reply with quote

Dear All,

tried the code listed above, and during debugging, it is clear that the micro is looping in the:

Code:
rs485_wait_for_bus(TRUE);


the receiver is showing "0 0 0 0 0"

I tried the same code to have an easy starting. On the transmitter side, the LCD is displaying nothing. The code I am using is:

Code:
#include <18f252.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use    delay(clock=20000000)

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B1
#define LCD_ENABLE_PIN  PIN_B2
#define LCD_DATA0       PIN_B4
#define LCD_DATA1       PIN_B5
#define LCD_DATA2       PIN_B6
#define LCD_DATA3       PIN_B7   

#include <lcd.c>

#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT FALSE

#define  RS485_ID             0x01
#define  RS485_DEST_ID        0x09
#define RS485_ENABLE_PIN      PIN_C2
#define RS485_TX_PIN       PIN_C6
#define RS485_RX_PIN       PIN_C7

#include <rs485.c>
#include <stdlib.h>

void LCD_CHECK();

void LCD_CHECK()
{
   lcd_gotoxy(1,1);
   printf(lcd_putc, "System Ready");
   delay_ms(500);
   printf(lcd_putc,"\f");
}
int8 size=1;
int i, max = 5 ;
int8 bufsend[5] = {'A','B','C','D','E'};
int *pointer;

void main()
{
     

   rs485_init();

   lcd_init();
   LCD_CHECK();
   while(true)
      {
      for(i=0; i<max; i++)
      {
         pointer = &bufsend[i];
         rs485_wait_for_bus(TRUE);     
         rs485_send_message(RS485_DEST_ID, size, pointer);       
         printf(lcd_putc,"\fSent: %c", bufsend[i]);
         delay_ms(1000);
      }
      delay_ms(1000); 
   }
}


and receiver side:

Code:
#include <18f252.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use    delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, enable = PIN_C5, stream=PC)

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B1
#define LCD_ENABLE_PIN  PIN_B2
#define LCD_DATA0       PIN_B4
#define LCD_DATA1       PIN_B5
#define LCD_DATA2       PIN_B6
#define LCD_DATA3       PIN_B7   

#include <lcd.c>

#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT FALSE
#define  RS485_ID             0x09

#define RS485_ENABLE_PIN      PIN_C2
#define RS485_TX_PIN       PIN_C6
#define RS485_RX_PIN       PIN_C7

#include <rs485.c>
#include <stdlib.h>

void LCD_CHECK();

int8 msg[32];

void main()
{
   output_low(RS485_ENABLE_PIN); 
   rs485_init();
   rs485_no=1;
   lcd_init();
   LCD_CHECK();

   while(true)   
   {
//!      if(rs485_get_message(msg, FALSE));
//!      printf(lcd_putc, "%d ", msg[1]);
//!                delay_ms(400);
   }
}

void LCD_CHECK()
{
   lcd_gotoxy(1,1);
   printf(lcd_putc, "System Ready");
   delay_ms(500);
   printf(lcd_putc,"\f");
}


the setup I am using is here:

http://postimg.org/image/8z1fcokwj/
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 18, 2014 4:14 pm     Reply with quote

Are you using real PICs wired as in the schematic then it can't work!
Several errors in configureation...

Also always add 'errors' to USE RS232(...options...) when using the hardware UART peripheral...This is mandatory...

jay
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Tue Aug 19, 2014 2:24 am     Reply with quote

I just ordered the parts and will be delivered next week. I am making a simulation to finish the program and when the parts arrive , i built the circuit immediately. But during debugging i noticed that the master is looping in the wait_bus function. When i disable it, thr master starts to send the mesages and display on the lcd. Is there so,ething wrong in the circuit?
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