|
|
View previous topic :: View next topic |
Author |
Message |
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Thu Jan 25, 2007 10:09 am |
|
|
hi
the filter only works with the first transmission.
the TX code is
Code: | while(TRUE)
{
can_putd(0x0074, &ppp, 8, 1, 1, 0); //first transmission
delay_ms(200);
can_putd(0x0222, &ccc, 8, 1, 1, 0); //( second transmission)
delay_ms(600);
}
|
without the filter I'm receiving all perfectly!
Code: | CAN_GETD(): BUFF=0 ID=00000074 LEN=8 OVF=0 FILT=0 RTR=0 EXT=1 INV=0
DATA = 83 2E 8F 5C 84 75 44 A0
CAN_GETD(): BUFF=0 ID=00000222 LEN=8 OVF=0 FILT=0 RTR=0 EXT=1 INV=0
DATA = 84 75 44 A0 22 02 00 00 |
For the first transmitted data
Code: | can_putd(0x0074, &ppp, 8, 1, 1, 0); |
and the filter set for id = 0x0074
all it is perfect
BUT
if I set the filter for 0x0222 simply replacing 0x0222 in in place of 0x0074
on HyperTerminal I' ll receive:
Code: | CAN_GETD(): BUFF=0 ID=0005AA04 LEN=15 OVF=0 FILT=0 RTR=0 EXT=0 INV=0
DATA = 00 00 00 00 00 00 04 AA 05 00 00 00 00 00 0F
# TEST OK =>: 0.00 |
- the data is obviously not correct
- the id is random and nothing transmits with this id!
what is the mistake?
many, many thanks
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Thu Jan 25, 2007 3:43 pm |
|
|
Hi,
I'm assuming you've got two chips talking to each other, the code above is split between the two, one sending one receiving. It would be helpful to explain which chip the code is on. I'm only so telepathic!
Are you using can_kbhit()? see my last post. This function returns true if a message with a valid (passed filtration) ID has been received. The code above looks like you've not checked and are just reading whatever values are in the buffer without checking that they've been set.
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Thu Feb 01, 2007 2:40 pm |
|
|
Thanks for the very fast reply, and sorry if I only wrote now, but I wasn?t at home,
It isn't easy to explain for me what is happened with the code you suggested.
I'm trying to do my best to clarify it:
I have a couple of pic in typical configuration 18f458 and a MCP2551 runs at 20Mhz
The first just transmits two data with different Id
Code: | //cut
import_data (ppp, ccc); //function generate 2 data
can_init();
do {
can_putd(0x0222, &ppp, 8, 1, 1, 0);
delay_ms(400);
can_putd(0x0074, &ccc, 8, 1, 1, 0);
delay_ms(600);
} while (TRUE);
} |
The second receives the data with the filter you gave me.
Code: | //cut
void set_my_can_filters(void) {
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0x0222, 1); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x0222, 1); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0x0222, 1); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x0222, 1); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x0222, 1); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x0222, 1); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
}
void main() {
struct rx_stat rxstat;
int32 rx_id;
float dato_filtrato;
int rx_len;
can_init();
set_my_can_filters();
do {
if(can_kbhit()) {
can_getd(rx_id, &dato_filtrato, rx_len, rxstat);
Printf(? TEST OK =>: %3.2f\r\n ",dato_filtrato);
delay_ms(800);
}
} while(TRUE);
} |
In this case everything is OK
But if I transmit the data with id inverted :
At first time 0x0074 and the second time 0x0222 I mean:
Code: | //cut
can_putd(0x0074, &ppp, 8, 1, 1, 0);
delay_ms(400);
can_putd(0x0222, &ccc, 8, 1, 1, 0);
//cut |
I do not receive Any data!!!
I Hope I'm explaining better then my last post...
Best regards and many thanks for you help.
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Thu Feb 01, 2007 4:13 pm |
|
|
Hi,
You use the a pointer to the variable "float dato_filtrato" to return the data back to your main routine, float is 32bits (4 bytes) and the data structure being written is 64 bits (8 bytes). Therefore whatever variables the compiler has listed after the 32 for "dato_filtrato" will be overwritten. Therebye corrupting your data, anything could happen including freezing of the PIC. This is most likely your problem. I can't see the type of data used for sending but I'd make sure that this is also 64 bytes. (The two separate Rx compiles may put variables in different locations therefore one gets away with writing 64bits, the other may not!)
I'd also suggest puting a few LEDs on your circuit board, one as a heart beat so you know the PIC is still running, and a second to mark communication status GOOD/BAD. On the transmition PIC, you switch on when data is succesfully placed on the TX buffer, and turn it off should it fail. Have a look at the example code. Before using the can_putd routine they perform a test "can_is_one_of_the_TX_buffers_empty" (sorry have no idea what the function is called, not at my PC!). Use that routine to see if messages are being transmited. You can use similar thing for Rx, this will point you better than I can at you specific issue.
There is no need for the delay_ms(800) in the recieve routine, small point, this will not be causing your problems.
When you say everything works fine I'm assuming you receive data every second?
Just out of interest, what made you decide to use extended IDs?
Do you have a 3rd party piece of CAN equipment which you can comminicat with? This is a very useful test.
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Fri Feb 02, 2007 12:15 pm |
|
|
Hi
As you suggested I changed the float dato_filtrato to int16 but the problem remains..
About Quote: | can_is_one_of_the_TX_buffers_empty | Do you mean: can_tbe()?
reducing or Deleting the delay_ms apparently doesn�t change the result.
Quote: | When you say everything works fine I'm assuming you receive data every second? | Yes correct.
Quote: | just out of interest, what made you decide to use extended IDs? | No particular reason just to test it.
Quote: | Do you have a 3rd party piece of CAN equipment which you can comminicat with? This is a very useful test. | No but have you some link about?
What do you think if I transmit two data in a different buffer but through the same ID?
Thank you very much
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Feb 02, 2007 4:30 pm |
|
|
Hi,
Unfortunately, changing dato_filtrato int16 has moved you're problem in the wrong direction, you need a 64 bit memory space.
Personally I'd just use the "int in_data[8]" variable and set integer values in the array, especially for you're early testing. But if you wanted to use float then you'd need to use something like this, both on the Tx and Rx...
Code: |
int in_data[8];
float *dato_filtrato;
dato_filtrato = in_data;
*dato_filtrato = 3.5;
if( can_kbhit()){
can_getd(rx_id, &in_data[0], rx_len, rxstat);
Printf(� TEST OK =>: %3.2f\r\n ",dato_filtrato); // not 3.5!
}
|
Yes I mean can_tbe()
I'd suggest using standard IDs, purely because it's quicker, and more devices use it, but it's up to you.
We (my work) use these, http://www.kvaser.com/, use the products links and have a look at the USB leafs.
Quote: | What do you think if I transmit two data in a different buffer but through the same ID? |
You can multiplex can messages but I'd not advise it. The best way to think of CAN as global memory and each ID is an address, the various node either put data into an address while others can read it. Until you've got the messaging sorted, I'd leave this sort of additional complexity til later.
Cheers Scott |
|
|
ratgod
Joined: 27 Jan 2006 Posts: 69 Location: Manchester, England
|
|
Posted: Sun Aug 05, 2007 12:15 am |
|
|
I'm a little confused with the filtering, I have played with CAN based on the examples but I made my own filtering system that only listens to messages with the devices ID on it (and a broadcast ID). It was a system thrown together for the company I work for.
How exactly would I gain the same effect using the can_set_id commands?
I used extended ID's btw.
It is set up like so:
Code: |
#define my_id 0x11 // my ID
int1 tx_rtr=0; // was 1
int1 tx_ext=1; // was 0
int tx_len=8;
int tx_pri=3;
byte outdata[8];
int rx_len;
int i; |
I also have can_init() in the main function before I go into the main loop.
then when in the main() loop I poll the can_kbhit() check the ID attached to it and only accept if it matches my_id or broadcast (0xFF)
Say, one unit is id 0x11 and broadcast is 0xFF, I want unit 0x12 to send a message with the ID of 0x13. how would I counfigure the code below to ignore any message that is not addressed to ID 0x11 or 0xFF?
Code: |
can_set_id(RX0MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0x0074, 1); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x0074, 1); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0x0074, 1); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x0074, 1); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x0074, 1); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x0074, 1); //set filter 3 of mask 1 |
note: this code was taken from the other page of this thread.
also, would can_kbhit() and the can interupts ignore the non-addressed packets?
many thanks |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Sun Aug 05, 2007 2:04 pm |
|
|
Code: |
can_set_id(RX0MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0x0011, 1); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x00FF, 1); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0x00FF, 1); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x00FF, 1); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x00FF, 1); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x00FF, 1); //set filter 3 of mask 1
|
The above code should set the chip up to recieve only the two IDs of interest. Have a look at a mistake I was making in this http://www.ccsinfo.com/forum/viewtopic.php?t=30984 thread if you want a little more insight. |
|
|
ratgod
Joined: 27 Jan 2006 Posts: 69 Location: Manchester, England
|
|
Posted: Sun Aug 05, 2007 6:42 pm |
|
|
many thanks, I will try this tommorow when I get a chance. |
|
|
Guest
|
|
Posted: Sat Dec 08, 2007 4:17 pm |
|
|
ferrumvir: you mentioned you made a mistake, and it was the parameters list thing, did this allow you to filter different rxID's when you fixed it?
Code: | void can_filt( int16 rxid1,rxid2,rxid3,rxid4,rxid5,rxid6 )
{
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, 0x07FF, 0); //set mask 0 // MATCH MASK 100%
can_set_id(RX0FILTER0, rxid1, 0); //set filter 0 of mask 0
can_set_id(RX0FILTER1, rxid2, 0); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x07FF, 0); //set mask 1 // MATCH MASK 100%
can_set_id(RX1FILTER2, rxid3, 0); //set filter 0 of mask 1
can_set_id(RX1FILTER3, rxid4, 0); //set filter 1 of mask 1
can_set_id(RX1FILTER4, rxid5, 0); //set filter 2 of mask 1
can_set_id(RX1FILTER5, rxid6, 0); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
} |
this is your code from the linked thread, did it work when you changed the parameter list? also, does this allow you to select which rxID's to listen to?
thanks |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Sun Dec 09, 2007 1:36 pm |
|
|
Once the parameter list for the function call was fixed, i.e. declaring each int16 the routine worked fine.
All the rxids come in to the can_kbhit or the interupts, you need to parse out which ID is being handled and handle it accordingly.
Hope that helps.
Cheers Scott |
|
|
ratgod
Joined: 27 Jan 2006 Posts: 69 Location: Manchester, England
|
|
Posted: Tue Jan 29, 2008 9:09 pm |
|
|
I got my code working in the end,
I set the RX0 filters to 0x0011 (which is the boards ID) and the RX1 filters to 0x00FF (which is the broadcast ID) and using the separate RX0 and RX1 interrupts I have a separate interrupt for a direct addressed packet and broadcast packet.
on a side note, do you know if I can change the filters or even the speed of the CAN at run-time? I am designing a new system with a faster rate CAN and I want to be able to be able to use my CAN-RS232 module with both systems and select the speed via my PC software?
many thanks
Peter |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Tue Feb 05, 2008 10:29 am |
|
|
Hi RatGod,
Yes you can reconfigure the speed at run time though you have to take the bus off line, use the can_set_mode function to take the bus off and on line and set the speed inbetween. Sorry I've not got access to my code so I can't tell you what the speed related registry settings are. Have a look in the example can_init() function.
Code: |
can_set_mode(CAN_OP_CONFIG);
// SET SPEED HERE
can_set_mode(CAN_OP_NORMAL);
|
Cheers Scott |
|
|
|
|
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
|