CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

CANBus ID filtering
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ll.luca



Joined: 18 Jan 2007
Posts: 10
Location: Tuscany

View user's profile Send private message

PostPosted: Thu Jan 25, 2007 10:09 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Jan 25, 2007 3:43 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Feb 01, 2007 2:40 pm     Reply with quote

Thanks for the very fast reply, and sorry if I only wrote now, but I wasn?t at home, Bummed Out

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);
}

Laughing In this case everything is OK Laughing
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


Sad I do not receive Any data!!!Sad

I Hope I'm explaining better then my last post... Embarassed

Best regards and many thanks for you help.

Luca
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Thu Feb 01, 2007 4:13 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 02, 2007 12:15 pm     Reply with quote

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?

Idea What do you think if I transmit two data in a different buffer but through the same ID? Question


Thank you very much

Luca
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Fri Feb 02, 2007 4:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Aug 05, 2007 12:15 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 05, 2007 2:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Aug 05, 2007 6:42 pm     Reply with quote

many thanks, I will try this tommorow when I get a chance.
Guest








PostPosted: Sat Dec 08, 2007 4:17 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Dec 09, 2007 1:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jan 29, 2008 9:09 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 05, 2008 10:29 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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