Mega 2560 and MCP2515

Hi everyone !

I´m trying to use the MCP2515 with a new arduino mega 2560 with no success. The same pins and sketch runs on arduino UNO + MCP2515, but when I try to use the same ports and sketch the MCP2515 cannot be initialize.

The problem occurs on section of the code :

  // Initialize MCP2515 running at 8MHz with a baudrate of 500kb/s and the masks and filters disabled.

  if (CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK) 
    {
      Serial.println("MCP2515 Initialized Successfully!");
    }
  else 
    {
      Serial.println("Error Initializing MCP2515...");
      while (1);
    }

On the UNO + MCP2515 works and is initializated. On Mega + MCP2515 fails. I check more than 10 times if the connections are ok, and are exactly the same on both setups.

The full code is :

// Service 01 PIDs (more detail: https://en.wikipedia.org/wiki/OBD-II_PIDs)

#define PID_ENGINE_LOAD 0x04
#define PID_COOLANT_TEMP 0x05
#define PID_SHORT_TERM_FUEL_TRIM_1 0x06
#define PID_LONG_TERM_FUEL_TRIM_1 0x07
#define PID_SHORT_TERM_FUEL_TRIM_2 0x08
#define PID_LONG_TERM_FUEL_TRIM_2 0x09
#define PID_FUEL_PRESSURE 0x0A
#define PID_INTAKE_MAP 0x0B
#define PID_ENGINE_RPM  0x0C
#define PID_VEHICLE_SPEED 0x0D
#define PID_TIMING_ADVANCE 0x0E
#define PID_INTAKE_TEMP 0x0F
#define PID_MAF_FLOW 0x10
#define PID_THROTTLE 0x11
#define PID_AUX_INPUT 0x1E
#define PID_RUNTIME 0x1F
#define PID_DISTANCE_WITH_MIL 0x21
#define PID_COMMANDED_EGR 0x2C
#define PID_EGR_ERROR 0x2D
#define PID_COMMANDED_EVAPORATIVE_PURGE 0x2E
#define PID_FUEL_LEVEL 0x2F
#define PID_WARMS_UPS 0x30
#define PID_DISTANCE 0x31
#define PID_EVAP_SYS_VAPOR_PRESSURE 0x32
#define PID_BAROMETRIC 0x33
#define PID_CATALYST_TEMP_B1S1 0x3C
#define PID_CATALYST_TEMP_B2S1 0x3D
#define PID_CATALYST_TEMP_B1S2 0x3E
#define PID_CATALYST_TEMP_B2S2 0x3F
#define PID_CONTROL_MODULE_VOLTAGE 0x42
#define PID_ABSOLUTE_ENGINE_LOAD 0x43
#define PID_AIR_FUEL_EQUIV_RATIO 0x44
#define PID_RELATIVE_THROTTLE_POS 0x45
#define PID_AMBIENT_TEMP 0x46
#define PID_ABSOLUTE_THROTTLE_POS_B 0x47
#define PID_ABSOLUTE_THROTTLE_POS_C 0x48
#define PID_ACC_PEDAL_POS_D 0x49
#define PID_ACC_PEDAL_POS_E 0x4A
#define PID_ACC_PEDAL_POS_F 0x4B
#define PID_COMMANDED_THROTTLE_ACTUATOR 0x4C
#define PID_TIME_WITH_MIL 0x4D
#define PID_TIME_SINCE_CODES_CLEARED 0x4E
#define PID_ETHANOL_FUEL 0x52
#define PID_FUEL_RAIL_PRESSURE 0x59
#define PID_HYBRID_BATTERY_PERCENTAGE 0x5B
#define PID_ENGINE_OIL_TEMP 0x5C
#define PID_FUEL_INJECTION_TIMING 0x5D
#define PID_ENGINE_FUEL_RATE 0x5E
#define PID_ENGINE_TORQUE_DEMANDED 0x61
#define PID_ENGINE_TORQUE_PERCENTAGE 0x62
#define PID_ENGINE_REF_TORQUE 0x63

//----------------------------------------------

#define CAN_ID_PID 0x7DF //OBD-II CAN frame ID

#include <mcp_can.h>
#include <SPI.h>

#define CAN0_INT 2                             // Set INT to pin 2  <--------- CHANGE if using different pin number
MCP_CAN CAN0(10);                               // Set CS to pin 10 <--------- CHANGE if using different pin number

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128];                        // Array to store serial string

void setup()

  {
  
  Serial.begin(9600);

  // Initialize MCP2515 running at 8MHz with a baudrate of 500kb/s and the masks and filters disabled.

  if (CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK) 
    {
      Serial.println("MCP2515 Initialized Successfully!");
    }
  else 
    {
      Serial.println("Error Initializing MCP2515...");
      while (1);
    }

  //initialise mask and filter to allow only receipt of 0x7xx CAN IDs

  CAN0.init_Mask(0, 0, 0x07E00000);              // Init first mask...
  CAN0.init_Mask(1, 0, 0x07E00000);              // Init second mask...
 
  for (uint8_t i = 0; i < 6; ++i) 
    {
    CAN0.init_Filt(i, 0, 0x07E00000);           //Init filters
    }

  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.

  pinMode(CAN0_INT, INPUT);                    // Configuring pin for /INT input

  Serial.println("Sending and Receiving OBD-II_PIDs Example...");

}

void loop()

  {

  //request throttle %
  sendPID(PID_THROTTLE);
  receivePID(PID_THROTTLE);

  // request throttle actuator %
  sendPID(PID_COMMANDED_THROTTLE_ACTUATOR);
  receivePID(PID_COMMANDED_THROTTLE_ACTUATOR);

  //request engine speed rpm
  sendPID (PID_ENGINE_RPM);
  receivePID(PID_ENGINE_RPM);

  //request timing advance 
  sendPID (PID_TIMING_ADVANCE);
  receivePID(PID_TIMING_ADVANCE);

  //request vehicle speed 
  sendPID (PID_VEHICLE_SPEED);
  receivePID(PID_VEHICLE_SPEED);

  }

void sendPID(unsigned char __pid)
  
  {
  
  unsigned char tmp[8] = {0x02, 0x01, __pid, 0, 0, 0, 0, 0};

  byte sndStat = CAN0.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);

  if (sndStat == CAN_OK) 
    {
      Serial.print("PID sent: 0x");
      Serial.println(__pid, HEX);
    }
  else 
    {
      Serial.println("Error Sending Message...");
    }

}

void receivePID(unsigned char __pid)

{
    int vResultI = 0;
    double vResultD = 0;

    if (!digitalRead(CAN0_INT)) 

      {

        CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

        if (rxId == 0x7E8)

          {

            sprintf(msgString, "Received -> Standard ID: 0x%.3lX, DLC: %1d, Data: ", rxId, len);
            Serial.print(msgString);

            for (byte i = 0; i < len; i++)
              {
                sprintf(msgString, " 0x%.2X", rxBuf[i]);
                Serial.print(msgString);
              }
  
            Serial.println("");

            switch (__pid) 
              {
                case PID_THROTTLE:
                  if(rxBuf[2] == PID_THROTTLE)
                    {
                      vResultD = double(100.0 / 255.0) * rxBuf[3];
                      vResultI = vResultD;
                      Serial.print("Posição de TPS (%): ");
                      Serial.println(vResultI);
                    }
                  break;
                case PID_COMMANDED_THROTTLE_ACTUATOR:
                  if(rxBuf[2] == PID_COMMANDED_THROTTLE_ACTUATOR)
                    {
                      vResultD = double(100.0 / 255.0) * rxBuf[3];
                      vResultI = vResultD;
                      Serial.print("Posição do atuador do acelerador (%): ");
                      Serial.println(vResultI);
                    }
                  break;
                case PID_ENGINE_RPM:
                  if(rxBuf[2] == PID_ENGINE_RPM)
                    {
                      vResultI = ((256 * rxBuf[3]) + rxBuf[4]) / 4;
                      Serial.print("RPM : ");
                      Serial.println(vResultI, DEC);
                    }
                  break;
                case PID_TIMING_ADVANCE:
                  if(rxBuf[2] == PID_TIMING_ADVANCE)
                    {
                      vResultD = (double(rxBuf[3]) / 2.0) - 64.0;
                      vResultI = vResultD;
                      Serial.print("Avanço da ignição : ");
                      Serial.println(vResultI, DEC);
                    }
                  break;
                case PID_VEHICLE_SPEED:
                  if(rxBuf[2] == PID_VEHICLE_SPEED)
                    {
                      vResultD = rxBuf[3];
                      vResultI = vResultD;
                      Serial.print("Velocidade KM/H : ");
                      Serial.println(vResultI, DEC);
                    }
                 break;
            }

          }
      }

}

Somebody knows what I´m doing wrong ?

Thanks !

1 Like

Check out the code example:
CAN Bus Programming With Arduino Uno, Mega 2560 - Copperhill (copperhilltech.com)

also of interest:
Mega2560 w/ MCP2515 SPI module, filters and masks need to be cleared on setup · Issue #229 · ttlappalainen/NMEA2000 · GitHub

Sorry guys... forgot to put the ports I´m using !

INT -> 2
CS -> 10
SI -> 11
SO -> 12
SCK -> 13

Check the Mega SPI pin numbers. They are not the same as the Uno

You are correct ! Working correctly now.

PORT UNO MEGA
---- --- ----
MOSI  11   51
MISO  12   50
SCK   13   52
SS    10   53

Thanks very much !

I am glad you got it working

Remember, if all else fails RTFM :grinning:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.