CAN bus error event rapid firing

Trying to run the example code of CAN-FD from the documentation, as soon as I send a message the error event fires like there is no tomorrow, error code is Passive.

My current setup is the 20260D SOM on a UCM development board. Following the pin out diagrrams I’m initiliasing Can1. I have the can bus setup with two terminating resistors of 120Ohms each

Any thoughts?

Is there a device on the bus that is receiving your message? You need at least 1 other device on the same baud rate to be able to send a message.

This is because can bus messages are acknowledged by the devices on the bus. If this doesn’t happen, a passive error will be thrown.

Ok so double checked my connections and the second device wasn’t connected…however device one which will send a message when i click a button is till erroring at a rate of knots even before i send a message. the second device which is receiving loads of messages till the read buffer is full again before i have actually sent a message.

Any thoughts

It confuses me. Keep in mind that, the button event (I guess you are using UI) has at least 2 events, up and down, and may noise with your finger. So, you click one time, even you did not release your finger up yet, the message was sent. You need to add code to handle this case.

OK so i have simplified the apps to just sending one message from the dev board to the fez stick. I’ve incuded the code below and its still happening.

SC20260D

public sealed class Program
    {
        private static void Main()
        {
            try
            {
                /// References 
                ///     https://docs.ghielectronics.com/hardware/netmf/pdfs/scm20260d-g400d-pinoutmap.pdf
                ///     http://files.ghielectronics.com/downloads/Schematics/Systems/UCM%20Dev%20Board%20Rev%20E%20Schematic.pdf
                ///      
                /// SET UP
                /// 
                /// Fez Stick                
                /// SC20260D Module (replacing my G400D)
                /// UCM Development board
                /// 
                /// CANA on Dev board, GHIElectronics.TinyCLR.Pins.SC20260.CanBus.Can2, is connected to CanBus
                /// Can2 on Fez Stick is connected to CanBus
                /// 
                /// all this app is doing is sending one message but the error event is firing rapidly, 
                /// it seems the module is continually sending the same message over the bus.
                /// 
                /// the second app on the Fez stick is receiving the same message continually and is being overwhelmed with its read buffer maxing out

                var propagationPhase1 = 13; //250 kilobaud settings
                var phase2 = 2;
                var baudratePrescaler = 12;
                var synchronizationJumpWidth = 1;
                var useMultiBitSampling = false;

                var can = CanController.FromName(GHIElectronics.TinyCLR.Pins.SC20260.CanBus.Can1);

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

                baudratePrescaler = 3;  //Change bit timing to 1 megabaud.

                //Set faster CAN speed to 1 megabaud.
                can.SetDataBitTiming(new CanBitTiming(propagationPhase1, phase2, baudratePrescaler, synchronizationJumpWidth, useMultiBitSampling));

                can.Filter.AddMaskFilter(Filter.IdType.Standard, 0x12, 0xFFFF);

                can.MessageReceived += (sender, e) =>
                {
                    Debug.WriteLine($"RX: {sender.MessagesToRead}, TX :{sender.MessagesToWrite}");
                };
                can.ErrorReceived += (sender, e) =>
                {
                    var error = string.Empty;

                    switch (e.Error)
                    {
                        case CanError.Passive:

                            error = "Passive";

                            break;
                        case CanError.ReadBufferOverrun:

                            error = "ReadBufferOverrun";

                            break;
                        case CanError.BusOff:

                            error = "BusOff";

                            break;
                        case CanError.ReadBufferFull:

                            error = "ReadBufferFull";

                            break;
                    }

                    Debug.WriteLine($"Error: {error}, Time stamp: {e.Timestamp}");
                };

                can.Enable();

                Random random = new Random();

                var canMessage = BuildMessage(0x11, (short)random.Next(360), (short)random.Next(1024), 0);

                if (can.CanWriteMessage && can.WriteMessage(canMessage))
                    Debug.WriteLine("CAN message sent.");
            }
            catch
            {
            }
            finally
            {
            }

            Thread.Sleep(Timeout.Infinite);
        }

        private static CanMessage BuildMessage(int arbitrationId, short angle, short power, byte mode)
        {
            var angleBytes = BitConverter.GetBytes(angle);
            var powerBytes = BitConverter.GetBytes(power);
            var data = new byte[] { angleBytes[0], angleBytes[1], powerBytes[0], powerBytes[1], mode };

            return new CanMessage()
            {
                Data = data,
                ArbitrationId = arbitrationId, // priority
                Length = data.Length,
                RemoteTransmissionRequest = false,
                ExtendedId = false,
                FdCan = true,
                BitRateSwitch = true
            };
        }
    }

Fez Stick

    public sealed class Program
    {
        private static void Main()
        {
            try
            {
                var propagationPhase1 = 13; //250 kilobaud settings
                var phase2 = 2;
                var baudratePrescaler = 12;
                var synchronizationJumpWidth = 1;
                var useMultiBitSampling = false;

                var can = CanController.FromName(GHIElectronics.TinyCLR.Pins.SC20100.CanBus.Can2);

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

                baudratePrescaler = 3;  //Change bit timing to 1 megabaud.

                //Set faster CAN speed to 1 megabaud.
                can.SetDataBitTiming(new CanBitTiming(propagationPhase1, phase2, baudratePrescaler, synchronizationJumpWidth, useMultiBitSampling));

                can.Filter.AddMaskFilter(Filter.IdType.Standard, 0x11, 0xFFFF);

                can.MessageReceived += (sender, e) =>
                {
                    $"RX: {sender.MessagesToRead}, TX :{sender.MessagesToWrite}".DebugWriteLine();

                    if (can.ReadMessage(out var message))
                    {
                        byte[] angleBytes = new[] { message.Data[0], message.Data[1] };
                        byte[] powerBytes = new[] { message.Data[2], message.Data[3] };

                        var angle = BitConverter.ToInt16(angleBytes, 0);
                        var power = BitConverter.ToInt16(powerBytes, 0);
                        var mode = message.Data[4];

                        Debug.WriteLine($"Angle: {angle}, Power: {power}, Mode: {mode}");
                    }
                };
                can.ErrorReceived += (sender, e) =>
                {
                    var error = string.Empty;

                    switch (e.Error)
                    {
                        case CanError.Passive:

                            error = "Passive";

                            break;
                        case CanError.ReadBufferOverrun:

                            error = "ReadBufferOverrun";

                            break;
                        case CanError.BusOff:

                            error = "BusOff";

                            break;
                        case CanError.ReadBufferFull:

                            error = "ReadBufferFull";

                            break;
                    }

                    Debug.WriteLine($"Error: {error}, Time stamp: {e.Timestamp}");
                };

                can.Enable();
            }
            catch
            {
            }
            finally
            {
            }

            Thread.Sleep(Timeout.Infinite);
        }
    }

Your code look ok, could you please try do few things:

  • Disable FDCan, mean no need to switch to 1Mbs. When an issue happened, we would like to keep everything simple. A notice here is, if max is 1Mbs then you don’t need to enable FDCan.

  • The received one, is it receiving errors all the time or message all the time. Or first message then error, we need detail on this.

  • You need two CAN modules, one connects to 260D, other one for Stick. TX is TX, RX is RX, no swap like UART. I guess you have right connection but for sure.

Thanks for the response

I will try with FDCan disabled.

The Fez Stick receves the message but continually to the point that a Read Buffer Full error is rasied.

Yes thats right i have the modules and they are wired straight not crossed over.

Makes no difference disabling FDCan. I also tried at a lower baud and still the same…perplexed

I just tried your code between SC20260D and SC20100, only change CAN2 become CAN1 on SC20100 because the setup is ready.

Seem work to me. Do you have any other GHI board so we can test CAN1 to CAN1?

image

Can you take screen shot how those wires connect?

  • You are using UCM board, I am not sure if it is fully compatible to SC20260D. You should us SC20260-Dev Rev C for sure. If RevA or RevB, I think CAN High and Can GND swapped, RevC fixed this issue
  • There is a so many connections done manually, so I am not surprised if something is not correct. Can you please just test CAN only?

Yes i am using a UCM board as stated, according to the doucmentation on the site, Upgrading (ghielectronics.com), the SCM20260D is a drop in replacemnet for the G400D apart from a couple of pins. For this reason we went for SCM20260D module as we already purchased a number of these.

I will setup cleaner rig with just CAN connected

One more thing, can you swap, instead of sender become receiver, and was receiver become sender?

I mean SC20260 was sender, now become receiver…

I have tried swapping the sender and receiver apps around and it is still doing the same, i will change the setup to use 2 Fez sticks as well as simplify the rig.

This is good, I was worried receiving has problem on CAN2 but switched to CAN1 still have problem, mean something wrong with connection:)).

Anyway, if you have 2 UCM, that is much easier, because they have CAN modules buildtin already.

You just need 3 wires between them.

I see you are using external CAN module from FEZ stick, for all test we had, I think something wrong come from that module.

On UCM dev, I believe they have jumper that you can set, no need to add extra resistor on that side.

No jumper on the dev board but there is a couple of pads to add a terminating resistor

image

try to connect them and remove your resistor.

any update on this?

Hi there
sorry for lat response, was off on holiday. Yes I managed to get the two UCM boards talking to each other. Further checks on the transciever also missed the fact that it had a terminating resistor on there as well. However I am still unable to get the ucm board talk to the fez stick though I now have my doubts about the CAN transceiver module.