Exception in CAN DW module

I am trying to build a sample application that send a CAN Message on channel 1 then it is recieved on Channel2 and re-transmitted from channel2.

This sample application should allow for testing CAN Communication without the need of any external hardware.

However when I am sending a CAN Message I end up with the following error:

[quote] #### Exception System.Exception - 0xffffffff (1) ####
#### Message:
#### GHI.IO.ControllerAreaNetwork::NativeSendMessages [IP: 0000] ####
#### GHI.IO.ControllerAreaNetwork::SendMessages [IP: 005d] ####
#### GHI.IO.ControllerAreaNetwork::SendMessages [IP: 0013] ####
#### GHI.IO.ControllerAreaNetwork::SendMessage [IP: 0060] ####
#### CanSample2.Program::timer_Tick [IP: 0044] ####
#### Gadgeteer.Timer::dt_Tick [IP: 0018] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 001d] ####[/quote]

Here is the code:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using GHI.IO;

namespace CanSample2
{
    public partial class Program
    {
        ControllerAreaNetwork CANBUS;
        ControllerAreaNetwork CANBUS2;
        byte runtime = 0;
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            CANBUS = new ControllerAreaNetwork(ControllerAreaNetwork.Channel.One, ControllerAreaNetwork.Speed.Kbps1000);
            CANBUS2 = new ControllerAreaNetwork(ControllerAreaNetwork.Channel.Two, ControllerAreaNetwork.Speed.Kbps1000);
            CANBUS.ErrorReceived += can_ErrorReceived;
            CANBUS.MessageAvailable += can_MessageAvailable;

            CANBUS.Enabled = true;
            CANBUS2.Enabled = true;

            GT.Timer timer = new GT.Timer(5000);
            timer.Tick += timer_Tick;
            timer.Start();
            //Thread.Sleep(-1);
            
        }

        void timer_Tick(GT.Timer timer)
        {
            Debug.Print("Sending Message");
            ControllerAreaNetwork.Message message = new ControllerAreaNetwork.Message() { Data = new byte[] { 0, 0, 0, 0, 0, 0, 0, ++runtime }, Length = 8, IsRemoteTransmissionRequest = false, IsExtendedId = true };
            CANBUS.SendMessage(message);


        }

        private static void can_MessageAvailable(ControllerAreaNetwork sender, ControllerAreaNetwork.MessageAvailableEventArgs e)
        {
            var received = sender.ReadMessage();

            var data = string.Empty;
            for (int i = 0; i < received.Length; i++)
                data += "0x" + received.Data[i].ToString("x2") + " ";

            //Debug.Print("   CAN Message   ");
            //Debug.Print("-----------------");
            //Debug.Print("    ID: " + received.ArbitrationId.ToString());
            //Debug.Print("  Time: " + received.TimeStamp.ToString());
            //Debug.Print("   RTR: " + received.IsRemoteTransmissionRequest.ToString());
            //Debug.Print("   EID: " + received.IsExtendedId.ToString());
            //Debug.Print("Length: " + received.Length.ToString());
            //Debug.Print("  Data: " + data);
            //Debug.Print("");

            sender.SendMessage(new ControllerAreaNetwork.Message() { Data =  BitConverter.GetBytes(received.ArbitrationId), ArbitrationId = 0x12345678, Length = 8, IsRemoteTransmissionRequest = false, IsExtendedId = true });
        }

        private static void can_ErrorReceived(ControllerAreaNetwork sender, ControllerAreaNetwork.ErrorReceivedEventArgs e)
        {
            Debug.Print("Error on CAN: " + e.Error.ToString());
        }
    }
}

@ andre.m - I just switched to the non pre-release SW and it is working now. Is it possible that this is a bug in the Beta 4 SDK?

@ ialastairhunter -

What SDK version and what is the device you are using?

@ Dat - It appears the issue is with GHI Electronics NETMF SDK 2015 R1 Pre-Release 4
However the issue does not occur with NETMF and Gadgeteer Package 2014 R5

The device is a Raptor

Sorry, we can not confirm :D, because we just tested it and working well.
@ ialastairhunter
I am curious because your code looks like not correct. How it works on 2014R1?
Anyway, here is your code with some correction from us, tested on 4.3.7.10.


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GHI.IO;
namespace CAN43_Gadgeeter
{
    public partial class Program
    {
        ControllerAreaNetwork CANBUS;
        ControllerAreaNetwork CANBUS2;
        byte runtime = 0;
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            CANBUS = new ControllerAreaNetwork(ControllerAreaNetwork.Channel.One, ControllerAreaNetwork.Speed.Kbps1000);
            CANBUS2 = new ControllerAreaNetwork(ControllerAreaNetwork.Channel.Two, ControllerAreaNetwork.Speed.Kbps1000);

            CANBUS.ErrorReceived += can_ErrorReceived;
            CANBUS.MessageAvailable += can_MessageAvailable;
            CANBUS2.MessageAvailable += CANBUS2_MessageAvailable;

            CANBUS.Enabled = true;
            CANBUS2.Enabled = true;

            GT.Timer timer = new GT.Timer(5000);
            timer.Tick += timer_Tick;
            timer.Start();
            Debug.Print("Program Started");
        }
        ControllerAreaNetwork.Message[] inBuffer = new ControllerAreaNetwork.Message[1024];
        void CANBUS2_MessageAvailable(ControllerAreaNetwork sender, ControllerAreaNetwork.MessageAvailableEventArgs e)
        {           
            
            var msg = sender.ReadMessage();
          

            Debug.Print("Can 2: Received = " + msg.ArbitrationId
                + " " + msg.Data[0]
                + " " + msg.Data[1]
                + " " + msg.Data[2]
                + " " + msg.Data[3]
                + " " + msg.Data[4]
                + " " + msg.Data[5]
                + " " + msg.Data[6]
                + " " + msg.Data[7]
                + " " + msg.IsExtendedId
                + " " + msg.IsRemoteTransmissionRequest
                + " " + msg.TimeStamp
                );
            
            sender.SendMessage(new ControllerAreaNetwork.Message() { Data = new byte[] { 2, 2, 2, 2, 2, 2, 2, ++runtime }, ArbitrationId = 0x87654321, Length = 8, IsRemoteTransmissionRequest = false, IsExtendedId = true });
        }
        void timer_Tick(GT.Timer timer)
        {
            Debug.Print("Sending Message");
            ControllerAreaNetwork.Message message = new ControllerAreaNetwork.Message() { Data = new byte[] { 1, 1, 1, 1, 1, 1, 1, ++runtime }, ArbitrationId = 0x12345678, Length = 8, IsRemoteTransmissionRequest = false, IsExtendedId = true };
            CANBUS.SendMessage(message);

        }

        private  void can_MessageAvailable(ControllerAreaNetwork sender, ControllerAreaNetwork.MessageAvailableEventArgs e)
        {
            var msg = sender.ReadMessage();
           

            Debug.Print("Can 1: Received = " + msg.ArbitrationId
                + " " + msg.Data[0]
                + " " + msg.Data[1]
                + " " + msg.Data[2]
                + " " + msg.Data[3]
                + " " + msg.Data[4]
                + " " + msg.Data[5]
                + " " + msg.Data[6]
                + " " + msg.Data[7]
                + " " + msg.IsExtendedId
                + " " + msg.IsRemoteTransmissionRequest
                + " " + msg.TimeStamp
                );
        }

        private static void can_ErrorReceived(ControllerAreaNetwork sender, ControllerAreaNetwork.ErrorReceivedEventArgs e)
        {
            Debug.Print("Error on CAN: " + e.Error.ToString());
        }
    }
}


I have the same issue with the raptor, but it works with G120 on CobraII.

I try on several Raptor but the issue remains the same.
Sometimes I got the exception, and sometimes not, but SendMessage method returns “false” and no message on the bus can be seen.

I use this code

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GHI.IO;

namespace CanSample2
{
    public class Program : Gadgeteer.Program
    {
        public static Program ProgramInstance;
        ControllerAreaNetwork CANBUS;
        private static int count = 0;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            CANBUS = new ControllerAreaNetwork(ControllerAreaNetwork.Channel.One, ControllerAreaNetwork.Speed.Kbps250);
            CANBUS.ErrorReceived += can_ErrorReceived;
            CANBUS.MessageAvailable += can_MessageAvailable;
            CANBUS.Enabled = true;


            GT.Timer timer = new GT.Timer(2000);
            timer.Tick += timer_Tick;
            timer.Start();
        }

        void timer_Tick(GT.Timer timer)
        {
            ControllerAreaNetwork.Message message = new ControllerAreaNetwork.Message() { Data = new byte[] { 0, 0, 0, 0, 0, 0, 0, (byte)(count%255) }, Length = 8, IsRemoteTransmissionRequest = false, IsExtendedId = true };
            try
            {
                if(CANBUS.SendMessage(message))
                    Debug.Print(String.Concat("Msg#", ++count, ": ok"));
                else
                    Debug.Print(String.Concat("Msg#", ++count, ": failed"));
            }
            catch
            {
            }
        }

        private static void can_MessageAvailable(ControllerAreaNetwork sender, ControllerAreaNetwork.MessageAvailableEventArgs e)
        {
            var received = sender.ReadMessage();
            Debug.Print("Message received");
        }

        private static void can_ErrorReceived(ControllerAreaNetwork sender, ControllerAreaNetwork.ErrorReceivedEventArgs e)
        {
            Debug.Print("Error on CAN: " + e.Error.ToString());
        }

        public static void Main(string[] args)
        {
            Program.Mainboard = new GHIElectronics.Gadgeteer.FEZRaptor();
            ProgramInstance = new Program();
            ProgramInstance.ProgramStarted();
            // Starts Dispatcher
            ProgramInstance.Run();
        }
    }
}

To add to my previous post, the trace of the exception on G400:

The thread ‘’ (0x2) has exited with code 0 (0x0).
#### Exception System.Exception - 0xffffffff (1) ####
#### Message:
#### GHI.IO.ControllerAreaNetwork::NativeSendMessages [IP: 0000] ####
#### GHI.IO.ControllerAreaNetwork::SendMessages [IP: 005d] ####
#### GHI.IO.ControllerAreaNetwork::SendMessages [IP: 0013] ####
#### GHI.IO.ControllerAreaNetwork::SendMessage [IP: 0060] ####
#### MFConsoleApplication2.Program::Main [IP: 005e] ####

@ cmilllet -

I copied exactly your code and run on our side, it is working fine.
Only way to get your exception is, make a bad connection.
So I guess you should check your connection. If the connection was your problem, easy to see that once it worked, it always work, once it fails, it will be always failed, of course, without changing/touching anything on its connection.

Thanks for the test.

What do you mean when you talk about bad connection ? is nothing connected, only the 120 ohm terminator is a bad connection ?

For example, if i run my program G120 without connecting anything to CAN bus, it perfectly works. But if I do exactly the same with G400, it doesn’t work.

You must have at least 2 nodes. Please read more about the CAN bus. Why do you mean when you say it works?

@ Gus - I mean “it works” when there is no exception and the SendMessage method returns true.

The program “works” with G120, but not G400 with SDK 2015. And it works with G120 and G400 with SDK 2014.
I also tried to add nodes connected to the CAN bus and the results are the same.

Could you explain in which situation the CAN bus could raise an exception ? maybe it could help to explain why it doesn’t work. In my opinion, maybe i’m wrong, if the module is not connected, there is no reason to raise an exception…

One of the many tests I made: I just run the program on a FEZ Raptor with no attached module. Is it regular to get exception when you try to send messages in this configuration ? Same test with FEZ Cobra 2 Eco : no exception.

Thanks in advance for your comments

@ cmilllet - you should not be able you send messages when nothing is connected. We will look into this.

As for your needs, just connect two nodes and everything should work.