MKR CAN shield on MKR GSM 1400 - issue Tx CAN messages

Hi all

Recently dived into the Arduino world and hit a wall trying to run the MKR CAN shield on the MKR GSM 1400 board. There seems to be limited info and examples available for the MKR CAN shield, so I'm turning to you guys for help.

I've started with the Sandeep Mistry CAN library, installed through library manager, and tried to run one of the OBDII examples (EngineRPM).

I've tried the setup both on vehicle and on bench with CANape attached to verify Tx/Rx messaged. My MKR CAN shield does not seem to transmit anything on CAN though.

Checks completed:

  • CAN hi/lo from CAN shield to OBD connector continuity
  • CAN hi/lo both reading cte 2.5V from shield pin to shield GND
  • Modified CS and INT pin assignments in code to resp. 3 and 7, with INT pin attached as interrupt (see code).
  • Tried different clock speeds / SPI frequencies
  • However unlikely, tried supporting MKR GSM with 3.7V lipo in case current draw exceeded

Any thoughts why MKR CAN shield is apparently not sending any messages?

#include <CAN.h>
#include <MKRGSM.h>

const bool useStandardAddressing = true;

float rpm = 0;
int cs = 3;
int irq = 7;
int freq = 10E6;
int clockFrequency = 16E6;
bool incomingMSG = false;


void setup() {
  Serial.begin(9600);
  while (!Serial);

  attachInterrupt(digitalPinToInterrupt(7), readCAN, CHANGE);
  CAN.setPins(cs,irq);
  CAN.setSPIFrequency(freq);
  CAN.setClockFrequency(clockFrequency);
  
  Serial.println("CAN OBD-II engine RPM");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  else{
     Serial.println("CAN started");  
  }

   // CAN msg filtering
  if (useStandardAddressing) {
    CAN.filter(0x7e8);
  } else {
    CAN.filterExtended(0x18daf110);
  }
}

void loop() {
  if (useStandardAddressing) {
    CAN.beginPacket(0x7df, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // Mode 1
  CAN.write(0x0c); // engine RPM PID
  CAN.write(0); // 
  CAN.write(0); // 
  CAN.write(0); // 
  CAN.write(0); // 
  CAN.write(0); // 
  CAN.endPacket();
  
  Serial.println("Message sent");
    
  // Method 1: wait for response
  // while(CAN.parsePacket() == 0 ||
  //       CAN.read() < 3 ||          // correct length
  //       CAN.read() != 0x41 ||      // correct mode
  //       CAN.read() != 0x0c);       // correct PID

  // Method 2: look for INT
  if (incomingMSG) {
    Serial.println(CAN.read());
    rpm = ((CAN.read() * 256.0) + CAN.read()) / 4.0;

    Serial.print("Engine RPM = ");
    Serial.println(rpm);
    
    incomingMSG = false;
  }
  
  delay(5000);
}

void readCAN() {
  incomingMSG != incomingMSG;
  Serial.println("Incoming message");
}

Update

When sending packets with lots of 0's (e.g. HEX 80) at 5000 ms intervals, I do seem to pick up a Voltage delta between CAN HI/LO, but only 250 mV measured on multimeter. This is with on-board 120 Ohm resistor switch turned off. Similar order of magnitude with on-board resistor switch on.

Voltage delta between CAN HI/LO should be 2.5V to be picked up as a bit on the bus.

Update

Sketches I use for testing work with Leonardo + Seeed Studio CAN shield, with the only change moving the CS pin in line with CAN shield specs.

Issue seems to narrow down to MKR GSM 1400 and MKR CAN shield combination. Anyone tried this setup before?