Canbus scanning

Hello everyone,

I have a project using the MCP2515 CAN bus module, and everything is working perfectly so far.

I am currently looking for a way to scan all the devices on the CAN bus network, similar to a network "ping." Is this possible to do?

Since I plan to connect over 40 MCP2515 modules with Arduino Nano V3 controllers, I need my main controller to scan the entire CAN bus network to detect which nodes are active and currently in use.

Thanks!

Is this an actual CAN bus, like possibly a car? Or the more involved SAE J1939 protocol that runs on can bus? (Like heavy equipment or a boat?)

I only pester you with this question because if it is J1939. There is a ping kinda' thing built in.

No, I use for the trains "0" Lionel.

Not an expert on the CAN bus, written a CAN sniffer a few months ago. It does not active ping the CAN bus, but it captures all messages on the bus and prints them. One could check if an ID has been seen before (e.g. with an array for the 40 ID's) to generate a list of "seen" devices.

Maybe this helps.

//
//    FILE: CAN_sniffer.ino
//  AUTHOR: Rob Tillaart
//    DATE: 2026-02-23
// PURPOSE: Sniffing for CAN packets
// WORKING: Connect MCP2515 to CAN bus and to SPI interface of UNO
//          messages are forwarded to Serial.
//
//  uses https://github.com/autowp/arduino-mcp2515
//
//  This software is provided "as is", without warranty of any kind, express or
//  implied, including but not limited to the warranties of merchantability,
//  fitness for a particular purpose and noninfringement. In no event shall the
//  authors or copyright holders be liable for any claim, damages or other
//  liability, whether in an action of contract, tort or otherwise, arising from,
//  out of or in connection with the software or the use or other dealings in the
//  software.
//


#define CAN_SNIFFER_VERSION           ("0.1.1")

#include "Arduino.h"
#include "SPI.h"
#include "mcp2515.h"

struct can_frame packet;

//  SPI PINS
//  SCK = 13
//   SO = 12
//   SI = 11
//   CS = 10
MCP2515 canbus(10);


uint32_t lastTime = 0;
uint32_t counter = 0;


////////////////////////////////////////////////////////
//
//  START OF CODE
//
void setup()
{
  //  print file and version number to know which code runs.
  Serial.begin(115200);
  Serial.println();
  Serial.println(__FILE__);
  Serial.print("CAN_SNIFFER_VERSION: ");
  Serial.println(CAN_SNIFFER_VERSION);
  Serial.println();

  SPI.begin();
  
  canbus.reset();
  canbus.setBitrate(CAN_500KBPS, MCP_8MHZ);
  canbus.setNormalMode();

  Serial.println();
  Serial.println();
  Serial.println("MILLIS\tCOUNT\tID\tLENGTH\tPACKET");
}

void loop()
{
  //  5 seconds no packets test
  uint32_t now = millis();
  if (now - lastTime >= 5000)
  {
    lastTime = now;
    Serial.print(millis());
    Serial.println("\tno packet");
  }

  //  detect CAN PACKET
  if (canbus.readMessage(&packet) == MCP2515::ERROR_OK)
  {
    //  print time stamp
    Serial.print(millis());
    Serial.print("\t");

    //  print recv counter
    Serial.print(counter);
    counter = counter + 1;
    Serial.print("\t");

    //  print packet ID
    Serial.print(packet.can_id);
    Serial.print("\t");

    //  print the bytes of the packet
    int length = packet.can_dlc;
    Serial.print(length);
    Serial.print("\t");
    for (int i = 0; i < length; i++)
    {
      if (packet.data[i] < 0x010) Serial.print("0");
      Serial.print(packet.data[i], HEX);
      Serial.print("  ");
    }
    Serial.println();
  }
}

//  -- END OF FILE --

I would say probably but it depends on the protocol. It is possible but if is not done properly it may cause problems.

Hello all!, I just got Ping worked with my own coded. thanks for inputs!!

Please share your code for future reference if possible.

Sorry!! here codes:

CONTROLLER:

#include <CAN.h>
int Received_CANBUS_ID;
int CANBUS_Scan_Enable = 1;
char CANBUS_Message_Char[8] = "        ";
String CANBUS_Message_String;
int Device_ID_Memory[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int m;

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
  }
  Serial.println("STARTING CANBUS INITIALIZE...");
  if (!CAN.begin(125E3)) {
    Serial.println("Starting CANBUS failed!");
    while (1)
      ;
  }
  Serial.println("CANBUS STARTED SUCCESSFUL.");
  Serial.println("CONTROLLER IS READY.");
}

void CANBUS_Read(int Expected_ID) {
  if (CAN.parsePacket()) {
    Received_CANBUS_ID = CAN.packetId();
    while (CAN.available()) {
      for (int i = 0; i <= 7; i++) {
        CANBUS_Message_Char[i] = (char)CAN.read();
      }
      if (Expected_ID == 0 || Expected_ID == Received_CANBUS_ID) {
        CANBUS_Message_String = CANBUS_Message_Char;
        if (CANBUS_Message_String.length() >= 9) {
          CANBUS_Message_String.remove(8, 100);
        }
        Serial.print("Received Data> ID:");
        Serial.print(Received_CANBUS_ID);
        Serial.print(" - Message:");
        Serial.println(CANBUS_Message_String);
      }
    }
  }
}


void CANBUS_Write(char Create_Message[8], int Create_ID) {
  CAN.beginPacket(Create_ID);
  for (int i = 0; i <= 7; i++) {
    CAN.write(Create_Message[i]);
  }
  CAN.endPacket();
  Serial.print("CANBUS Wrote> ID:");
  Serial.print(Create_ID);
  Serial.print(" - Message:");
  Serial.println(Create_Message);
}

void CANBUS_Scan() {
  m = 0;
  Serial.println("Started to scan devices...");
  for (int s = 1; s <= 255; s++) {
    CANBUS_Write("SENDPING", s);
    delay(75);
    CANBUS_Read(s);
    if (CANBUS_Message_String == "PINGBACK") {
      m++;
      Device_ID_Memory[m] = s;
      CANBUS_Message_String = "";
    }
  }
  Serial.println("");
  for (int b = 1; b <= m; b++) {
    Serial.print("ID:");
    Serial.print(int(Device_ID_Memory[b]));
    Serial.println(" Detected");
  }
  Serial.print("Total ");
  Serial.print(m);
  Serial.println(" devices found");
}



void loop() {
  if (CANBUS_Scan_Enable == 1) {
    CANBUS_Scan();
    CANBUS_Scan_Enable = 0;
  }
  CANBUS_Read(0);
  delay(100);
}

DEVICES:

#include <CAN.h>
int Received_CANBUS_ID;
char CANBUS_Message_Char[8] = "        ";
String CANBUS_Message_String;
int This_Device_ID = 10;

void setup() {
  pinMode(5, INPUT_PULLUP);
  Serial.begin(115200);
  while (!Serial)
    ;
  Serial.println("STARTING CANBUS INITIALIZE...");
  if (!CAN.begin(125E3)) {
    Serial.println("Starting CANBUS failed!");
    while (1)
      ;
  }
  Serial.println("CANBUS STARTED SUCCESSFUL.");
  Serial.println("");
}

void CANBUS_Read(int Expected_ID) {
  if (CAN.parsePacket()) {
    Received_CANBUS_ID = CAN.packetId();
    while (CAN.available()) {
      for (int i = 0; i <= 7; i++) {
        CANBUS_Message_Char[i] = (char)CAN.read();
      }
      if (Expected_ID == 0 || Expected_ID == Received_CANBUS_ID) {
        CANBUS_Message_String = CANBUS_Message_Char;
        if (CANBUS_Message_String.length() >= 9) {
          CANBUS_Message_String.remove(8, 100);
        }
        Serial.print("Received Data> ID:");
        Serial.print(Received_CANBUS_ID);
        Serial.print(" - Message:");
        Serial.println(CANBUS_Message_String);
      }
    }
  }
}

void CANBUS_Write(char Create_Message[8], int Create_ID) {
  CAN.beginPacket(Create_ID);
  for (int i = 0; i <= 7; i++) {
    CAN.write(Create_Message[i]);
  }
  CAN.endPacket();
  Serial.print("CANBUS Wrote> ID:");
  Serial.print(Create_ID);
  Serial.print(" - Message:");
  Serial.println(Create_Message);
}

void loop() {
  CANBUS_Read(This_Device_ID);
  if (CANBUS_Message_String == "SENDPING" && Received_CANBUS_ID == This_Device_ID) {
    CANBUS_Write("PINGBACK", This_Device_ID);
    delay(100);
  }

  if (digitalRead(5) == 0) {
    CANBUS_Write(" HELLO ", This_Device_ID);
  }
}

enjoy.

Thanks!