CAN Support in Meadow

The Controller Area Network (commonly called “CAN”) bus is a fault-tolerant, two-wire serial bus used extensively in automotive and telematics applications today. Since Meadow hardware provides an excellent platform for applications in the harsh environments of fielded vehicle monitoring and control systems, we have added support for CAN bus operations to our Meadow.Foundation library. In doing so we, once again, are greatly simplifying IoT application development for .NET developers.

Using CAN

The starting point for applications using a CAN bus is the ICanController interface. Any hardware that provides access to one or more physical buses implements this interface, and it is through this interface that an application obtains an ICanBus instance by calling CreateCanBus().

ICanBus CreateCanBus(CanBitrate bitrate, int busNumber = 0);

For example, if you are using hardware with the common MCP2515 CAN controller, your application creates an instance of the Mcp2515, providing information about the physical connection (e.g. SPI bus, chip select, etc) and then use the CreateCanBus() method to get an instance of an ICanBus that represents the hardware.

var mcp = new Mcp2515(
    Device.CreateSpiBus(),
    Device.Pins.D05.CreateDigitalOutputPort(true),
    Mcp2515.CanOscillator.Osc_8MHz,
    Device.Pins.D05.CreateDigitalInterruptPort(InterruptMode.EdgeFalling),
    Resolver.Log);

var bus = mcp.CreateCanBus(CanBitrate.Can_250kbps);

CAN data, AKA Frames

CAN bus communication revolves around data packets called “frames” and therefore the API we provide is also frame-centric.

Once you have an instance of an ICanBus from the CreateCanBus method, putting data onto the bus from an application is a single method call to the WriteFrame() method. For example, sending a standard (11-bit ID) data frame can be done like this:

bus.WriteFrame(new StandardDataFrame
{
    ID = 0x700,
    Payload = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
});

The procedure for sending extended (29-bit ID) frames or retransmit request (RTR) frames is effectively the same, just substituting a different concrete ICanFrame instance for the call parameter.

Applications that need to receive frames have a couple different options.  First, the bus can be queried at any time using a call to ReadFrame.

if (bus.IsFrameAvailable)
{
    var frame = bus.ReadFrame();

    if(frame != null)
    {
        // handle frame data
    }
}

If the selected CAN controller supports interrupts, then the application can use events to get notified when frames arrive on the bus.

bus.FrameReceived += (object sender, ICanFrame e) =>
{
    // handle frame data
};

The addition of CAN bus support to the Meadow.Foundation library greatly simplifies creating IoT and automotive applications, making it easier for .NET developers to integrate robust vehicle monitoring and control systems. With simple and intuitive APIs for both sending and receiving CAN frames, along with support for common hardware like the MCP2515, developers can now build fault-tolerant applications with minimal effort. Whether you’re handling data through direct polling or leveraging event-based notifications, Meadow’s CAN bus support streamlines the process of developing applications for this common vehicle bus.