|
|
View previous topic :: View next topic |
Author |
Message |
cheehow
Joined: 15 Sep 2010 Posts: 28
|
PIC to PIC communication through RS485 |
Posted: Thu Nov 11, 2010 8:59 am |
|
|
Hi, guys. Im having a project which is about communication between 1 master to multiple slave. But for now, I just only testing on 1 master with 1 slave, and it fails. In my coding, I using 1 push button to send a signal to master, then the master will light up an LED for 1sec. Then, the master will send the signal to the slave and an LED light up for 1sec in the slave. Then, the slave will send back the signal to the master and the master's LED will light up again. Below is my code:
Master:
Code: |
#include <16F877A.h>
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock = 20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PIC)
#define RS485_ID 0x11
#define RS485_USE_EXT_INT TRUE
#include <RS485.c>
int buffer[40];
int next_in = 0;
int next_out = 0;
#INT_RDA
void serial_isr()
{
int t;
buffer[next_in] = fgetc(RS485);
t = next_in;
next_in = (next_in+1) % sizeof(buffer);
if(next_in == next_out)
next_in=t; // Buffer full !!
}
void main()
{
int data_received[32];
int j;
rs485_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(True)
{
rs485_wait_for_bus(FALSE);
if (input(pin_b1))
{
rs485_send_message(0x12, 1, 3);
output_high(PIN_d7);
delay_ms(1000);
output_low(PIN_d7);
}
if(rs485_get_message(data_received, FALSE))
{
for(j=0; j<3; ++j)
data_received[j] = buffer[j];
if(data_received[2]==6)
{
output_high(PIN_d6);
delay_ms(1000);
output_low(PIN_d6);
}
}
}
} |
Slave:
Code: |
#include <16F877A.h>
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock = 20000000)
#define RS485_ID 0x12
#define RS485_USE_EXT_INT TRUE
#include <RS485.c>
int buffer[40];
int next_in = 0;
int next_out = 0;
#INT_RDA
void serial_isr()
{
int t;
buffer[next_in] = fgetc(RS485);
t = next_in;
next_in = (next_in+1) % sizeof(buffer);
if(next_in == next_out)
next_in=t; // Buffer full !!
}
void main()
{
int j;
int data_received[32];
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
rs485_init();
do
{
if(rs485_get_message(data_received, TRUE))
{
for(j=0; j<3; ++j)
data_received[j] = buffer[j];
if(data_received[0] == 0x11)
{
output_high(PIN_d4);
delay_ms(1000);
output_low(PIN_d4);
}
}
rs485_wait_for_bus(FALSE);
if(rs485_send_message(0x11, 1, 6))
{
output_high(PIN_d5);
delay_ms(1000);
output_low(PIN_d5);
}
}
while(true);
} |
I really need this help, your help is much appreciated,thanks. |
|
|
cheehow
Joined: 15 Sep 2010 Posts: 28
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Nov 11, 2010 10:46 am |
|
|
The RS485 code, already includes the functions to receive data.
You have specified 'USE_EXT_INT', which tells the RS485 code to use the external interrupt, but you have the RS485 wired to the hardware serial UART, and therefore using the RDA interrupt....
You need to either get rid of the RS485 code, and 'write your own' using your own transmit/receive functions, or use the RS485 ones. Get rid of your int_rda, and the USE_EXT_INT lines.
Look at EX_RS485.c, Understand that in this, the RS485, is wired with the incoming line on the B0 interrupt (hence 'USE_EXT_INT' is set), and the PC is talking to the chips via the hardware UART, and hence the code to handle INT_RDA for the PC communications.....
Best Wishes |
|
|
cheehow
Joined: 15 Sep 2010 Posts: 28
|
|
Posted: Sat Nov 13, 2010 11:07 am |
|
|
but my connection is MCU (master) to Multiple MCU (slave), is it still using #use rs232 (baud=9600, xmit=PIN_B2, rcv=PIN_B1, stream=PIC)??? and the "stream", can i just change it to PIC instead of PC ... because the example there given is " Stream=PC". Please give me some guide of this part ... i'm quite confuse...... thxs ...
Regards
Cheehow |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Nov 13, 2010 2:19 pm |
|
|
Your software is not right for the hardware.
Your hardware does NOT have any RS-485 interface chips, rather they are direct connected, so you do not need the 485 files.
I haven't looked at the 485.c files to see how they handle xmt/rcv but doubt they will work as the scematic shows.
You could just use the regular rs232 commands with the invert option though.
Also your pushbutton doesn't seem to have any filtering(hard or soft) for debounce which may cause you no end of grief.... |
|
|
cheehow
Joined: 15 Sep 2010 Posts: 28
|
|
Posted: Sun Nov 14, 2010 7:23 am |
|
|
but i need to indicate each MCU addresses because each MCU's have their own address, so that master jz can send data to the particular MCU...however, for rs232, it can't assign the MCU addresses., so i jz use rs485. is it got any other way to recognise the address of MCU .. ?? because RS485 got "define RS485_ID 0x11" to recognise the addresses of each MCU.. therefore, i used RS485.. for the hardware part, i jz ned serial communicate with each MCU only .. so i didnt used any RS485 interface chips. Can please give me some guide, because i really do not have any idea to solve this problem. your help is much appreciated.. thxs !!!
Regards
Cheehow |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Nov 14, 2010 9:11 am |
|
|
You have two options..
One...IF you're only using two PICS, do NOT use the RS485 drivers as it is complicated AND requires RS485 interface chips to function properly, like the examples in the compiler files.
It is easy to setup a 'transmission protocol' to include a 'PIC-ID, command' message.
Two..Use the RS485 interface chips and use the appropriate drivers and try the examples in the compiler folders. |
|
|
cheehow
Joined: 15 Sep 2010 Posts: 28
|
|
Posted: Mon Nov 15, 2010 8:36 am |
|
|
What do you mean by using "PIC-ID, command"?? Is it write in this way ? #define PIC-ID 0x11 ?? Or using #define UART_address 0x11 ?? Thanks for helping me .. =) Your help would be appreciated !! Thanks ...
Regards
Cheehow |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Nov 15, 2010 12:16 pm |
|
|
If you're stuck using those RS485 drivers and program, then you MUST use appropriate RS-485 interface chips. The software is designed to operate WITH the correct hardware.
Then, after the hardware has been changed, try the examples that are in the compiler folders. They'll probably work fine, but I do not use those drivers.
If you can't get it to work, then I suggest you 'google' something like RS-485 PIC C code and read a few of the thousands of hits Google will find.
The more you read and experiment yourslef, the better you'll understand how the PIC hardware and C code works.
As I've said before, you do NOT need RS-485 to communicate between 2 or more PICs. If you're developing a network of dozens of PICs, maybe, but there are other options depending on your skill level. One I've used for almost 30 years has 512 remotes with nothing more than transistors and runs over 30Km of wire.
Start small and build upon your failures and sucesses. Be sure to comment every line of code (or function) and make backups ! |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
Re: PIC to PIC communication through RS485 |
Posted: Mon Nov 15, 2010 1:17 pm |
|
|
cheehow wrote: | Hi, guys. Im having a project which is about communication between 1 master to multiple slave. |
Here is an example of a single master/multiple slave protocol. Read it.
http://losdos.dyndns.org/public/pic-uC/cbus-protocol-spec-draft-rev1.pdf
The PIC code at the slave is simply RS232 + an enable; the enable activates the RS485 driver if and only if the slave needs to transmit on the bus.
Reminder -- keep it simple and plan your work. If you don't have a plan for how to make it work BEFORE YOU START CODING, there is no way you are going make it work reliably AFTER you start coding. Spend 80% of your time defining how it should work (see the document above, for example) and the other 20% of your time coding and debugging. This approach will result in a FAR more robust implementation and FAR less aggravation on your end.
jds-pic |
|
|
cheehow
Joined: 15 Sep 2010 Posts: 28
|
|
Posted: Tue Nov 16, 2010 12:00 pm |
|
|
HI jds-pic,
Can you please show me some sample code for initialize the MCU protocol?? After reading through the pdf file that you given to me, I found that I understand the concept but I have a little bit of confusion. For the pins B0 to B7, is it same to all 40 pins MCU ? and how could I start to write the protocol codes for each MCU ?? Use "#define ????" or any way to define these ?? Please show me some example. Your help is much appreciated and thxs for advance reply !!
Regards
Cheehow |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Tue Nov 16, 2010 4:07 pm |
|
|
cheehow wrote: | HI jds-pic,
Can you please show me some sample code for initialize the MCU protocol?? After reading through the pdf file that you given to me, I found that I understand the concept but I have a little bit of confusion. For the pins B0 to B7, is it same to all 40 pins MCU ? and how could I start to write the protocol codes for each MCU ?? Use "#define ????" or any way to define these ?? Please show me some example. Your help is much appreciated and thxs for advance reply !! Regards
Cheehow |
hi cheehow,
It occurs to me after reading your post that you may be a little inexperienced in microcontroller applications, and more specifically in serial communications. That's ok. But you need to understand that to build a complex structure you have to start from the ground up, not from the top down.
The PDF I posted above has no relation whatsoever to pins on a microcontroller (such as a PIC); it simply documents a polling protocol which could be used for pt-to-pt or multidrop applications between a host and one or more slaves. The actual electrical implementation is dependent on the hardware at the ends, as is the associated software.
As an example, you can have a supercomputer with a serial port at the master end, and 8 pin PICs as clients. Or you could have an industrial controller at the master end, and PC's as clients. Either way, the protocol on the line is the same.
Since the suggested protocol is symmetrical (i.e. the same packet structure goes in both directions), the protocol handling code on the master end is structurally the same as the code on the slave ends; only certain changes have to be made as one end is polling and the other ends are waiting to be polled. Now clearly the C/C++ (or VB, or Java, or whatever) code that you write for the PC end is not exactly the same code as you write for the PIC (in CCS C) -- but the section that handles the protocol will be remarkably similar and can in fact be shown to be the same algorithm.
Since you don't have either end operational or even architected at this point, I suggest that you start by purchasing a PIC prototyping board with a serial port (from Sparkfun, etc). With this in hand, you can begin to play around with writing CCS C code for the PIC which handles communications over the serial port to the PC. There are several examples in the CCS directory, and dozens here on the forum, which will assist you in this.
Once you have sent "Hello World!" to the PC (running a terminal program like TeraTerm), and back again, you will be on your way to actually developing your end application. At that point you can get a second PIC development board, and some inexpensive RS232-RS458 converters, and repeat the process with multiple clients. Following, you can work on getting a PC application coded so you can start to periodically poll the client PICs. And finally, you can fully implement your protocol, leaving behind simple-but-limiting ASCII communications.
I suggest this route because if you jump straight into coding up a multi-client communications protocol on two different platforms (PIC and PC), you may soon find yourself frustrated -- nothing will work, and you will not have a foundation to fall back on to debug from.
jds-pic |
|
|
|
|
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
|