View previous topic :: View next topic |
Author |
Message |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
Problem with MCP2515 CAN bus |
Posted: Tue Feb 14, 2017 10:30 am |
|
|
Greetings! I'm using can-mcp251x library to drive MCP2515. I want to set different ID to every node on the line, so it receives only the data sent to its ID. I tried to use different can_id values -> no result!
How can I achieve this?
Thanks! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Feb 14, 2017 10:44 am |
|
|
I've never used that IC (only PICs with built-in CAN). That said,
- are you setting the mask and filter of each node to respond to a specific ID only?
- are you properly setting the speed of each node? Have you consulted the microchip CAN bit timing generator?
- are you setting the sending node to match what the receiving node is expecting (not just ID but also standard or extended ID)?
- what happens if you set your receiving node to capture all incoming messages? Do you receive anything?
- is your node wiring set up properly (no crossed lines)?
- do you have your 120R termination resistors in your bus?
- is it possible to set a node for "loopback" mode? If so, can you see what you try to send echoed back? |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Tue Feb 14, 2017 11:08 am |
|
|
I have 2 nodes on the line working properly. I have terminator resistor. The hardware is ok. For oscillator settings I`m using the default setting in the library for both nodes.
I`ve notice the can_set_id() in the can_init() function sets all mask and filter registers to 0.
Can you give me more info here? Which one is for income data and which for outcome? They are both called RX...
Thanks! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Feb 14, 2017 11:24 am |
|
|
There are only receive (RX) filters and masks. Sending a message doesn't require any special setup to filters or masks or anything like that - you just load the data you want to send and then send it.
This is from my standard CAN header file, just before I set my filters and masks. It helps me to set everything properly.
Code: | // mask bit n | filter bit n | message ID bit n | result
// 0 x x accept
// 1 0 0 accept
// 1 0 1 reject
// 1 1 0 reject
// 1 1 1 accept |
Since everything is defaulting to 0's, it's defaulting to ACCEPT_ALL. You should be receiving every message you send.
Can you check the contents of the CAN error register? If you have any sort of issue (hardware, speed mismatch, etc), you're going to get CAN errors. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Feb 14, 2017 12:04 pm |
|
|
One other thing I just thought of regarding CAN errors. In a CAN network, a message is only considered successfully sent/transmitted if the sending node gets an ACK during transmission. During the time the sender is transmitting the message is a dedicated ACK time. Any and all listeners on the bus must ACK the message even if it's not intended for that node. If the transmitting node does not see an ACK during the transmission of the message, the message is considered failed and it is re-sent automatically. This process can repeat forever if there are no listeners and it appears as though the bus is "hung".
You should be able to test for/see if the transmitting node has successfully sent the message. |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Tue Feb 14, 2017 12:43 pm |
|
|
OK! I don`t have any errors!
I want to know how to send data to specific node? Can I use these RX masks and filters or I have to use a software approach(adding extra data with address)?
For example can I set my masks to a value(receiver`s address) and receiving only data sent to this address?! How can I specify the output address?!
I don`t understand the function of these mask and filter registers! Are they filtering every bite of received data or just the ID?
Thanks! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Feb 14, 2017 12:57 pm |
|
|
The mask and filter apply only to the message ID. Only the message ID is masked/filtered.
To send a message, you just load the transmit buffers with your data and the ID of the message that you're setting. Look at can_putd() function in the drivers (the drivers for the processors with CAN built-in; I don't know if CCS named their send function the same for that chip).
Nothing special has to be done to send a message - you just send it. No filters or masks need to be set. That's assuming, of course, that you set up the MCP2515 properly in the first place. In the same place that you set up the receive masks & filters, you also have to set up the transmit properly. All you're really doing is dedicating a set of registers to the transmit functionality. That will definitely be in the examples for that chip. |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Tue Feb 14, 2017 1:09 pm |
|
|
So I just have to change the 2 masks and filters so the nodes can filter income data?
What`s the difference between the 2 masks - once has 2 filters the other 4?
I can set 2 income address? The income data attempts to pass first through the first and if it can`t tried through the second? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Feb 14, 2017 1:35 pm |
|
|
It's just the way it is; one set has 2 filters and the other has 4. Of all the filter combinations, one has to be set aside for transmission. That transceiver has 6 sets of registers and those registers can generally be dedicated as either for transmission or reception. It's up to you to set them up properly.
Regarding scanning for multiple IDs, you generally try to set up one combination of masks and filters for IDs that are relatively close to each other and the other can be for combinations that are generally quite different. Just keep in mind the rules I posted regarding masks and filters because quite often you'll find that you can't arrive at a perfect combination of mask and filter that only respond to the messages you actually want. There'll often be extra messages that get through the hardware filters as well that you'll have to filter in software. |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Wed Feb 15, 2017 1:11 am |
|
|
OK! I'm doing something wrong.
I set both masks to 0xFFFFFF and all filters to 0x000032. The sender is transmitting data with 0x00000A address. In this case the receiver still receives the data...
The filters are different from the sent package ID...
Any suggestions? |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Feb 15, 2017 3:13 am |
|
|
Unless you are worried about how much time CAN handling is taking in firmware there's not much point in doing filtering in the CAN hardware. Intead, simply accept all and only respond to the IDs you want to in firmware, ignoring any messages you aren't interested in. That's how I run most of my CAN messaging code.
Even if you filter in the hardware, all CAN nodes will acknowledge all CAN messages, regardless of ID. There is no way of knowing that a message has been received by a particular receiver. To do that you have to have the node send back some kind of response message. There isn't even any way of knowing when a message has actually been sent. You know when you put it in the CAN peripheral's buffer, but you cannot tell when it sent it.
While you can run CAN this way, treating the ID as an address, it is not the way in which CAN was intended to be used. The ID was intended as a message identity, not a destination address. It identifies the content of the message, i.e. what kind of message it is, not where it goes. IDs often are also used to identify where a message came from rather than where it's going to. This is needed because all CAN messages must have unique IDs to allow the clash detection and arbitration to work. So there has to be some way to distinguish between two or more nodes that generate the same type of message.
CAN is broadcast, all messages go to all nodes, and all nodes acknowledge all messages. The ID allows nodes to listen to messages it want to hear, and ignore those it's not interested in. A message is received by all other nodes, and can be listened to, or not, as required. This is much more flexible than a simple point to point connection.
So, yes, you can use the ID as an address, and you can filter in hardware, but it is not the best way of using CAN. In many cases, unless the IDs have been carefully selected to be easily filtered, it is often simpler to accept all in hardware and filter in software. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Wed Feb 15, 2017 7:09 am |
|
|
stoyanoff wrote: | OK! I'm doing something wrong.
I set both masks to 0xFFFFFF and all filters to 0x000032. The sender is transmitting data with 0x00000A address. In this case the receiver still receives the data...
The filters are different from the sent package ID...
Any suggestions? |
Code: | // mask bit n | filter bit n | message ID bit n | result
// 0 x x accept
// 1 0 0 accept
// 1 0 1 reject
// 1 1 0 reject
// 1 1 1 accept |
Mask: 0xffffff
Filter: 0x000032
Message ID: 0x00000a
You have an issue and I'm going to let you figure it out. |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Fri Feb 17, 2017 12:01 pm |
|
|
Ok! Thanks!
I just did a software filter. I can try to set the masks and filters again! |
|
|
|