|
|
View previous topic :: View next topic |
Author |
Message |
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
[CANbus] communication between two nodes with PIC18F2580 |
Posted: Fri Aug 29, 2008 2:04 am |
|
|
I need some hardware and software tips on making two nodes (pic18f2580 + mcp2551) communicate via canbus at 500 kbaud.
Is there anyone who tried to do this?
I will post my HW and SW setup soon...
Thank you |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 29, 2008 11:09 am |
|
|
In the middle of this thread, there is a test program for two PIC
boards, with a CAN bus connection on each board. This code tests
if two PIC boards can talk to each other via the CAN bus.
http://www.ccsinfo.com/forum/viewtopic.php?t=29627 |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Sun Aug 31, 2008 7:40 am |
|
|
x PCM programmer: I will try the example code you link, thanks.
-------------------------------------------------------
In the meanwhile, I will post my hw and sw setup.
This is my hardware setup:
And, this is my software setup:
NODE A (board 1: it transmits to NODE B)
Code: | /*
* NODE_1
*/
#include <18F2580.h>
#fuses NOWDT, INTRC, NOPUT, NOPROTECT
#use delay (clock=8M) // oscillator frequency for delay_ms(). Manually edit variable Tq in the main() to display the correct can bit rate
#include <can-18F4580_mod.c>
// redefinitions
#define CAN_BRG_PRESCALAR 0 //custom bit rate
#define CAN_ENABLE_DRIVE_HIGH 0
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B6)
#include <INPUT.C>
void main()
{
//recv message
struct rx_stat rxstat;
int32 rx_id;
int in_data[8];
int rx_len;
//send message
int out_data[8];
int32 tx_id;
int1 tx_rtr=0;
int1 tx_ext=1;
int tx_len;
int tx_pri=3;
int i;
float Tq = ( 2.0 * (CAN_BRG_PRESCALAR+1) ) / 8.0; // microsec
int Tq_num = 1 + (CAN_BRG_PROPAGATION_TIME+1) + (CAN_BRG_PHASE_SEGMENT_1+1) + (CAN_BRG_PHASE_SEGMENT_2+1);
puts("===========================================");
puts(" Comunication Test with a CAN message ");
puts(" from NODE_1 to NODE_2 and back to NODE_1 ");
puts("===========================================");
puts(" ");
can_init();
//can_set_mode(CAN_OP_NORMAL);
printf("Operating Mode.........%d (0 normal, 1 disable, 2 loopback, 3 listen, 4 config)\n\r",CANCON.reqop);
printf("Messages Received......%d (0 valid, 1 standard, 2 extended, 3 all)\n\r",RXB0CON.rxm);
// display baudrate
printf("Bit rate...............%f kb/s\n\r",(1000/(Tq * Tq_num)) );
puts(" ");
puts("Specify ID and data of the message");
//input data to send to NODE_2
printf("ID: 0x");
tx_id = gethex();
printf("\n\rdata: ");
get_string(out_data, sizeof(out_data), &tx_len);
while (TRUE)
{
// send message
if ( can_tbe())
{
i=can_putd(tx_id, out_data, tx_len,tx_pri,tx_ext,tx_rtr); //put data on transmit buffer
if ( i != 0xFF ) //success, a transmit buffer was open
{
printf("\r\nPUT %U: ID=%X LEN=%U ", i, tx_id, tx_len);
printf("PRI=%U EXT=%U RTR=%U\r\n DATA = ", tx_pri, tx_ext, tx_rtr);
for (i=0;i<tx_len;i++)
{
printf("%X ",out_data[i]);
}
printf("\r\n");
}
else //fail, no transmit buffer was open
{
printf("\r\nFAIL on PUTD\r\n");
}
}
output_bit( PIN_B0, 1 );
delay_ms(500);
output_bit( PIN_B0, 0 );
delay_ms(500);
//receive message
if ( can_kbhit() ) //if data is waiting in buffer...
{
if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) //...then get data from buffer
{
printf("\r\nGOT: BUFF=%U ID=%LU LEN=%U OVF=%U ", rxstat.buffer, rx_id, rx_len, rxstat.err_ovfl);
printf("FILT=%U RTR=%U EXT=%U INV=%U", rxstat.filthit, rxstat.rtr, rxstat.ext, rxstat.inv);
printf("\r\n DATA = ");
for (i=0;i<rx_len;i++)
{
printf("%X ",in_data[i]);
}
printf("\r\n");
}
else
{
printf("\r\nFAIL on GETD\r\n");
}
}
} // repeat forever
} |
NODE B (board 2: it receives from NODE A and reroutes the message as it is to NODE A again to be displayed on the pc screen)
Code: | /*
* NODE_2
*/
#include <18F2580.h>
#fuses NOWDT, INTRC, NOPUT, NOPROTECT
#use delay (clock=8M) // oscillator frequency for delay_ms()
#include <can-18F4580_mod.c>
//redefinitions
#define CAN_BRG_PRESCALAR 0 //custom bit rate
#define CAN_ENABLE_DRIVE_HIGH 0
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B6)
void main()
{
//recv message
struct rx_stat rxstat;
int32 rx_id;
int in_data[8];
int rx_len;
//send message
int out_data[8];
int32 tx_id;
int1 tx_rtr=0;
int1 tx_ext=1;
int tx_len;
int tx_pri=3;
int i;
can_init();
//can_set_mode(CAN_OP_LISTEN);
//printf("Operating Mode.........%d (0 normal, 1 disable, 2 loopback, 3 listen, 4 config)\n\r",CANCON.reqop);
//printf("Messages Received......%d (0 valid, 1 standard, 2 extended, 3 all)\n\r",RXB0CON.rxm);
while (TRUE)
{
// receive message
if ( can_kbhit() )
{
if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) //...then get data from buffer
{
printf("\r\nGOT: BUFF=%U ID=%X LEN=%U OVF=%U ", rxstat.buffer, rx_id, rx_len, rxstat.err_ovfl);
printf("FILT=%U RTR=%U EXT=%U INV=%U", rxstat.filthit, rxstat.rtr, rxstat.ext, rxstat.inv);
printf("\r\n DATA = ");
for ( i = 0; i < rx_len; i++ )
{
printf("%X ",in_data[i]);
}
printf("\r\n");
// send message
if ( can_tbe())
{
i=can_putd(tx_id, out_data, tx_len,tx_pri,tx_ext,tx_rtr); //put data on transmit buffer
if ( i != 0xFF ) //success, a transmit buffer was open
{
printf("\r\nPUT %U: ID=%X LEN=%U ", i, tx_id, tx_len);
printf("PRI=%U EXT=%U RTR=%U\r\n DATA = ", tx_pri, tx_ext, tx_rtr);
for (i=0;i<tx_len;i++)
{
printf("%X ",out_data[i]);
}
printf("\r\n");
}
else //fail, no transmit buffer was open
{
printf("\r\nFAIL on PUTD\r\n");
}
}
}
else
{
printf("\r\nFAIL on GETD\r\n");
}
}
output_bit( PIN_B0, 1 );
delay_ms(500);
output_bit( PIN_B0, 0 );
delay_ms(500);
} // repeat forever
} |
My problem:
When I wonder why it didn’t work, I got a 5 MHz analogue oscilloscope to analyse what was on the CANbus. What I sense with the oscilloscope on both the CANH and CANL line is a constant +2V. That is, both line are get high, but I don’t know the reason.
What’s happening?
Thank you for your help
Ambrogio
P.S. the loopback mode it’s ok on both nodes. The bit rate is set at 250 kbaud for both nodes.
Last edited by ambrojohn on Mon Sep 01, 2008 4:48 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 31, 2008 1:02 pm |
|
|
What was wrong with my code ? Your test code is much longer.
You don't need that much code to test if two boards can communicate
with each other. When you are first trying to get something to work,
smaller is better. |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Sun Aug 31, 2008 3:34 pm |
|
|
You're perfectly right about the length of my code :-P.
Anyway, it is mostly due to print debug lines on the screen and it isn't actually so complex.
Anyway, even with your code, I can't have a can message at the CANbus level (right after the MCP2551). The oscilloscope doesn't reveal any bus activity.
Is my hw setup correct? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 31, 2008 4:18 pm |
|
|
I can't see anything about your hardware setup.
You need to post a schematic or a detailed description of the pin
connections between the PIC and the MCP2551 chips. Also post
a detailed description of the connections between the two boards.
Post if you have the CAN bus termination resistors and their values.
I can't see anything about your setup of the BRGCON registers in the PICs.
I assume you're still trying to get this to work at 500 kbaud. I wouldn't
do that initially. Try a lower (standard) rate, such as 125 kbaud.
Make things work at baseline levels. Then once you've got it working,
you can start to push it. |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Mon Sep 01, 2008 4:51 pm |
|
|
Can't you see the image I link with the schemtic of my hw setup?
I can visualize it from my browser...
I will post the BRGCON register value soon |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 01, 2008 4:54 pm |
|
|
No, it shows as a broken link in either IE or Firefox. It doesn't work.
------
OK. If I right-click on it in Firefox, and select Show Image, now I
can see it. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 01, 2008 5:25 pm |
|
|
When I say to take everything back to a baseline level, I also mean
the oscillator. When I saw that you were using the internal oscillator
on both PICs, with their tolerances of at least +/- 1%, and with a 500
kbaud bit rate, that set off a red flag. I suggest that you use crystals for
the oscillators, and that you reduce the bit rate to 125 kbaud.
For example, this PowerPoint document has some sample calculations
of the required oscillator tolerance for a CAN bus that operates at
1 Mbps and is 25m long. They calculate the frequency tolerance must
be better than 0.65 %.
http://www-ec.njit.edu/~khader/classes/ecet410/Chapter%2013.ppt
So I suggest that, at least initially, you should be using crystals on
your boards. |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Wed Sep 10, 2008 12:19 pm |
|
|
Exams finished (for now).
Ok, I will try with crystal oscillator and a lower bitrate.
I have tried to use crystal yet, but I continue to have both CANH and CANL high at the oscilloscope.
To see my hw setup:
http://ambrojohn.altervista.org/CAN_nodes.PNG |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Wed Sep 10, 2008 6:16 pm |
|
|
Hi
I would like start try using CANBUS on a new project but I never used this protocol...
ambrojohn:
You can post the schematic for communicate with two PICs?
regards |
|
|
Guest
|
|
Posted: Tue Sep 23, 2008 7:28 am |
|
|
Ok,
I've done my test at a baseline setup, with crystal resonator (4MHz) and 125k of baudrate.
The result is always the same, that is no signal on the oscillocope.
I can't figure out what it could be. Something trivial as experience teaches.
I will post a clear sketch of my hw setup (of this single node) and code, hoping someone will help me.
Thank you |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Sun Sep 28, 2008 9:05 am |
|
|
Here is the hardware setup I'm using to make this transmitting node to work.
Copy the subsequent link on your browser address tab:
http://ambrojohn.altervista.org/CAN_node_TX.PNG
The code with which I program the PIC18F2580 is the following:
Code: | #include <18F2580.h>
#fuses NOWDT, HS, NOPUT, NOPROTECT
#use delay (clock=20M) // oscillator frequency for delay_ms(). Manually edit variable Tq in the main() to display the correct
can bit rate
#include <can-18F4580_mod.c>
// redefinitions
#define CAN_BRG_PRESCALAR 4 //custom bit rate
#define CAN_ENABLE_DRIVE_HIGH 0
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_B6)
#include <INPUT.C>
void main()
{
//send message
int out_data[8];
int32 tx_id;
int1 tx_rtr=0;
int1 tx_ext=1;
int tx_len;
int tx_pri=3;
int i;
float Tq = ( 2.0 * (CAN_BRG_PRESCALAR+1) ) / 20.0; // microsec
int Tq_num = 1 + (CAN_BRG_PROPAGATION_TIME+1) + (CAN_BRG_PHASE_SEGMENT_1+1) + (CAN_BRG_PHASE_SEGMENT_2+1);
puts("===========================================");
puts(" Comunication Test with a CAN message ");
puts(" from NODE_1 to NODE_2 and back to NODE_1 ");
puts("===========================================");
puts(" ");
can_init();
//can_set_mode(CAN_OP_NORMAL);
printf("Operating Mode.........%d (0 normal, 1 disable, 2 loopback, 3 listen, 4 config)\n\r",CANCON.reqop);
printf("Messages Received......%d (0 valid, 1 standard, 2 extended, 3 all)\n\r",RXB0CON.rxm);
// display baudrate
printf("Bit rate...............%f kb/s\n\r",(1000/(Tq * Tq_num)) );
puts(" ");
puts("Specify ID and data of the message");
//input data to send to NODE_2
printf("ID: 0x");
tx_id = gethex();
printf("\n\rdata: ");
get_string(out_data, sizeof(out_data), &tx_len);
while (TRUE)
{
// send message
if ( can_tbe())
{
i=can_putd(tx_id, out_data, tx_len,tx_pri,tx_ext,tx_rtr); //put data on transmit buffer
if ( i != 0xFF ) //success, a transmit buffer was open
{
printf("\r\nPUT %U: ID=%X LEN=%U ", i, tx_id, tx_len);
printf("PRI=%U EXT=%U RTR=%U\r\n DATA = ", tx_pri, tx_ext, tx_rtr);
for (i=0;i<tx_len;i++)
{
printf("%X ",out_data[i]);
}
printf("\r\n");
}
else //fail, no transmit buffer was open
{
printf("\r\nFAIL on PUTD\r\n");
}
}
output_bit( PIN_B0, 1 );
delay_ms(500);
output_bit( PIN_B0, 0 );
delay_ms(500);
} // repeat forever
} |
As you see, I have used a 20 MHz crystal resonator with correct 15pF capacitors (from datasheet), because I did not have a 27pF capacitors requested by the 4 MHz crystal.
The CAN registers are the default ones, except for the CAN_BRG_PRESCALAR that is set to 4 to obtain a communication baud rate of 125k.
Here is the output I get on the PC via rs232:
Code: | ===========================================
Comunication Test with a CAN message
from NODE_1 to NODE_2 and back to NODE_1
===========================================
Operating Mode.........0 (0 normal, 1 disable, 2 loopback, 3 listen, 4 config)
Messages Received......3 (0 valid, 1 standard, 2 extended, 3 all)
Bit rate...............125.00 kb/s
Specify ID and data of the message
ID: 0xaa
data: hello
PUT 1: ID=AA LEN=5 PRI=3 EXT=1 RTR=0
DATA = 68 65 6C 6C 6F
PUT 1: ID=AA LEN=5 PRI=3 EXT=1 RTR=0
DATA = 68 65 6C 6C 6F
PUT 1: ID=AA LEN=5 PRI=3 EXT=1 RTR=0
DATA = 68 65 6C 6C 6F |
Now, you have all the elements to evaluate where I'm wrong.
Hoping in some help. Thank you.
Ambrogio |
|
|
Martinez_pt
Joined: 26 Sep 2008 Posts: 11
|
|
Posted: Sun Sep 28, 2008 10:31 pm |
|
|
Hello everyone.
I'm also trying to connect two boards using CANBUS.
Hardware: PIC 18F4580 + MCP2551.
Software: i'm using MPLAB and CCS.
My problem is i can't compile any one of the examples I found. In CCS
I get errors in the header files. In MPLAB I get errors when I make the
include of a *.c" file for example #include <can-18xxx8.c>
Hey ambrojohn, why do you have renamed the file can-18F4580.c to an-18F4580_mod.c ? what modifications have you done ?
Which compiler have you used?
The header file for your pic is p18f2580.h from microchip?
Thanks for you time and for possible help..
Martinez_pt |
|
|
ambrojohn
Joined: 27 Apr 2008 Posts: 18
|
|
Posted: Mon Sep 29, 2008 7:17 am |
|
|
Martinez_pt wrote: |
Hey ambrojohn, why do you have renamed the file can-18F4580.c to an-18F4580_mod.c ? what modifications have you done ? |
Just few modifications during my first trials. Now, can-18F4580.c and can-18F4580_mod.c are the same (you can substitute it with the original can-18F4580.c file)
Quote: |
The header file for your pic is p18f2580.h from microchip?
|
Yes, it is. But it is included in the "devices" installation directory of CCS compiler. If you don't have it, you have an old compiler version. I don't precisely remember the version of my compiler (I don't have it on this pc), but it is greater than 4.0. Check this out! |
|
|
|
|
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
|