CAN
CANH: CAN-High, CANL: CAN-Low, NC: Not Connected
V-: Ground, 5V: 5V output, V+: BATT rail output (~12V)
Ports are interconnected and used for daisy-chaining. Rated for 1Amp.
Cable is available in our store: Totemmaker.net store → TOTEMBUS CABLE
Interact with CAN bus network connected over TBUS (TotemBUS) connector. Has dual purpose: Plug into CAN bus networks or attach X4 extension modules.
void setup() {
// Start CAN peripheral at 500kbps
CAN.begin(500);
}
void loop() {
// Wait for CAN packet receive. 300ms timeout
if (CAN.readPacketWait(300)) {
// Get received packet
auto packet = CAN.getPacket();
// packet.id, packet.data, packet.len, packet.ext, packet.rtr
}
// Send CAN packets
uint8_t data[8] = {1,2,3,4,5,6,7,8};
CAN.writePacketExt(0x112233, data, 8); // Extended
CAN.writePacketStd(0x1AB, data, 8); // Standard
}
For more example code check: Examples → RoboBoard → CAN
Wiring
CAN bus network requires specific wiring with terminal resistors at each side of yellow and green wires. 120Ω resistor is already present inside X4. Additional one should be added to the last node in the network. May use resistors inside module (if available) or external one.
GUI Monitor
RoboBoard X4 is compatible with open source SavvyCAN application to monitor CAN bus traffic. For setup instructions check totemmaker/ESP32RET repository.
Operating modes
CAN peripheral operates in 3 modes:
- Normal - Send and received messages on CAN bus.
- Listen - Receive messages without influencing the bus (monitoring).
- Loopback - Sent messages will be received right away. Used for demo and testing purposes.
Supported baud (kBits): 25, 50, 100, 125, 250, 500, 800, 1000
CAN.begin(
baud
) ¶-
Start CAN bus peripheral in Normal mode.
Parameter:baud
: CAN bus baud rate (kBits). CAN.beginListen(
baud
) ¶-
Start CAN bus peripheral in Listen mode.
Note: There must be at least 2 devices on CAN bus for messaging to work, as RoboBoard won't send any packet acknowledgments. Can't usewritePacket
in this mode.
Parameter:baud
: CAN bus baud rate (kBits). CAN.beginLoopback(
baud
) ¶-
Start CAN bus peripheral in Loopback mode.
Works without attached to CAN bus network. Each sent packet will loop back to receiver.
Parameter:baud
: CAN bus baud rate (kBits). CAN.end() ¶
-
Stop CAN peripheral. Required to change working mode or hardware filter.
state
CAN.isRunning() ¶-
Check if CAN peripheral state is "running".
Returns:true
: CAN is running.false
: CAN is non-functional. CAN.setEnable(
state
) ¶-
Switch CAN peripheral between "running" and "stopped" states.
Can be used to temporary stop packet transmit and reception.
Parameter:
state
-true
: put CAN to "running" state.false
: put CAN to "stopped" state.
Writing
CAN.writePacketStd(id
,data
,len
)
¶
CAN.writePacketExt(
id
,data
,len
) ¶-
Send CAN data packet. "Std" and "Ext" differs in identifier size:
• Standard: 11-bit identifier [0
:0x7FF
].
• Extended: 29-bit identifier [0
:0x1FFFFFFF
].
Parameter:
id
- identifier.
data
- pointer to 8-bit array (or NULL if len = 0).
len
- length of "data" array. [0
:8
].
CAN.writePacketStdRtr(id
,len
)
¶
CAN.writePacketExtRtr(
id
,len
) ¶-
Send Remote Transmission Request packet. "Std" and "Ext" differs in identifier size:
• Standard: 11-bit identifier [0
:0x7FF
].
• Extended: 29-bit identifier [0
:0x1FFFFFFF
].
Parameter:
id
- identifier.
len
- data length field. [0
:8
]. CAN.writePacket(
ext
,id
,data
,len
,rtr
) ¶-
Send CAN packet. Allows to select packet configuration trough parameters.
Ifrtr
is set - parameterdata
is ignored.
Parameter:
ext
-true
: extended packet.false
: standard packet.
id
- identifier extended:[0
:0x1FFFFFFF
], standard: [0
:0x7FF
].
data
- pointer to 8-bit array (or NULL if len = 0).
len
- length of "data" array. [0
:8
].
rtr
-true
: send RTR packet.false
: send data packet. Default:false
.
Reading
Different message reception methods available. Only single one can be used at the time:
- Event mode - messages will be received inside registered event handlers
- Event is fired right after message is received
- Multiple application modules can register event for CAN reception
- Main loop is free to use for other application requirements
- Polling mode - messages will be acquired using
readPacket
function inside a loop- Faster reception (bypassing event handling and context switching)
- Better handles high amount of data
Event mode
CAN.addEvent(
function
) ¶-
Register CAN packet receive event. Can be read using
getPacket()
.
Parameter:
function
- function name. CAN.removeEvent(
function
) ¶-
Unregister CAN packet receive event. Passed function won't be called anymore.
Parameter:
function
- registered function name.
void eventCAN() {
auto packet = CAN.getPacket();
// packet.id, packet.data, packet.len, packet.ext, packet.rtr
}
void setup() {
CAN.begin(500);
CAN.addEvent(eventCAN);
}
void loop() {
// Free to use
}
Polling mode
state
CAN.readPacket() ¶-
Read received packet. Acquired packet is returned by function
getPacket()
.
Each call will pull new packet from internal receive queue.
Returns:true
: packet is received.false
: no packets available.
state
CAN.readPacketWait()
¶
state
CAN.readPacketWait(timeout
) ¶-
Read received packet. Acquired packet is returned by function
getPacket()
.
Each call will pull new packet from internal receive queue.
Function will halt code execution until new packet is received or timeout is passed.
Parameter:
timeout
- (ms) time to wait for packet. Default: 0 - indefinitely.
Returns:true
: packet is received.false
: no packets available, timeout.
void setup() {
CAN.begin(500);
}
void loop() {
if (CAN.readPacketWait(300)) {
auto packet = CAN.getPacket();
// packet.id, packet.data, packet.len, packet.ext, packet.rtr
}
}
CANPacket
CAN.getPacket() ¶-
Return received CAN packet inside event function or after
readPacket()
returnedtrue
.
Returns:CANPacket
structure, containing packet information.
struct CANPacket { uint16_t ext : 1; // Is extended packet (or standard) uint16_t rtr : 1; // Is Remote Transmit Request int16_t filter; // Software filter that accepted packet (otherwise -1) uint32_t id; // Packet identifier uint8_t len; // Packet data length uint8_t data[8]; // Packet data array };
Filters
Filters will be applied to all received messages and intercepted only if id
and mask
parameters matches. Used to receive only specific packets, ignoring anything else.
Software
Software filters are running inside application, but has a few more advantages:
• Associate received packet with filter it matched packet.filter
.
• Add and remove filters when CAN peripheral is running.
• Add up to 16 filters.
CAN.setFilterStd(
num
,id
,mask
) ¶-
Set standard software filter.
Parameter:
num
- filter slot number [0
:15
].
id
- identifier [0
:0x7FF
].
mask
- validated identifier bits [0
:0x7FF
]. CAN.setFilterExt(
num
,id
,mask
) ¶-
Set extended software filter.
Parameter:
num
- filter slot number [0
:15
].
id
- identifier [0
:0x1FFFFFFF
].
mask
- validated identifier bits [0
:0x1FFFFFFF
]. CAN.resetFilter(
num
) ¶-
Disable filter on selected slot (num).
Parameter:
num
- filter slot number [0
:15
].-1
- disable all filters.
void setup() {
CAN.begin(500);
// Allow to receive only standard packets:
// 0x0A1 0x1A1 0x2A1 0x3A1 0x4A1 0x5A1 0x6A1 0x7A1
// 0x0A2 0x1A2 0x2A2 0x3A2 0x4A2 0x5A2 0x6A2 0x7A2
CAN.setFilterStd(0, 0xA1, 0xFF);
CAN.setFilterStd(1, 0xA2, 0xFF);
}
Hardware
Hardware filters are limited, but efficient with high amount of data.
Notice:
• Must be configured before calling CAN.begin()
.
• Only single one of "setHardware" function can be used.
CAN.setHardwareFilterStd(
id
,mask
) ¶-
Set single standard hardware filter.
Parameter:
id
- identifier [0
:0x7FF
].
mask
- validated identifier bits [0
:0x7FF
]. CAN.setHardwareFilterExt(
id
,mask
) ¶-
Set single extended hardware filter.
Parameter:
id
- identifier [0
:0x1FFFFFFF
].
mask
- validated identifier bits [0
:0x1FFFFFFF
]. CAN.setHardwareFilterDual(
id1
,mask1
,id2
,mask2
) ¶-
Set dual hardware filter. Can filter out 2 different standard packets.
Parameter:
id1
,id2
- identifier [0
:0x7FF
].
mask1
,mask2
- validated identifier bits [0
:0x7FF
]. CAN.setHardwareFilter(
code
,mask
,single
) ¶-
Set hardware filter manually. Allows for some additional configuration.
For meaning ofcode
andmask
read: ESP32 → TWAI → Acceptance Filter.
Parameter:
code
- 32-bit code.
mask
- 32-bit mask.
single
-true
: single filter,false
: dual filter.
void setup() {
// Allow to receive only standard packets:
// 0x0A1 0x1A1 0x2A1 0x3A1 0x4A1 0x5A1 0x6A1 0x7A1
CAN.setHardwareFilterStd(0xA1, 0xFF);
CAN.begin(500);
}
Bus info
alerts
CAN.readAlerts() ¶-
Read CAN peripheral alerts (if any). Returned value is reset each function call.
Returns:
alerts
- 32-bit value of active alerts. See TWAI - Alerts for description.
Definitions are available in#include "driver/twai.h"
count
CAN.readRxCount() ¶-
Read amount of queued RX messages.
Returns:
count
- number of messages awaiting for read withreadPacket
.