MCP2515 + SNHVD230 RX works TX not

mr0wl@sixweb.hu
Posts: 1
Joined: Fri Jul 18, 2025 8:59 am

MCP2515 + SNHVD230 RX works TX not

Postby mr0wl@sixweb.hu » Fri Jul 18, 2025 2:29 pm

Hello All,
I designed a board to use 2 can buses with ESP32-D0WDQ6-V3 (revision v3.0). One of the can buses use the builtin TJA1000 + SN65HVD230 chip (this post is not about that part) and the other uses an MCP2515 + SN65HVD230. The reason for this (maybe unusual) setup is that I could have only one voltage rail (3.3V) as all components work with that. The wiring diagram looks like this:
1.png
1.png (258.04 KiB) Viewed 96 times
As I'm a bit more familiar to TJA1000, I started working on the other part. I use Cory J Fowler's mcp_can library that work excellent with my old Arduino projects. The first part went pretty well, I can see the messages of the CAN bus. The problem is that I cannot send messages, the TX part does not work at all.
My code, first is the main .ino

Code: Select all

#ifdef ESP32
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include "mycan.h"


void setup() {

  Serial.begin(115200);

  if(!initCan()){
    DPRINTLN0(F("Error CAN"));
  }

  dispTime = millis();

} // setup()

void loop() {
   if((dispTime + 500) < millis()) {
     canByteLS(0x10AC0097,8, 0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00);
     dispTime = millis();
   }
   readCANLS();
}

#endif // ifdef ESP32
And the mycan.h:

Code: Select all

#ifndef MYCAN_HEADER_H
#define MYCAN_HEADER_H

#define CANLS_INT 16 // GPIO16
#define CANLS_CS 5 // GPIO5 = VSPI CS0

// CAN bus
MCP_CAN               CANLS(CANLS_CS);
long unsigned int     rxId;
uint8_t               len = 0;
uint8_t               rxBuf[8];
uint8_t               txBuf[8];
bool                  canSilence = 1;
char                  msgString[128];

// Basic functions
uint32_t              dispTime; // timer

bool initCan() {

// Slope control
  pinMode(27, OUTPUT);
  digitalWrite(27, LOW);

#ifdef CANLS_INT
  // CAN_33K3BPS
  if(!CANLS.begin(MCP_ANY, CAN_33K3BPS, MCP_8MHZ) == CAN_OK) {
      Serial.print("FAIL");
      return 0;
  }

  CANLS.setMode(MCP_NORMAL);
  pinMode(CANLS_INT, INPUT);
#endif

  return 1;
}

bool canByteLS(long int id, byte len, byte a, byte b, byte c, byte d, byte e, byte f, byte g, byte h) {
#if defined(CANLS_INT)
  bool ext = 0;
  txBuf[0]=a; txBuf[1]=b; txBuf[2]=c; txBuf[3]=d; txBuf[4]=e; txBuf[5]=f; txBuf[6]=g; txBuf[7]=h;
  if(id > 0x7FF) ext = 1;
  byte sndStat = CANLS.sendMsgBuf(id, ext, len, txBuf);
  Serial.println(sndStat);
  return sndStat; // 1 if NOK
#endif
  return 0;
}

void readCANLS() {
  if(!digitalRead(CANLS_INT)) {
    if(canSilence == 1){
        canSilence = 0;
    }
    CANLS.readMsgBuf(&rxId, &len, rxBuf);

	sprintf(msgString, "LS %lu 0x%.3lX %1d ", millis(), (rxId & 0x1FFFFFFF), len);
	Serial.print(msgString);
	for(byte i = 0; i < len; i++){
	  sprintf(msgString, " 0x%.2X", rxBuf[i]);
	  Serial.print(msgString);
	}
	Serial.println();
  }
}

#endif
As you can see, I don't even include other libraries to prevent any collision.
Since the mcp_can library works for people, I'm suspecting a hardware design failure. Especially the slope control; I verified that the Rs pin is pulled down to GND, in the code I set GPIO27 to low. The connectivity of all other pins are OK and Vcc and GND has the correct voltage levels.

The SendMsgBuf() returns back with 7 (CAN_SENDMSGTIMEOUT) a couple of times, then 6 (CAN_GETTXBFTIMEOUT) as the outbut buffer expires.

I removed R8 so the Rs pins must be on GND level, but nothing changed.

How come that the RX works and TX not? I only designed boards with two voltage rails (3.3V for micro and 5V for CAN) so far, but jumping between the voltage levels was always inconvenient, I thought 3.3V should be enough to comply with ISO 11898-2? Am I miss something?

Thanks,

Who is online

Users browsing this forum: Amazon [Bot], Qwantbot and 3 guests