JMRI® connects to...

Controller Area Networks (CAN)

Supported Hardware

Devices, command stations, networks, and protocols:


By the community of


JMRI tools for working with your layout:

Layout Automation

Use JMRI to automate parts of your layout and operations:

JMRI Help:
Contents/ Index
Glossary/ FAQ

Donate to JMRI Donate to

Hardware Support: CAN - Scripting

JMRI scripting can be used to send and receive CAN frames. You can use this to create test routines for boards under development, etc.

This page describes the CAN extensions for JMRI scripting. For more information on JMRI scripting itself, see the Scripting Help pages.

There's a basic sample script in the jython directory.

Scripting Code Examples

Sending CAN Frames

CAN frames are created as objects, then queued for transmission. The header (ID) and data are handled separately.

frame = jmri.jmrix.can.CanMessage(2)  # will load 2 bytes
frame.setElement(0, 0x45)
frame.setElement(1, 0x67)
jmri.jmrix.can.TrafficController.instance().sendCanMessage(frame, None)

Receiving CAN Frames

A script can listen for CAN frames as they're received from the bus, and separately for CAN frames that are being transmitted on the bus by JMRI. The CanListener interface provides these separately via "reply" and "message" procedures, respectively.

class MyCanListener (jmri.jmrix.can.CanListener) :
    def message(self, msg) :
        # handle transmitted CAN frames by ignoring them
    def reply(self, msg) :
        # handle received CAN frames by printing their content
        print "received Frame"
        print "ID: 0x"+java.lang.Integer.toHexString(msg.getId())
        print "content: ", msg.toString()