Unexplained CanMessage Exception

(edit: I inherited this code from someone else so I apologize if it takes me a bit to find stuff)

Hi, I’m getting an unexplained exception in the CAN WriteMessage(CanMessage) method.

This is the message I’m trying send:

{GHIElectronics.TinyCLR.Devices.Can.CanMessage}|GHIElectronics.TinyCLR.Devices.Can.CanMessage|
|||ArbitrationId|5|int|
|||BitRateSwitch|0|bool {int}|
|+||Data|{byte[8]}|byte[]|
|||ErrorStateIndicator|Active|GHIElectronics.TinyCLR.Devices.Can.ErrorStateIndicator|
|||ExtendedId|1|bool {int}|
|||FdCan|0|bool {int}|
|||Length|8|int|
|||RemoteTransmissionRequest|0|bool {int}|

Does the ErrorStateIndicator have anything to do with it? it never gets set, but if that’s something that should be monitored then I can look into that more. This is just keeping our app from running, is there anything else I can do to see what exactly is failing?

This is the exception:

Exception System.Exception - CLR_E_BUSY (1)

#### Message: 
#### GHIElectronics.TinyCLR.Devices.Can.Provider.CanControllerApiWrapper::WriteMessages [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.Can.CanController::WriteMessages [IP: 001c] ####
#### GHIElectronics.TinyCLR.Devices.Can.CanController::WriteMessage [IP: 000e] ####
#### VersaCAN.CAN::CAN_SendItem [IP: 0148] ####
#### VersaCAN.CAN::CAN_SendMessage [IP: 0338] ####
#### TitanVersa.Program::Main [IP: 0426] ####

Exception thrown: ‘System.Exception’ in GHIElectronics.TinyCLR.Devices.Can.dll

Can you post your CAN initialization code?
Maybe the code where you create this message and actually send it could be useful too.

1 Like

There is a property call CanWrite, make sure that one is true before sending a message.

1 Like

I will post it but keep in mind that this works 95% of the time. Sometimes i power on the machine and…nothing. Power cycle and it will fire right up.

Initialize:

can = CanController.FromName(SC20260.CanBus.Can1);
            //can = CanController.FromName(SC20260.CanBus.Can2);

            var propagationPhase1 = 13;
            var phase2 = 2;
            var baudratePrescaler = 24;
            var synchronizationJumpWidth = 1;
            var useMultiBitSampling = false;

            //var propagationphase1 = 7;
            //var phase2 = 8;
            //var baudratePrescaler = 27;
            //var synchronizationJumpWidth = 1;
            //var useMultiBitSampling = false;

            can.SetNominalBitTiming(new CanBitTiming(propagationPhase1, phase2, baudratePrescaler, synchronizationJumpWidth, useMultiBitSampling));

            can.MessageReceived += CanController_MessageReceived;
            can.ErrorReceived += CanController_ErrorReceived;

            can.Enable();

Sending:

private static bool CAN_SendItem(string item)
        {
            if(item == "" || item == null)
            {
                return true;
            }
            // show current screen and command array index:
            //Debug.WriteLine("[" + ((int)DataDefs.CurrentScreen).ToString() + "][" + DataDefs.CurrentSubScreen.ToString() + "][" + canIndex.ToString() + "] " +
            //                (item.Substring(0, 1) == "?" ? item : "       " + item));
            int cscrn = (int)DataDefs.CurrentScreen;
            int csub = (int)DataDefs.CurrentSubScreen;
            LastCmd = item;
            Stat.LastCmd = item;

            if (item == "?FM" ) //|| item == "=VPUD")
            {

            }

            string canSendString = item + "\r";  // add carraige return to string
            string tmpstr = canSendString;

            byte[] tempByteArray;   // cmd string to byte array
            byte[] fullCanSendByte = new byte[8];       // the packet buffer

            int p;
            byte arbId = 4;
            do
            {
                p = canSendString.IndexOf('\r');
                if (p >= 8) // cmd is longer than one packet
                {
                    tempByteArray = Encoding.UTF8.GetBytes(canSendString.Substring(0, 8));  // convert string to one packet byte array 
                    tmpstr = canSendString.Substring(0, 8);     // tmpstr is string of one packet cmd
                    canSendString = canSendString.Substring(8); // remainder of cmd string
                    Thread.Sleep(1);
                }
                else    // cmd fits into one packet
                {
                    tempByteArray = Encoding.UTF8.GetBytes(canSendString.Substring(0, p + 1));  // convert string to byte array
                    tmpstr = canSendString.Substring(0, p + 1);     // string of cmd
                    canSendString = "";     // no remainder
                }

                for (int i = 0; i < fullCanSendByte.Length; i++)    // load packet buffer
                {
                    if (i < tempByteArray.Length)
                    {
                        fullCanSendByte[i] = tempByteArray[i]; // copy command
                    }
                    else
                    {
                        fullCanSendByte[i] = 0;     // zero fill
                    }
                }
                ++arbId;        // set arb ID for this packet

                canMessage = new CanMessage()  // build can message
                {
                    Data = fullCanSendByte,
                    ArbitrationId = arbId,
                    Length = fullCanSendByte.Length,
                    RemoteTransmissionRequest = false,
                    ExtendedId = true
                };
                if (canRxMessage != "")
                {

                }
                canRxMessage = "";
                //T_CanWait = new Tmr(10000);       // instantiate timer
                //                T_CanWait = new Tmr(300);       // instantiate timer

                //                CanTO = new Timer(CanTimeout, null, 5000, Timeout.Infinite);
                elapsed = DateTime.Now.Ticks;

                can.WriteMessage(canMessage);  // Send the can message <----Throws exception on this line
                CAN.canStatus = CanStatus.Receiving;

                //Stat.CANSend = true;
            }
            while (canSendString.Length > 0);

            ++Stat.CAN_MsgCount;
            

            return true;

Are you receiving any errors in the error event handler?

Correct but if the system is too busy then maybe there is no room to send the message. Which is why Dat was asking if you check CanWrite before you Write.

1 Like

@Dat_Tran, I don’t believe it is - I’ll implement that and see if the problem goes away. Thanks