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

Serial communication

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



Joined: 25 Sep 2017
Posts: 5
Location: Türkiye

View user's profile Send private message

Serial communication
PostPosted: Mon Sep 25, 2017 8:52 am     Reply with quote

Hi,
I have a problem.
I want to communicate with RS485 with CCS C.
1 master and 2 slaves.
Can you share sample code?
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Mon Sep 25, 2017 9:11 am     Reply with quote

You already have code for this in the examples with the compiler.....

Understand that for anything involving more than one slave there has to be an 'address' involved, and a protocol to handle whatever data you intend to send.
In the examples folder there are examples for ModBus (a common protocol). Change the slave address on the second device.

If you don't want this much complexity, and assuming you only need to send limited mounts of data, then a simpler protocol can be used. However this is totally down to what you need to do. We can't guess this...
A search here will find dozens (hundreds) or threads showing some basic RS485 comms.
Critical things though are:
1) Bus termination and biasing.
2) Biasing on the undriven RX line of the PIC.
3) Designing the protocol to fail safe and handle errors.

Start simple. Get your devices able to switch the buffers, listen to the bus, and transmit.
Emre



Joined: 25 Sep 2017
Posts: 5
Location: Türkiye

View user's profile Send private message

PostPosted: Mon Sep 25, 2017 11:26 pm     Reply with quote

@Ttelmah thank you
But Can you answer these questions?
1.How is addressing done?
2.Where are my mistakes and places where I need to attach?

Master Code

Code:
#include <master.h>
#include <lcd.c>
#include <rs485.c>

//////////////////////////////////////////////////LCD pin connect//////////////////////////////////////////////////////////////

#define LCD_ENABLE PIN        PIN_D0       
#define LCD_RS_PIN            PIN_D1
#define LCD_RW_PIN            PIN_D2
#define LCD_DATA4             PIN_D4
#define LCD_DATA5             PIN_D5
#define LCD_DATA6             PIN_D6
#define LCD_DATA7             PIN_D7

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

/////////////////////////////////////////// RS-485 SETTINGS ////////////////////////////////////////////////////////////////////

#define RS485_USE_EXT_INT_FALSE
#use rs232(baud=9600,xmit=RS485_TX_PIN,rcv=RS485_RX_PIN,enable=RS485_ENABLE_PIN,bits=9,long_data,errors,stream=slave_1)
#use rs232(baud=9600,xmit=RS485_TX_PIN,rcv=RS485_RX_PIN,enable=RS485_ENABLE_PIN,bits=9,long_data,errors,stream=slave_2)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main()
{
   set_tris_b(0x00); output_b(0x00);
   set_tris_c(0x80); output_c(0x00);
   set_tris_d(0x00); output_d(0x00);
   
   lcd_init();                        delay_us(20);
   rs485_init();                      delay_us(20);
   
   while(TRUE)
   {
     printf(lcd_putc,"\f Veri Gonderme");
     delay_ms(500);
     
     output_high(RS485_ENABLE_PIN);
     fprintf(slave_1,"\f Veri1=%s","Elma");  delay_us(20);
     fprintf(slave_2,"\f Veri2=%s","Armut"); delay_us(20);   
   }

}

This is master code.

Now, Slave1 code.

Slave1 Code
Code:

#include <slave_1.h>
#include <lcd.c>
#include <rs485.c>

//////////////////////////////////////////////////LCD pin connect//////////////////////////////////////////////////////////////

#define LCD_ENABLE PIN        PIN_D0       
#define LCD_RS_PIN            PIN_D1
#define LCD_RW_PIN            PIN_D2
#define LCD_DATA4             PIN_D4
#define LCD_DATA5             PIN_D5
#define LCD_DATA6             PIN_D6
#define LCD_DATA7             PIN_D7

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

/////////////////////////////////////////// RS-485 SETTINGS ////////////////////////////////////////////////////////////////////

#define RS485_USE_EXT_INT_FALSE
#use rs232(baud=9600,xmit=RS485_TX_PIN,rcv=RS485_RX_PIN,enable=RS485_ENABLE_PIN,bits=9,long_data,errors,stream=slave_1)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

char x,y;

void main()
{
   set_tris_b(0x00); output_b(0x00);
   set_tris_c(0x80); output_c(0x00);
   set_tris_d(0x00); output_d(0x00);
   
   lcd_init();                        delay_us(20);
   rs485_init();                      delay_us(20);
   
   while(TRUE)
   {
     printf(lcd_putc,"\f Haberlesme");
     delay_ms(500);
     
     output_low(RS485_ENABLE_PIN);
     x=fgets(y,slave_1);
     printf(lcd_putc,"\f Veri Alindi  %s",x);
     delay_ms(500);
   }

}

and finally

Slave2 Code

Code:
#include <slave2.h>
#include <lcd.c>
#include <rs485.c>

//////////////////////////////////////////////////LCD pin connect//////////////////////////////////////////////////////////////

#define LCD_ENABLE PIN        PIN_D0       
#define LCD_RS_PIN            PIN_D1
#define LCD_RW_PIN            PIN_D2
#define LCD_DATA4             PIN_D4
#define LCD_DATA5             PIN_D5
#define LCD_DATA6             PIN_D6
#define LCD_DATA7             PIN_D7

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

/////////////////////////////////////////// RS-485 SETTINGS ////////////////////////////////////////////////////////////////////

#define RS485_USE_EXT_INT_FALSE
#use rs232(baud=9600,xmit=RS485_TX_PIN,rcv=RS485_RX_PIN,enable=RS485_ENABLE_PIN,bits=9,long_data,errors,stream=slave_2)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

char y;

void main()
{
   set_tris_b(0x00); output_b(0x00);
   set_tris_c(0x80); output_c(0x00);
   set_tris_d(0x00); output_d(0x00);
   
   lcd_init();                        delay_us(20);
   rs485_init();                      delay_us(20);
   
   while(TRUE)
   {
     printf(lcd_putc,"\f Communication");
     delay_ms(500);
   
     output_low(RS485_ENABLE_PIN);
     fgets(y,slave_2);
     delay_us(50);
     output_high(RS485_ENABLE_PIN);
     printf(lcd_putc,"\f Veri Alindi \n%c",y);
     
     delay_ms(500);
   }

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 1:35 am     Reply with quote

The rs485.c driver, just gives a basic 'send messages' communication.

You have to setup things for the driver, and telling it what you are going to use as hardware _before_ loading it, and the device addresses you want (RS485_ID).

What chips are you using?.
What do you actually want to send?.
What pins have you connected the RS485 driver chip to?.
(You only actually need one control connection).
What baud rate?.

Assuming hardware UART, the basic wiring on the transceiver chip should be:

Single connection to the DE and /RE pin. Wire these together to one pin on the PIC. (1)

RO pin on the driver with a pull up resistor to the +ve supply (4K7R), to the RX pin of the PIC. (2)

DI pin on the driver to the TX pin of the PIC. (3)

Then +5v and 0v to the driver chip.

A pins on all the drivers connected together via the bus.

B pins of all the drivers connected together via the bus.

Terminator at each end of the bus. At the master end, have a 556R resistor from the 'A' line to +5v, A 133R resistor between A and B, and a 556R resistor from B to 0v. At the other end, a simple 120R resistor.
This ensures 'A' is held above 'B', when the line is undriven.

Then:
Code:

#include <slave_1.h>
#include <lcd.c>

#define RS485_ID 10 //perhaps 10, 11 & 12 for the 3 boards
#define RS485_USE_EXT_INT FALSE
#define RS485_RX_ENABLE //leave blank
#define RS485_ENABLE_PIN PIN_XX //PIN (1)
#define RS485_RX_PIN PIN_YY //PIN (2)
#define RS485_TX_PIN PIN_ZZ //PIN (3)
#include <rs485.c>

//Then get rid of your RS232 setup, and of the fast_io settings
//If you feel you must leave the fast_io, then read your chips data
//sheet, and ensure that the TRIS is set correctly for the UART, and
//to output for the pin used as the enable pin....

void RS485send(char* s, int8 id) //routine to send a string message
{
   int8 size;

   for(size=0; s[size]!='\0'; ++size);
   rs485_wait_for_bus(FALSE);
   while(!rs485_send_message(id, size, s))
      delay_ms(RS485_ID);
   //This ensures the delays are different in different devices
}

//Then assuming this is board 10,
//To send messages to boards 11 & 12
void main(void)
{
   char message[] = "Test Message 1\n";
   char message2[] = "Test Message 2\n";
   delay_ms(100); //almost everything requires a short delay
   lcd_init();
   rs485_init();

   while (TRUE)
   {
       rs485Send(message,11); //send the first string to board 11
       rs485Send(message2,12); //and the second to board 12
       delay_ms(1000);
   }
}


The other devices need similar setups, but then then will call rs485_get_message to see if a message is available.

This is used like:
Code:

    char buffer[64];

    while (TRUE)
    {
       if (rs485_get_message(buffer, FALSE) == TRUE)
       {
           //here a message has arrived and is now in the buffer
           //Do what you want with it

       }
       else
       {
           //You can do whatever else you want when a message is not
           //available
       }
    }


Since you can call 'get_message' with a 'FALSE' as I show, all the devices can do this when they are not sending, in case anything arrives from another unit.
Emre



Joined: 25 Sep 2017
Posts: 5
Location: Türkiye

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 2:00 am     Reply with quote

https://postimg.org/image/kzcapv0yt/


This is the Connection Scheme
is there an error?

Max487 integration?

https://postimg.org/image/d6oe64omd/
Emre



Joined: 25 Sep 2017
Posts: 5
Location: Türkiye

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 2:14 am     Reply with quote

@Ttelmah
If I ask you to write me a program for 1 master 2 slave?
I want to review it.

If it's not a running program, it's not understood.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 2:26 am     Reply with quote

1) Proteus....
Read the 'sticky' at the top of the forum. Proteus is full of bugs on the PIC....

2) You 'bus' between the Max487 chips does not want resistors at each chip, and the value needed is much lower than the 10K you show. A typical bus will have 120ohm impedance wiring, and this needs to be matched at the ends if you are not to get signal problems - this won't cause a problem with Proteus but will in the real world.

3) _Bias_. A RS485 bus needs to be biased off when idle. You are not doing this. There are transceivers that will do this for you and even terminators that do. Or the resistors as I describe. Required.

3) _Bias_. The line from the RO output of the RS485 driver needs to have a pull up resistor to bias it high. This line goes 'undriven' when the chip is transmitting, and leaving it floating, will give indeterminate behaviour.

I've posted a lot of the code for you, showing 90% of a device sending to two other units.
Emre



Joined: 25 Sep 2017
Posts: 5
Location: Türkiye

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 2:44 am     Reply with quote

I'm testing your code

1.
is the first code you sent for master?

2. Is the second send code you want to retrieve data from?For slaves?
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Tue Sep 26, 2017 3:23 am     Reply with quote

The simple driver here, is not master/slave. It's device to device.

The bus sits idle.

Any device can send a 'message' to another numbered device.

It's like a 'field telephone'. You check that nobody else is sending, and then press the button to talk. 'Calling number 10, this is a message for you'. The devices just listen to the bus, and when they hear a message for their number, 'pick up' the message.
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