CAN Receive problems

Hi all,

well the CAN problems keep going on and i really makes me want to give it up… We have got the latest sdk installed (4.1.5). If i take the default tutorial for the CAN bus and just change the T1, T2 and BRP values to the correct ones i hardly ever get any data received events. If i disconnect the remote control (which is the CAN sending device) then i get a bus off error. So the CAN bus detects that. Sometimes after that i do get some messages. The remote is currently continously sending the same message by the way. But there is no real line to find in what to do to get the messages. So i use the default tutorial for CAN, i am not doing anything fancy.

Now i switched back to SDK 4.1.3 and used this code :

    // Messages list
    static CAN.Message[] msgList;

    public static void Main()
    {
        // Set the system time. CAN messages will have a time stamp
        Utility.SetLocalTime(new DateTime(2011, 2, 14, 0, 0, 0));

        int T1, T2, BRP;

        // These numbers were calculated using the calculator on this link:
        // http://www.kvaser.com/can/protocol/index.htm
        // We used the very first value from the calculator output

        /////////////////////////////////////////////////////////////////////////////////////////////
        // Bitrate 250Kbps
        // CLK = 72 Mhz, with BRP = 12 -> 6Mhz CAN clock
        // 6Mhz/250Kbps = 24 TQ
        // T1 = 16 minus 1 for sync = 15
        // T2 = 8
        // 15 + 1 + 8 = 24 TQs which is what we need
        /////////////////////////////////////////////////////////////////////////////////////////////
        // uncomment to use this bit timing
        //BRP = 12;
        //T1 = 15;
        //T2 = 8;

        /////////////////////////////////////////////////////////////////////////////////////////////
        // Bitrate 125Kbps
        // CLK = 72 Mhz, with BRP = 24 -> 3Mhz CAN clock
        // 3Mhz/125Kbps = 24 TQ
        // T1 = 16 minus 1 for sync = 15
        // T2 = 8
        // 15 + 1 + 8 = 24 TQs which is what we need
        /////////////////////////////////////////////////////////////////////////////////////////////
        // uncomment to use this bit timing
        BRP = 24;
        T1 = 15;
        T2 = 8;

        // Use channel 1
        CAN can = new CAN(CAN.Channel.Channel_1, (uint)(((T2 - 1) << 20) | ((T1 - 1) << 16) | ((BRP - 1) << 0)),2);
  
         //create a message list of 100 messages
        msgList = new CAN.Message[100];
        for (int i = 0; i < msgList.Length; i++)
            msgList[i] = new CAN.Message();

        Boolean RUN;
        RUN = true;

        while (RUN == true)
        {
             int count = can.GetRxQueueCount() ;
            if (can.GetRxQueueCount() > 0) 
            {
                can.GetMessages(msgList);
               for (int i = 0; i < count; i++)
               {
                   Debug.Print("MSG: ID = " + msgList[i].ArbID );
               }
            }
            System.Threading.Thread.Sleep(50); 
        }

    }

Now it works straigth away without any problems! I know that there is a new CAN driver in 4.1.5, but is there something in there that we have to do that i am forgetting? Like i said, i tried the default tutorial code and that doesn’t work good. Is there something that is changed that could make things more critical? I has got me a bit puzzled because the above code works at once without any problems.

Regards,

Per

What code did you use in latest SDK?

Hi Gus,

this code.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
 
public class Program
{
    // Messages list
    static CAN.Message[] msgList;
 
    public static void Main()
    {
        // Set the system time. CAN messages will have a time stamp
        Utility.SetLocalTime(new DateTime(2011, 2, 14, 0, 0, 0));
 
        int T1, T2, BRP;
 
        // These numbers were calculated using the calculator on this link:
        // http://www.kvaser.com/can/protocol/index.htm
        // We used the very first value from the calculator output
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        // Bitrate 250Kbps
        // CLK = 72 Mhz, with BRP = 12 -> 6Mhz CAN clock
        // 6Mhz/250Kbps = 24 TQ
        // T1 = 16 minus 1 for sync = 15
        // T2 = 8
        // 15 + 1 + 8 = 24 TQs which is what we need
        /////////////////////////////////////////////////////////////////////////////////////////////
        // uncomment to use this bit timing
        //BRP = 12;
        //T1 = 15;
        //T2 = 8;
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        // Bitrate 125Kbps
        // CLK = 72 Mhz, with BRP = 24 -> 3Mhz CAN clock
        // 3Mhz/125Kbps = 24 TQ
        // T1 = 16 minus 1 for sync = 15
        // T2 = 8
        // 15 + 1 + 8 = 24 TQs which is what we need
        /////////////////////////////////////////////////////////////////////////////////////////////
        // uncomment to use this bit timing
        BRP = 24;
        T1 = 15;
        T2 = 8;
 
        // For 500Kbps you can use BRP=6 and for 1Mbps you can use BRP=3 ...and so on
 
        // Use channel 1
        CAN can = new CAN(CAN.Channel.Channel_1, (uint)(((T2 - 1) << 20) | ((T1 - 1) << 16) | ((BRP - 1) << 0)));
 
        // create a message list of 100 messages
        msgList = new CAN.Message[100];
        for (int i = 0; i < msgList.Length; i++)
            msgList[i] = new CAN.Message();
 
        /*
        // example for sending one message
        // msg ID
        msgList[0].ArbID = 0x55;
        msgList[0].Data[0] = 1;
        msgList[0].Data[1] = 2;
        msgList[0].Data[2] = 3;
        msgList[0].Data[3] = 4;
        msgList[0].Data[4] = 5;
        msgList[0].Data[5] = 6;
        msgList[0].Data[6] = 7;
        msgList[0].Data[7] = 8;
        // Send the 8 bytes for example
        msgList[0].DLC = 8;
        msgList[0].IsEID = false;
        msgList[0].IsRTR = false;
        // Send one messages
        int numberOfMessagesPosted = can.PostMessages(msgList, 0, 1);
        */
 
        // subscribe to events
        can.DataReceivedEvent += new CANDataReceivedEventHandler(can_DataReceivedEvent);
        can.ErrorReceivedEvent += new CANErrorReceivedEventHandler(can_ErrorReceivedEvent);
 
        // sleep forever
        Thread.Sleep(Timeout.Infinite);
    }
 
    static void can_DataReceivedEvent(CAN sender, CANDataReceivedEventArgs args)
    {
        Debug.Print(">>> can_DataReceivedEvent <<<");
 
        // read as many messages as possible
        int count = sender.GetMessages(msgList, 0, msgList.Length);
        for (int i = 0; i < count; i++)
        {
            Debug.Print("MSG: ID = " + msgList[i].ArbID + " at time = " + msgList[i].TimeStamp);
        }
    }
 
    static void can_ErrorReceivedEvent(CAN sender, CANErrorReceivedEventArgs args)
    {
        Debug.Print(">>> can_ErrorReceivedEvent <<<");
 
        switch (args.Error)
        {
            case CAN.Error.Overrun:
                Debug.Print("Overrun error. Message lost");
                break;
 
            case CAN.Error.RXOver:
                Debug.Print("RXOver error. Internal buffer is full. Message lost");
                break;
 
            case CAN.Error.BusOff:
                Debug.Print("BusOff error. Reset CAN controller.");
                sender.Reset();
                break;
        }
    }
}

and then i sometimes get the datareceived event. But most of the time i don’t. If i pull out the can wire it will give an can busoff error and will reset the can controller. Then i sometimes get the received event (but not all the times, so i can’t really find a fix that works all the times). Switching to the previous sdk solves the problem at once.

Regards,

Per

Current SDK is NOT 4.1.5.

SDK Version 1.0.15 June 30, 2011
• USBizi (FEZ Mini, FEZ Domino, FEZ Rhino, FEZ Panda) V 4.1.6.0
•EMX (FEZ Cobra) V 4.1.6.0, TinyBooter V 4.1.6.0
•ChipworkX V 4.1.6.0 TinyBooter V 4.1.5.1
•GHI NETMF Library V 4.1.6.0

4.1.5 was from March:
SDK Version 1.0.13 March 14, 2011
• USBizi (FEZ Mini, FEZ Domino, FEZ Rhino, FEZ Panda) V 4.1.5.0
•EMX (FEZ Cobra) V 4.1.5.0, TinyBooter V 4.1.3.0
•ChipworkX V 4.1.5.0 TinyBooter V 4.1.3.0
•GHI NETMF Library V 4.1.5.0

Edit: not saying this is your problem, but I am saying that you keep saying the latest SDK but it’s not. There aren’t any obvious release notes related to CAN but it is always worth going to the latest and confirming your error is still there, that way GHI know what firmware level to review their code on.

Hi Brett,

sorry my mistake, i just quickly looked what it said on the download page. But it is the latest version we are working with. But you are correct! I have been sitting behind my computer for too long i guess to get this product ready for a major tradeshow this week…

The one that does work is this one : [url]http://www.ghielectronics.com/downloads/NETMF/GHI%20NETMF%20v4.1%20SDK(4.1.3.0).zip[/url]

The main thing is that ghi changed the CAN driver and somehow that doesn’t work on our system. Data is being send correctly by the remote control. We are debugging with CAN monitoring software and i can debug CAN signals on my scope yokogawa DLM2024). Which is a great scope by the way that will show all kinds of serial signals, including CAN, but that is an add on that you will need to buy.

But the main thing is that i measure with the scope on the CAN inputs of our pcb and the software tool sits as a sniffer between it. They both show the correct data coming from the remote. If i use the sdk from the above link then it works straight away. So i am wondering what is changed that could have this effect. We use a pretty standard can transceiver [url]http://www.infineon.com/dgdl/tle6250_v38.pdf?folderId=db3a304412b407950112b437def36973&fileId=db3a304412b407950112b437df786974[/url] in al our designs.

Regards,

Per

Ok, we couldn’t go back to the older ghi sdk. So i changed the code to this and it is now working (but without the receive event).

 public static void Main()
        {

            // Use channel 1
            CANchannel = new CAN(CAN.Channel.Channel_1, (uint)(((T2 - 1) << 20) | ((T1 - 1) << 16) | ((BRP - 1) << 0)), 200);

            // create a message list of 200 messages
            CAN_rcvList = new CAN.Message[200];
            for (int i = 0; i < CAN_rcvList.Length; i++)
                CAN_rcvList[i] = new CAN.Message();

            // subscribe to events
            //CANchannel.DataReceivedEvent += new CANDataReceivedEventHandler(CANchannel_DataReceivedEvent);
            CANchannel.ErrorReceivedEvent += new CANErrorReceivedEventHandler(CANchannel_ErrorReceivedEvent);

            // Timer starten die periodiek events roept.
            Timer CANtimer = new Timer(new TimerCallback(CANEvents_OnTimer), null, 0, 10000);

            //Thread.Sleep(Timeout.Infinite);

            while (Program.RUN == true)
            {
                MessageCount = CANchannel.ReceivedMessagesCount;

                if (MessageCount > 0)
                {
                    CANchannel.GetMessages(CAN_rcvList, 0, CAN_rcvList.Length);
                    for (int i = 0; i < MessageCount; i++)
                    {
                        ProcessMessage(CAN_rcvList[i]);
                    }
                }

                Thread.Sleep(50);
            }

        }

With this the device can be shipped to the tradefair at least. But i would still like to use the event that is there for this ofcourse :stuck_out_tongue:

Regards,

Per

What did you change to make it work? The event should work fine as well. Don’t read the messages in the while loop and you should receive an event.

Hi Mike,

well that is the entire problem, we don’t get the event. It sometimes happens, but not very often and there also is no real path to take to get them to work. Sometimes if we disconnect the remote it will fire the Bus off error and then the can controller will get a reset. But that doesn’t work every time.

Like i said, i have checked the rx an tx pins of the can transceiver with our scope and the correct data is there. The only way to get it to work at this moment (for us) is with the while loop. I don’t want to do it this way either but i needed to (because of the tradefair of our customer). But what can be wrong then? If i can get the data using the while loop, then there something must be going wrong in the can driver part (that fires the event)?

In the beginning i thought that the emx might be to busy or something, but even with just the sample code doesn’t work. That codes just outputs received messages to the debug window (i posted it in on of my earlier replies).

Regards,

Per

Anybody from GHI got any ideas?

I am thinking about it but it is not making a lot of sense! Receive works fine but receive events are not firing! Are you 100% positive you have used the exact same hardware and the exact same setup and the exact same firmware then tested with events and without events?

A problem like this will need some time to investigate. I hope your latest code will get you by till we/you can find the source of the problem.

Hi Gus,

it is exactly the same hardware. The processor board of our design hasn’t changed in quite some time now (months). The back plane has, but that hasn’t got anything to do with the processor board. I can replicate the situation in under a minute. Just remove the while loop and everything becomes strangely quite on the CAN receiving part.

So i am using the latest sdk from the website (from the download page, from Jun. 30, 2011). It is not that i never get a receive event (almost never). The remote control has got a test function and then it will send data continuously to the processor board. Every 5 seconds it sends the same data (just an ID number on address 8). Sometimes after rebooting everything or disconnecting the CAN line the event starts to fire. As long as you then don’t do anything (reboot or whatever) it will keep receiving (don’t know if it will stop after an hour or something because i didn’t wait that long).

But i also understand that it is strange. Since the data is there and can be read without a problem in the while loop. Weird isn’t it :P. Like i said, i got it working now for the customer, the tradefair started today for them. Works without a problem with the while loop!

Regards,

Per

I think it didn’t work before because you specified only 2 messages buffered in the constructor:

The receive event will not be fired if you read the messages already in a loop or somewhere else.

Please copy our documentation example and try it as-is. Only change bit timings if you must. Please let us know if this works.

Hi Mike,

i just tried 2, 20, 80, 100 and 200 bytes buffer. Doesn’t help (and i removed the while loop ofcourse :wink: )

Regards,

Per

Have you tried the example in docs as is with no changes at all? Answering this will make Mike happier :slight_smile:

Hi Gus,

i will try anything to make mike happy ofcourse ; But which docs do you mean exactly? From the wiki [url]http://wiki.tinyclr.com/index.php?title=CAN[/url] I don’t think you mean the one from the free ebook on the download page, because that one still works in the old way with the while loop.

But isn’t the second code i posted in this thread the way mike means? At least that is like in the wiki. If have tried it with declaring different buffer sizes in the can bus declaration and with no specific buffer size.

Or does mike mean some other sample code?

Regards,

Per

The one in official documentation not he wiki
http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/html/d2f107a4-a6fb-58bf-f847-4ec15aa14496.htm

Thanks for taking time in helping out.

Hi Gus,

Morning overhere in the Netherlands again :wink: No problems, i think we all want to solve this. So i copied the code exactly and this is what happens :

Run 1 : Yes, i get data!
Run 2 : Still data
Run 3 : :frowning:
Run 4 : :’(
Run 5 : Data again
Run 6 : No data
Run 7 : Data again

Strange isn’t it. But my scope gives is attached to the rx and tx pins of the can tranceiver and can decode the data without a problem on all runs.

Regards,

Per

1 Like

WOW! I guess we need more help then!

When you run again, do you redeploy or you you power the device?

Also, I am thinking maybe the device going into buss off before the system run. Try this please, disconnect the CAN cable, reset the device, wait 5 seconds, plug CAN back in. Does it work every time?

What type of cable are you using?
Have you terminated the cable?
Have you only applied the BIAS resistors once?
What resistor values are you using?

Hi Wouter,

we have been very busy so i didn’t reply in the forum :(. We use the following tranceiver for the can bus : TEL6250G_V33. I have tried different settings for the resistors for testing. The bus is terminated with 122 ohm at this moment. I have also added the bias resistors externally to make sure that that isn’t the problem. The transceiver should do this with this chip.

But we have done some extra testing and the part where we do get the data received event and when not is much smaller now. If we boot the system WITHOUT anything connected to the can bus then we never get the event (when i connect something ). I have attached my scope again to the receive output of the transceiver and the data is there. If i boot the system now with something connected the receive event gets fired.

So what did i change? There was a filter for noise on the can L and H, i removed that. I removed all resistors and just added the 122ohm for the bus load. Looking at the above situation (no data when booting without anything connected and then connect something) i thought that i might be something with the bias. But that can’t be the problem since i get the data on the output of the transceiver…

Regards,

Per