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: 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 ESP32Code: 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();
}
}
#endifSince 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,