### Initialize CAN Controller with begin() Source: https://context7.com/pierremolinaro/acan2515/llms.txt Illustrates the initialization process using the begin() method, including error handling and the setup of an interrupt service routine. It demonstrates how to verify successful initialization and interpret error codes. ```cpp #include ACAN2515 can(10, SPI, 3); static const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000; void setup() { Serial.begin(38400); SPI.begin(); ACAN2515Settings settings(QUARTZ_FREQUENCY, 125 * 1000); settings.mRequestedMode = ACAN2515Settings::LoopBackMode; const uint16_t errorCode = can.begin(settings, [] { can.isr(); }); if (errorCode == 0) { Serial.println("CAN controller initialized successfully"); } else { Serial.print("Configuration error: 0x"); Serial.println(errorCode, HEX); } } ``` -------------------------------- ### Arduino MCP2515 CAN Controller Initialization and Loopback Mode Source: https://github.com/pierremolinaro/acan2515/blob/master/README.md This Arduino sketch demonstrates the basic setup of the ACAN2515 library for the MCP2515 CAN Controller. It configures the controller for loopback mode, allowing messages to be sent and received without external hardware. The code initializes the serial communication, sets up the CAN bit rate, and checks for configuration errors. ```cpp static const byte MCP2515_CS = 20 ; static const byte MCP2515_INT = 37 ; ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ; const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000 ; void setup () { Serial.begin (9600) ; while (!Serial) {} Serial.println ("Hello") ; ACAN2515Settings settings (QUARTZ_FREQUENCY, 125 * 1000) ; settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ; if (0 == errorCode) { Serial.println ("Can ok") ; }else{ Serial.print ("Error Can: 0x") ; Serial.println (errorCode, HEX) ; } } ``` -------------------------------- ### Configure ESP32 for ACAN2515 CAN Bus Source: https://context7.com/pierremolinaro/acan2515/llms.txt This example demonstrates how to initialize the MCP2515 CAN controller on an ESP32 using custom SPI pins. It includes hardware reset handling, SPI bus setup, and the basic loop for sending heartbeat messages and processing incoming CAN traffic. ```cpp #ifndef ARDUINO_ARCH_ESP32 #error "Select an ESP32 board" #endif #include static const byte MCP2515_SCK = 26; static const byte MCP2515_MOSI = 19; static const byte MCP2515_MISO = 18; static const byte MCP2515_CS = 17; static const byte MCP2515_INT = 23; static const byte MCP2515_RESET = 27; ACAN2515 can(MCP2515_CS, SPI, MCP2515_INT); static const uint32_t QUARTZ_FREQUENCY = 20UL * 1000UL * 1000UL; void setup() { pinMode(MCP2515_RESET, OUTPUT); digitalWrite(MCP2515_RESET, LOW); delay(10); digitalWrite(MCP2515_RESET, HIGH); Serial.begin(115200); while (!Serial) { delay(50); } SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI); ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); settings.mRequestedMode = ACAN2515Settings::NormalMode; const uint16_t errorCode = can.begin(settings, [] { can.isr(); }); if (errorCode == 0) { Serial.println("CAN initialized successfully"); } else { Serial.print("Error: 0x"); Serial.println(errorCode, HEX); } } void loop() { static uint32_t lastSend = 0; if (millis() - lastSend >= 1000) { lastSend = millis(); CANMessage heartbeat; heartbeat.id = 0x700; heartbeat.len = 1; heartbeat.data[0] = 0x05; can.tryToSend(heartbeat); } CANMessage received; while (can.receive(received)) { Serial.print("RX: 0x"); Serial.print(received.id, HEX); } } ``` -------------------------------- ### Configure MCP2515 Reception Filters with Callbacks (C++) Source: https://context7.com/pierremolinaro/acan2515/llms.txt Demonstrates how to configure hardware acceptance masks and filters on the MCP2515 controller to selectively receive CAN messages. It includes setting up callback functions for different message types, such as engine data, temperature, and extended frames. This setup requires the ACAN2515 library and basic SPI communication. ```cpp #include ACAN2515 can(20, SPI, 37); static const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000; // Callback functions for each filter static void handleEngineData(const CANMessage& msg) { Serial.print("Engine RPM: "); Serial.println(msg.data16[0]); } static void handleTemperature(const CANMessage& msg) { Serial.print("Temperature: "); Serial.println(msg.data[0]); } static void handleExtendedFrame(const CANMessage& msg) { Serial.print("Extended frame 0x"); Serial.println(msg.id, HEX); } void setup() { Serial.begin(38400); SPI.begin(); ACAN2515Settings settings(QUARTZ_FREQUENCY, 125 * 1000); settings.mRequestedMode = ACAN2515Settings::NormalMode; // Define acceptance masks // RXM0: For filters 0-1 (extended frames), check all 29 bits const ACAN2515Mask rxm0 = extended2515Mask(0x1FFFFFFF); // RXM1: For filters 2-5 (standard frames), check ID bits 10-4 and first data byte const ACAN2515Mask rxm1 = standard2515Mask(0x7F0, 0xFF, 0); // Define acceptance filters with callbacks const ACAN2515AcceptanceFilter filters[] = { {extended2515Filter(0x12345678), handleExtendedFrame}, // Filter 0: Extended ID {extended2515Filter(0x18765432), handleExtendedFrame}, // Filter 1: Extended ID {standard2515Filter(0x100, 0x00, 0), handleEngineData}, // Filter 2: ID 0x100-0x10F {standard2515Filter(0x200, 0x00, 0), handleTemperature} // Filter 3: ID 0x200-0x20F }; // Initialize with filters const uint16_t errorCode = can.begin( settings, [] { can.isr(); }, rxm0, rxm1, filters, 4 // Number of filters ); if (errorCode != 0) { Serial.print("Error: 0x"); Serial.println(errorCode, HEX); } } void loop() { // Dispatch received messages to appropriate callbacks can.dispatchReceivedMessage(); } ``` -------------------------------- ### Buffer Status Query and Flow Control Source: https://context7.com/pierremolinaro/acan2515/llms.txt Provides methods to check the utilization of transmit and receive buffers for performance monitoring and flow control. It shows how to get buffer sizes, current counts, and peak usage. The code is in C++ and utilizes the ACAN2515 library for CAN communication. ```cpp #include ACAN2515 can(10, SPI, 3); void printBufferStatus() { Serial.println("=== Buffer Status ==="); // Receive buffer Serial.print("RX Buffer Size: "); Serial.println(can.receiveBufferSize()); Serial.print("RX Buffer Count: "); Serial.println(can.receiveBufferCount()); Serial.print("RX Buffer Peak: "); Serial.println(can.receiveBufferPeakCount()); // Transmit buffers (3 available: 0, 1, 2) for (uint8_t i = 0; i < 3; i++) { Serial.print("TX Buffer "); Serial.print(i); Serial.print(" - Size: "); Serial.print(can.transmitBufferSize(i)); Serial.print(", Count: "); Serial.print(can.transmitBufferCount(i)); Serial.print(", Peak: "); Serial.println(can.transmitBufferPeakCount(i)); } } void sendWithFlowControl() { CANMessage frame; frame.id = 0x100; frame.len = 8; // Check if buffer has space before sending if (can.sendBufferNotFullForIndex(0)) { frame.idx = 0; // Use transmit buffer 0 can.tryToSend(frame); } else { Serial.println("TX buffer 0 full, waiting..."); } } ``` -------------------------------- ### Initialize ACAN2515 Driver Instance Source: https://context7.com/pierremolinaro/acan2515/llms.txt Demonstrates how to instantiate the ACAN2515 driver, specifying the chip select pin, SPI interface, and interrupt pin. It also shows how to configure the driver for polling mode by using 255 as the interrupt pin. ```cpp #include static const byte MCP2515_CS = 10; static const byte MCP2515_INT = 3; ACAN2515 can(MCP2515_CS, SPI, MCP2515_INT); // Polling mode example // ACAN2515 canPolling(MCP2515_CS, SPI, 255); ``` -------------------------------- ### Configure CAN Bit Timing and Settings Source: https://context7.com/pierremolinaro/acan2515/llms.txt Shows how to use the ACAN2515Settings class to define bit rates and operational modes. It covers setting buffer sizes, enabling triple sampling, and querying the calculated bit rate properties. ```cpp #include static const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000; void setup() { Serial.begin(38400); SPI.begin(); ACAN2515Settings settings(QUARTZ_FREQUENCY, 125 * 1000); settings.mRequestedMode = ACAN2515Settings::NormalMode; settings.mReceiveBufferSize = 32; settings.mTransmitBuffer0Size = 16; settings.mRolloverEnable = true; Serial.print("Actual bit rate: "); Serial.print(settings.actualBitRate()); Serial.println(" bit/s"); } ``` -------------------------------- ### Change MCP2515 Operating Mode On-the-Fly (C++) Source: https://context7.com/pierremolinaro/acan2515/llms.txt Demonstrates the `changeModeOnTheFly()` method of the ACAN2515 library, which allows switching the MCP2515 controller's operating mode at runtime without requiring a full reinitialization. This is useful for transitioning between normal operation, bus monitoring (listen-only), and diagnostic (loopback) modes dynamically. ```cpp #include ACAN2515 can(10, SPI, 3); void switchToListenOnly() { // Switch to listen-only mode (useful for bus monitoring) uint16_t error = can.changeModeOnTheFly(ACAN2515Settings::ListenOnlyMode); if (error == 0) { Serial.println("Now in listen-only mode"); } } void switchToNormal() { // Switch back to normal mode uint16_t error = can.changeModeOnTheFly(ACAN2515Settings::NormalMode); if (error == 0) { Serial.println("Now in normal mode"); } } void switchToLoopback() { // Switch to loopback mode (for testing) uint16_t error = can.changeModeOnTheFly(ACAN2515Settings::LoopBackMode); if (error == 0) { Serial.println("Now in loopback mode"); } } ``` -------------------------------- ### Receive CAN Messages with available and receive Source: https://context7.com/pierremolinaro/acan2515/llms.txt Illustrates two methods for receiving messages: checking availability before reading, or directly attempting to receive a message. ```cpp #include ACAN2515 can(10, SPI, 3); void loop() { if (can.available()) { CANMessage frame; can.receive(frame); Serial.print("ID: 0x"); Serial.print(frame.id, HEX); Serial.println(); } CANMessage message; if (can.receive(message)) { if (message.id == 0x123) { uint32_t sensorValue = message.data32[0]; Serial.print("Sensor reading: "); Serial.println(sensorValue); } } } ``` -------------------------------- ### Transmit CAN Messages with tryToSend Source: https://context7.com/pierremolinaro/acan2515/llms.txt Shows how to queue a message for transmission. The method returns a boolean indicating if the message was successfully added to the buffer. ```cpp #include ACAN2515 can(10, SPI, 3); void loop() { static uint32_t lastSendTime = 0; static uint32_t messageCounter = 0; if (millis() - lastSendTime >= 100) { lastSendTime = millis(); CANMessage frame; frame.id = 0x542; frame.len = 4; frame.data32[0] = messageCounter++; const bool sent = can.tryToSend(frame); if (sent) { Serial.print("Message queued, counter: "); Serial.println(messageCounter); } else { Serial.println("Transmit buffer full, message dropped"); } } } ``` -------------------------------- ### Dynamic Mode Switching Source: https://context7.com/pierremolinaro/acan2515/llms.txt Switches the MCP2515 operating mode (Normal, ListenOnly, LoopBack) at runtime. ```APIDOC ## PUT /can/mode ### Description Changes the MCP2515 operating mode on the fly without requiring a full reinitialization of the controller. ### Method PUT ### Endpoint /can/mode ### Parameters #### Request Body - **mode** (Enum) - Required - Target mode (e.g., NormalMode, ListenOnlyMode, LoopBackMode). ### Request Example { "mode": "ListenOnlyMode" } ### Response #### Success Response (200) - **errorCode** (uint16_t) - Returns 0 on success. ``` -------------------------------- ### Runtime Filter Updates with setFiltersOnTheFly Source: https://context7.com/pierremolinaro/acan2515/llms.txt Demonstrates how to use the `setFiltersOnTheFly()` method to modify acceptance masks and filters dynamically without controller reinitialization. Calling it without arguments disables all filtering, allowing all frames to be received. It requires the ACAN2515 library and is implemented in C++. ```cpp #include ACAN2515 can(10, SPI, 3); static void handleCriticalAlarm(const CANMessage& msg) { Serial.println("CRITICAL ALARM!"); } void enableAllFrames() { // Disable filtering - receive all frames uint16_t error = can.setFiltersOnTheFly(); if (error == 0) { Serial.println("Receiving all frames"); } } void enableSelectiveFiltering() { // Enable filtering for specific IDs only const ACAN2515Mask rxm0 = extended2515Mask(0x1FFFFFFF); const ACAN2515AcceptanceFilter filters[] = { {extended2515Filter(0x1FFFFFF0), handleCriticalAlarm} }; uint16_t error = can.setFiltersOnTheFly(rxm0, filters, 1); if (error == 0) { Serial.println("Selective filtering enabled"); } } ``` -------------------------------- ### Arduino MCP2515 CAN Controller with Optional Reception Filtering Source: https://github.com/pierremolinaro/acan2515/blob/master/README.md This Arduino sketch demonstrates how to configure optional reception filtering for the MCP2515 CAN Controller using the ACAN2515 library. It shows how to set up acceptance masks and filters for both extended and standard CAN frames. The `begin` method is called with filter configurations, and `dispatchReceivedMessage` is used in the loop to handle incoming messages based on the defined filters. ```cpp ACAN2515Settings settings (QUARTZ_FREQUENCY, 125 * 1000) ; settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; const ACAN2515Mask rxm0 = extended2515Mask (0x1FFFFFFF) ; const ACAN2515Mask rxm1 = standard2515Mask (0x7F0, 0xFF, 0) ; const ACAN2515AcceptanceFilter filters [] = { {extended2515Filter (0x12345678), receive0}, {extended2515Filter (0x18765432), receive1}, {standard2515Filter (0x560, 0x55, 0), receive2} } ; const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }, rxm0, rxm1, filters, 3) ; void loop () { can.dispatchReceivedMessage () ; } ``` -------------------------------- ### Define CAN Messages with CANMessage Source: https://context7.com/pierremolinaro/acan2515/llms.txt Demonstrates how to construct standard and extended CAN frames, including remote frames and data access using the union members for flexible payload handling. ```cpp #include void sendMessages() { CANMessage stdFrame; stdFrame.id = 0x123; stdFrame.ext = false; stdFrame.rtr = false; stdFrame.len = 4; stdFrame.data[0] = 0xDE; stdFrame.data[1] = 0xAD; stdFrame.data[2] = 0xBE; stdFrame.data[3] = 0xEF; CANMessage extFrame; extFrame.id = 0x12345678; extFrame.ext = true; extFrame.rtr = false; extFrame.len = 8; extFrame.data64 = 0x0102030405060708ULL; CANMessage remoteFrame; remoteFrame.id = 0x200; remoteFrame.ext = false; remoteFrame.rtr = true; remoteFrame.len = 8; CANMessage dataFrame; dataFrame.id = 0x300; dataFrame.len = 8; dataFrame.data32[0] = 0x12345678; dataFrame.data32[1] = 0x9ABCDEF0; } ``` -------------------------------- ### Hardware Reception Filters Source: https://context7.com/pierremolinaro/acan2515/llms.txt Configures MCP2515 hardware acceptance masks and filters to route specific CAN messages to callback functions. ```APIDOC ## POST /can/filters ### Description Configures the MCP2515 hardware filters and masks. Messages matching these filters are automatically dispatched to the associated callback functions via `dispatchReceivedMessage()`. ### Method POST ### Endpoint /can/filters ### Parameters #### Request Body - **settings** (ACAN2515Settings) - Required - CAN bus timing and mode configuration. - **isr** (function) - Required - Interrupt service routine callback. - **rxm0** (ACAN2515Mask) - Required - Acceptance mask for filters 0-1. - **rxm1** (ACAN2515Mask) - Required - Acceptance mask for filters 2-5. - **filters** (Array) - Required - List of filter objects with associated callback functions. ### Request Example { "filters": [ {"filter": "0x12345678", "callback": "handleExtendedFrame"}, {"filter": "0x100", "callback": "handleEngineData"} ] } ### Response #### Success Response (200) - **errorCode** (uint16_t) - Returns 0 on success, non-zero on configuration error. ``` -------------------------------- ### MCP2515 Polling Mode Operation (C++) Source: https://context7.com/pierremolinaro/acan2515/llms.txt Illustrates how to operate the MCP2515 controller in polling mode, which is useful when hardware interrupts are not available or desired. The code demonstrates manual checking of transmit and receive operations using the `poll()` method. It initializes the controller in loopback mode for testing purposes and periodically sends and receives messages. ```cpp #include // No interrupt pin - use 255 to indicate polling mode ACAN2515 can(20, SPI, 255); static const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000; void setup() { Serial.begin(38400); while (!Serial) {} SPI.begin(); ACAN2515Settings settings(QUARTZ_FREQUENCY, 125 * 1000); settings.mRequestedMode = ACAN2515Settings::LoopBackMode; // Begin with NULL ISR for polling mode const uint32_t errorCode = can.begin(settings, NULL); if (errorCode == 0) { Serial.println("CAN initialized in polling mode"); } } void loop() { // CRITICAL: Call poll() frequently when not using interrupts can.poll(); static uint32_t lastSend = 0; if (millis() - lastSend >= 1000) { lastSend = millis(); CANMessage frame; frame.id = 0x100; frame.len = 2; frame.data16[0] = (uint16_t)(millis() / 1000); if (can.tryToSend(frame)) { Serial.println("Sent"); } } CANMessage received; if (can.receive(received)) { Serial.print("Received ID: 0x"); Serial.println(received.id, HEX); } } ``` -------------------------------- ### Arduino MCP2515 CAN Controller Message Sending and Receiving Source: https://github.com/pierremolinaro/acan2515/blob/master/README.md This Arduino sketch illustrates how to send and receive CAN messages using the ACAN2515 library in loopback mode. It includes logic to periodically send a CAN message with a specific ID and checks for incoming messages, incrementing counters for sent and received messages. The `tryToSend` method attempts to queue a message for transmission, and `receive` checks if a message is available. ```cpp static uint32_t gSendDate = 0 ; static uint32_t gSentCount = 0 ; static uint32_t gReceivedCount = 0 ; void loop () { CANMessage message ; if (gSendDate < millis ()) { message.id = 0x542 ; const bool ok = can.tryToSend (message) ; if (ok) { gSendDate += 2000 ; gSentCount += 1 ; Serial.print ("Sent: ") ; Serial.println (gSentCount) ; } } if (can.receive (message)) { gReceivedCount += 1 ; Serial.print ("Received: ") ; Serial.println (gReceivedCount) ; } } ``` -------------------------------- ### Bus Health Monitoring with Error Counters Source: https://context7.com/pierremolinaro/acan2515/llms.txt Explains how to use the library's methods to retrieve MCP2515 error counters (receive and transmit) and the error flag register. This is crucial for diagnosing CAN bus issues like noise or faulty nodes. The code is in C++ and uses the ACAN2515 library. ```cpp #include ACAN2515 can(10, SPI, 3); void checkBusHealth() { uint8_t rxErrors = can.receiveErrorCounter(); uint8_t txErrors = can.transmitErrorCounter(); uint8_t errorFlags = can.errorFlagRegister(); Serial.print("RX Errors: "); Serial.println(rxErrors); Serial.print("TX Errors: "); Serial.println(txErrors); Serial.print("Error Flags: 0x"); Serial.println(errorFlags, HEX); // Error counter thresholds: // 0-95: Normal operation // 96-127: Error warning // 128-255: Error passive / Bus off if (rxErrors > 96 || txErrors > 96) { Serial.println("WARNING: High error count detected!"); } if (txErrors >= 255) { Serial.println("CRITICAL: Bus off state!"); } } void loop() { static uint32_t lastCheck = 0; if (millis() - lastCheck >= 5000) { lastCheck = millis(); checkBusHealth(); } // Normal receive/transmit operations CANMessage frame; if (can.receive(frame)) { // Process frame } } ``` -------------------------------- ### Polling Mode Operation Source: https://context7.com/pierremolinaro/acan2515/llms.txt Manually checks for pending transmit and receive operations when hardware interrupts are not used. ```APIDOC ## GET /can/poll ### Description Manually polls the MCP2515 controller for pending CAN events. This must be called frequently in the main loop when operating without an interrupt pin. ### Method GET ### Endpoint /can/poll ### Response #### Success Response (200) - **status** (void) - Updates internal buffers for transmit and receive operations. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.