CAN or Controller-area Network is a bus standard designed to allow microcontrollers and devices to communicate with each other without a host computer.
This example sends from one CAN bus (can1) an counter while it is listen on the other CAN bus (can2) to receive a packet. Each bus controller should be connected to a CAN bus transceiver. These should be connected together at a CAN bus.
The CAN Interface can be used to write data words out of a CAN port and will return the data received from another CAN device. The CAN clock frequency can be configured.
I'm glad so there is one more CAN in mbed, but you could repair that picture :) http://mbed.org/media/uploads/simon/mbedmicrocontrollerpinout4.png There is drawn only one CAN
The "Details" note says -
The CAN Interface can be used on mbed pins p9/p19 and p30/p29.
but should say
The CAN Interface can be used on mbed pins p9/p10 and p30/p29.
The "Details" note says -
The CAN Interface can be used on mbed pins p9/p19 and p30/p29.
but should say
The CAN Interface can be used on mbed pins p9/p1**__0__** and p30/p29.
In the example, ticker activates Send, and Send has the stack variable "counter" which is initialized to zero on each entry. Am I missing something that the value of counter will always be sent as zero? When successfully sent, the value is incremented, but then the Send function exits, and that value is lost to the stack frame.
In the example, ticker activates Send, and Send has the stack variable "counter" which is initialized to zero on each entry. Am I missing something that the value of counter will always be sent as zero? When successfully sent, the value is incremented, but then the Send function exits, and that value is lost to the stack frame.
But you do not need to know this! This polynome is calculated from the CAN-HW-Controller, and, if the crc is wrong on the transmission of a can frame, the HW will automaticaly repeat the can frame again, to enshure, that it will be transmitted correctly. All this stuf is done by the CAN-HW, and you need not think about it on sw side. This is the benefit from a can controller.
yes, there is a spec for CAN V2.0B:
http://www.hehlhans.de/bilder/autos/cdi270/comand/can2spec.pdf
The polynome is discribed at
Part A - page 13
But you do not need to know this! This polynome is calculated from the CAN-HW-Controller, and, if the crc is wrong on the transmission of a can frame, the HW will automaticaly repeat the can frame again, to enshure, that it will be transmitted correctly. All this stuf is done by the CAN-HW, and you need not think about it on sw side. This is the benefit from a can controller.
Can the CAN API be modified to include another variation of attach, similar to ticker:
template<typename T> void attach_us( T * tptr, void (T::*mptr)(void) )
Attach a function to call whenever a CAN frame received interrupt is generated.
Variables
tptr pointer to the object to call the member function on
mptr pointer to the member function to be called
Can the CAN API be modified to include another variation of attach, similar to ticker:
template<typename T> void attach_us( T * tptr, void (T::*mptr)(void) )
Attach a function to call whenever a CAN frame received interrupt is generated.
Variables
tptr pointer to the object to call the member function on
mptr pointer to the member function to be called
I want to put a CAN frame in a .txt file. When i write can_MsgRx.id in a table,my program compile and run but the mbed is not recognize by my computer.
Do you have any idea ? I'm sorry for my english, i'm french.
Thanks
François
"Hello World"
I want to put a CAN frame in a .txt file. When i write can_MsgRx.id in a table,my program compile and run but the mbed is not recognize by my computer.
Do you have any idea ? I'm sorry for my english, i'm french.
Thanks
François
But you do not need to know this! This polynome is calculated from the CAN-HW-Controller, and, if the crc is wrong on the transmission of a can frame, the HW will automaticaly repeat the can frame again, to enshure, that it will be transmitted correctly. All this stuf is done by the CAN-HW, and you need not think about it on sw side. This is the benefit from a can controller.
I just read up on your reply on changing a CAN CRC, it turns out that the mbed has the CRC hard coded and it can't be modified. The only way is to get an external Controller and communicate to it over SPI.
Lame...
<<quote est2fe>>
yes, there is a spec for CAN V2.0B:
http://www.hehlhans.de/bilder/autos/cdi270/comand/can2spec.pdf
The polynome is discribed at
Part A - page 13
But you do not need to know this! This polynome is calculated from the CAN-HW-Controller, and, if the crc is wrong on the transmission of a can frame, the HW will automaticaly repeat the can frame again, to enshure, that it will be transmitted correctly. All this stuf is done by the CAN-HW, and you need not think about it on sw side. This is the benefit from a can controller.
<</quote>>
I just read up on your reply on changing a CAN CRC, it turns out that the mbed has the CRC hard coded and it can't be modified. The only way is to get an external Controller and communicate to it over SPI.
Lame...
Could someone build, test, and confirm the minimal CAN sample is working for them?
I may have damaged the CAN interface on my mbed, and an independent verification would help. This is confusing, because I can wiggle the CAN pins as DigitalInOut signals, but even simple CAN code fails to communicate successfully.
CAN hardware: I have MCP2551 transceivers wired to each channel, powered by +5v, RS tied low, terminated w/120 ohm, and the CAN pairs tied together (H to H, L to L). This configuration was working for me a while back and verified with a USB to CAN adapter as the 3rd node on a baseboard I designed. I turned to other experiments, and a couple months later I came back to this and cannot seem to get CAN to work - even with the mbed on a protoboard. Quite confusing.
Confusing questions in my mind -
how could I have damaged CAN in the LPC1768, but can still control the IO pins? [seems unlikely]
was there an mbed library update that went backwards?
damaged MCP2551 [possible]
some other blind-spot I'm having... [most likely]
Could someone build, test, and confirm the minimal CAN sample is working for them?
I may have damaged the CAN interface on my mbed, and an independent verification would help. This is confusing, because I can wiggle the CAN pins as [[http://mbed.org/forum/bugs-suggestions/topic/1690/?page=1#comment-12046|DigitalInOut signals]], but even simple CAN code fails to communicate successfully.
CAN hardware: I have MCP2551 transceivers wired to each channel, powered by +5v, RS tied low, terminated w/120 ohm, and the CAN pairs tied together (H to H, L to L). This configuration was working for me a while back and verified with a USB to CAN adapter as the 3rd node on a [[http://mbed.org/users/WiredHome/notebook/Smartboard-baseboard/|baseboard]] I designed. I turned to other experiments, and a couple months later I came back to this and cannot seem to get CAN to work - even with the mbed on a protoboard. Quite confusing.
Confusing questions in my mind -
# how could I have damaged CAN in the LPC1768, but can still control the IO pins? [seems unlikely]
# was there an mbed library update that went backwards?
# damaged MCP2551 [possible]
# some other blind-spot I'm having... [most likely]
Hi David,
From ywhat you said, it seems the problem is in the hardware connections (since you said it was working before)
Also, it is important to know that the CAN tranceiver is eletrostatic device...so it could be possible that your MCP2551 is damaged!
Hi David,
From ywhat you said, it seems the problem is in the hardware connections (since you said it was working before)
Also, it is important to know that the CAN tranceiver is eletrostatic device...so it could be possible that your MCP2551 is damaged!
<<quote WiredHome>>
Could someone build, test, and confirm the minimal CAN sample is working for them?
<</quote>>
Have you seen this page with a minimal setup including transceiver or did you mean that with "confirm the minimal CAN sample" *confused* ? [[http://mbed.org/projects/cookbook/wiki/CanBusExample1]]
Hi Kevin, I was hoping that somebody had the simple configuration of CAN 1 wired to CAN 2 and a serial port to the PC. Then the sample at the top of this page should work and could be confirmed.
This would quickly eliminate possibility #2 from my list of possible failure modes (I numbered them for reference). #3 (damaged CAN transceiver) is the most likely problem, and I'll be pursuing that path later today.
I have never tried looping CAN 1 to CAN 2 w/o a CAN transceiver in the path, but this would then let me plug the mbed into the white proto-block and eliminate my [soldered in] hardware.
Hi Kevin, I was hoping that somebody had the simple configuration of CAN 1 wired to CAN 2 and a serial port to the PC. Then the sample at the top of this page should work and could be confirmed.
This would quickly eliminate possibility #2 from my list of possible failure modes (I numbered them for reference). #3 (damaged CAN transceiver) is the most likely problem, and I'll be pursuing that path later today.
I have never tried looping CAN 1 to CAN 2 w/o a CAN transceiver in the path, but this would then let me plug the mbed into the white proto-block and eliminate my [soldered in] hardware.
edit:
whoops.. dumb c&p without reading the code.. :(
It seems that the message is never received by can2..
if(can2.read(msg))
is never true..
is there any initialization missing? .. i don't see it at the moment..
--I can confirm that the loopback example (top of this page) works.--\\
**see edit below**\\
\\
* Hardware configuration:\\
DIP pin 10 (CAN_TX1) directly wired to DIP pin 30 (CAN_RX2)\\
and\\
DIP pin 9 (CAN_RX1) directly wired to DIP pin 29 (CAN_TX2)\\
(pin-name-source: [[http://mbed.org/media/uploads/mbedofficial/mbed-002.1.pdf|mbed-002.1.pdf, page 2]])\\
\\
* My MBED:\\
mbed [[/handbook/mbed-NXP-LPC2368|NXP LPC2368]]\\
Board rev: mbed-002.2 with Firmware version: 16457\\
\\
* Software:\\
copy&paste of the code above into a new project. (mbed lib@rev28))\\
\\
* Serial line output:
<<code>>
[...]
loop()
loop()
send()
wloop()
Message sent: 38
loop()
loop()
loop()
loop()
loop()
send()
wloop()
Message sent: 39
loop()
[...]
<</code>>
\\
----
**//edit://**\\
whoops.. dumb c&p without reading the code.. :(\\
It seems that the message is never received by can2..
<<code>>
if(can2.read(msg))
<</code>>
is never true..\\
\\
is there any initialization missing? .. i don't see it at the moment..
Hi Kevin, Unfortunately, your test probably isn't valid without the transceivers. CAN will simultaneously receive while it transmits. As you described the wiring, it won't see the network while it transmits. Also, towards the tail end of a packet is a special bit period where other nodes on the network actively "ack" the receipt of the packet. This informs the transmitter that at least one node saw the message. Without these extra elements working as designed, the CAN controller will end up in an error condition. This circuit would work -
CAN Feedback test
If you tried connecting the pairs of RD and TD together, then you would have two output pins fighting each other, so this is not recommended.
Hi Kevin, Unfortunately, your test probably isn't valid without the transceivers. CAN will simultaneously receive while it transmits. As you described the wiring, it won't see the network while it transmits. Also, towards the tail end of a packet is a special bit period where other nodes on the network actively "ack" the receipt of the packet. This informs the transmitter that at least one node saw the message. Without these extra elements working as designed, the CAN controller will end up in an error condition. This circuit would work -
[[http://mbed.org/forum/helloworld/topic/1731/?page=1#comment-8659|CAN Feedback test]]
If you tried connecting the pairs of RD and TD together, then you would have two output pins fighting each other, so this is not recommended.
Hi David, thanks for clarifying. - I should have known that this would not work... embarrassing.
So far I've never tried it without a transceiver and was just curious and did not think much about it..
At the moment i don't have 2 transceivers next to me, sorry.
(If there is anything else i can test, feel free to ask.)
Hi David, thanks for clarifying. - I should have known that this would not work... embarrassing.\\
So far I've never tried it without a transceiver and was just curious and did not think much about it..\\
At the moment i don't have 2 transceivers next to me, sorry.\\
(If there is anything else i can test, feel free to ask.)
Suggestion - can we have a way to set the CAN network frequency in the class's constructor (either another parameter, or in a constructor/initializer)?
I'm worried about initializing a CAN connection on a "live" CAN bus without setting the frequency at the same time - the mbed's CAN controller could possibly start transmitting error frames to other nodes on the network before it hits the frequency() statement, as we currently have to do it.
Thanks!
Suggestion - can we have a way to set the CAN network frequency in the class's constructor (either another parameter, or in a constructor/initializer)?
I'm worried about initializing a CAN connection on a "live" CAN bus without setting the frequency at the same time - the mbed's CAN controller could possibly start transmitting error frames to other nodes on the network before it hits the frequency() statement, as we currently have to do it.
Thanks!
What is the default frequency? how it can be changed?
Hakam,
I measure a default bit time as 10 μs. That would make the default frequency 100 kHz.
<<quote abubaha>>
What is the default frequency? how it can be changed?
<</quote>>
Hakam,
I measure a default bit time as 10 μs. That would make the default frequency 100 kHz.
how can i force my MBED to tx data (from array) to the bus. Always the compiler stops with message that the constructor does not match my code:
void send1000ms ()
{
data_ptr_msg_tx2[7] = 0x80;
build can message from unsigned char data_ptr_msg_tx2[8] = {0,0,0,0,0,0,0,0};
CANMessage can_msg_tx2(0x585, &data_ptr_msg_tx2, 8); system info
can transmission
if (can2.write(can_msg_tx2) == 1)
{
message transmitted
led2 = 1;
}
} end of void send1000ms ()
Hello,
how can i force my MBED to tx data (from array) to the bus. Always the compiler stops with message that the constructor does not match my code:
void send1000ms ()
{
data_ptr_msg_tx2[7] = 0x80;
// build can message from unsigned char data_ptr_msg_tx2[8] = {0,0,0,0,0,0,0,0};
CANMessage can_msg_tx2(0x585, &data_ptr_msg_tx2, 8); // system info
// can transmission
if (can2.write(can_msg_tx2) == 1)
{
// message transmitted
led2 = 1;
}
} // end of void send1000ms ()
Hi Patrick, please use the <<code>> and <</code>> tags to keep source code readable. See Editing tips below.
I think what your tried to do is this:
void send1000ms () {
//define the databytes of the CAN message
unsigned char data_ptr_msg_tx2[8] = {0,0,0,0,0,0,0,0};
// build can message from system info
data_ptr_msg_tx2[7] = 0x80;
CANMessage can_msg_tx2(0x585, &data_ptr_msg_tx2, 8);
// can transmission
if (can2.write(can_msg_tx2) == 1) {
// message transmitted
led2 = 1;
}
} // end of void send1000ms ()
The second parameter should be a pointer to the databytes. You have defined data_ptr_msg_tx2 as an array of 8 bytes. You now need a pointer to the array. That is in fact just the name of the array 'data_ptr_msg_tx2' or a pointer to the first element if that array: &data_ptr_msg_tx2[0].
Hi Patrick, please use the <<code>> and <</code>> tags to keep source code readable. See Editing tips below.
I think what your tried to do is this:
<<code>>
void send1000ms () {
//define the databytes of the CAN message
unsigned char data_ptr_msg_tx2[8] = {0,0,0,0,0,0,0,0};
// build can message from system info
data_ptr_msg_tx2[7] = 0x80;
CANMessage can_msg_tx2(0x585, &data_ptr_msg_tx2, 8);
// can transmission
if (can2.write(can_msg_tx2) == 1) {
// message transmitted
led2 = 1;
}
} // end of void send1000ms ()
<</code>>
The problem is in the constructor for CANMessage:
<<code>>
CANMessage can_msg_tx2(0x585, &data_ptr_msg_tx2, 8);
<</code>>
The second parameter should be a pointer to the databytes. You have defined data_ptr_msg_tx2 as an array of 8 bytes. You now need a pointer to the array. That is in fact just the name of the array 'data_ptr_msg_tx2' or a pointer to the first element if that array: &data_ptr_msg_tx2[0].
So try this:
<<code>>
CANMessage can_msg_tx2(0x585, data_ptr_msg_tx2, 8);
<</code>>
In case anyone is wondering how to convert other datatypes (float, double, etc.) to char arrays in order to transmit through CAN, here's how it's done. Just make sure to match the correct number of bytes for the datatype.
In case anyone is wondering how to convert other datatypes (float, double, etc.) to char arrays in order to transmit through CAN, here's how it's done. Just make sure to match the correct number of bytes for the [[http://www.cplusplus.com/doc/tutorial/variables/|datatype]].
<<code>>
float p = 1.23;
if(can1.write(CANMessage(1337, (char *)&p, 4))) {
printf("Message sent: %f\n\r", p);
}
if(can2.read(msg)) {
printf("Message received: %f\n\r", *((float *)msg.data));
}
<</code>>
Using two transceiver chips, pin 8 tied to ground on both, with a 100 ohm resistor between the two CAN bus lines (H&L), and the frequency set to 500,000 baud, I was able to send every 0.5 ms on both lines and receive (via the "attach" interrupt) on both lines.
Very nice work on the CAN library, thanks.
Using two transceiver chips, pin 8 tied to ground on both, with a 100 ohm resistor between the two CAN bus lines (H&L), and the frequency set to 500,000 baud, I was able to send every 0.5 ms on both lines and receive (via the "attach" interrupt) on both lines.
Very nice work on the CAN library, thanks.
Pull RS high to be silent, whenever you are just reading an existing CAN bus that already has both a Sender and a Receiver (and already has the required 120 ohm terminations).
However, to test Send to Read, CREATING a CAN bus between two transceivers, the RECEIVER must be ACTIVE, to write the final "ack" bit. So, for testing in this way, BOTH transceivers must be active, one to transmit the message, and the other to "send" the "ack" bit. Thus, both RS inputs to the transceiver chips must be "low" (active mode). Terminating this short bus usually requires two 120 ohm resistors, or one 60 ohm resistor, but usually one 100 ohm resistor would work for testing.
Just connecting the TX and RX pins of the Mbed will not work because of this requirement for the Received message to have a valid "ack" bit on the end (that the SENDER does not supply).
Pull RS high to be silent, whenever you are just reading an existing CAN bus that already has both a Sender and a Receiver (and already has the required 120 ohm terminations).
However, to test Send to Read, CREATING a CAN bus between two transceivers, the RECEIVER must be ACTIVE, to write the final "ack" bit. So, for testing in this way, BOTH transceivers must be active, one to transmit the message, and the other to "send" the "ack" bit. Thus, both RS inputs to the transceiver chips must be "low" (active mode). Terminating this short bus usually requires two 120 ohm resistors, or one 60 ohm resistor, but usually one 100 ohm resistor would work for testing.
Just connecting the TX and RX pins of the Mbed will not work because of this requirement for the Received message to have a valid "ack" bit on the end (that the SENDER does not supply).
Presumably a monitor(1) is Silent Mode, to Receive but not generate the "ack" bit.
If the transceiver has RS high (the HARDWARE silent mode) then the software mode would not matter.
In the Send-Receive test mode, once you have it working, setting the RECEIVER to "Silent" should stop it working.
Presumably a monitor(1) is Silent Mode, to Receive but not generate the "ack" bit.
If the transceiver has RS high (the HARDWARE silent mode) then the software mode would not matter.
In the Send-Receive test mode, once you have it working, setting the RECEIVER to "Silent" should stop it working.
Question about the "attach(&myReceiver)" function:
Since a "Message Received" INTERRUPT causes myReceiver subroutine to be run, I assume that the myReceiver subroutine is running at some Interrupt level. What level?
Then, when receiving from TWO CAN buses at the same time, and I "attach" myRecv1 and myRecv1, then these two subroutines will NOT interrupt each other?
THANKS
Question about the "attach(&myReceiver)" function:
Since a "Message Received" INTERRUPT causes myReceiver subroutine to be run, I assume that the myReceiver subroutine is running at some Interrupt level. What level?
Then, when receiving from TWO CAN buses at the same time, and I "attach" myRecv1 and myRecv1, then these two subroutines will NOT interrupt each other?
THANKS
I'm Japanese student and not good at writing English.
When you send a frame at a time, the frame continues to flow indefinitely in the Bus.
I want send a frame few times.
So what can you do for an appropriate response.
I'm Japanese student and not good at writing English.
When you send a frame at a time, the frame continues to flow indefinitely in the Bus.
I want send a frame few times.
So what can you do for an appropriate response.
When you send a Message on the CAN bus, some receiver of that message on the same bus must "write" a final "ack" bit just exactly at the end of the message, or the sender will think that nobody received the message, and might try to re-send the same message.
So, the sender AND the receiver must have their CAN-Transceiver in ACTIVE mode. Then, the sender writes the message, the receiver writes the "ack" bit, the sender reads the "ack" bit, and the Good-Sending is finished.
When you send a Message on the CAN bus, some receiver of that message on the same bus must "write" a final "ack" bit just exactly at the end of the message, or the sender will think that nobody received the message, and might try to re-send the same message.
So, the sender AND the receiver must have their CAN-Transceiver in ACTIVE mode. Then, the sender writes the message, the receiver writes the "ack" bit, the sender reads the "ack" bit, and the Good-Sending is finished.
Hi Renato , there is a nice application board for OBDII and Ecu reader code by Sukkin Pang here
Regards , Christos
http://mbed.org/users/pangsk/code/ecu_reader/
Hi Renato , there is a nice application board for OBDII and Ecu reader code by Sukkin Pang here
Regards , Christos
Please login to post comments.