**hey please help me **
i am work/using JBD BMS
I’m trying to collect data (total voltage, current, remaining capacity) from a BMS using an ESP32 and an MCP2515 CAN module over CANBUS, but I’m not getting consistent data. I’m following the BMS’s CANBUS protocol and using the mcp_can library. Any help debugging this would be greatly appreciated!
#include <SPI.h>
#include <mcp_can.h>
#define CAN_CS 5 // Chip Select pin (connect to ESP32 GPIO5)
MCP_CAN CAN(CAN_CS); // Create CAN object
// CRC-16 MODBUS check (polynomial 0xA001)
uint16_t crc16_modbus(const uint8_t *data, uint8_t len) {
uint16_t crc = 0xFFFF;
for (uint8_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc >>= 1;
}
}
return crc;
}
void setup() {
Serial.begin(115200);
delay(1000);
// Try initializing CAN
if (CAN.begin(MCP_ANY, 500000, MCP_8MHZ) == CAN_OK) {
Serial.println("CAN BUS Initialized Successfully");
} else {
Serial.println("CAN BUS Init Failed. Check wiring or crystal frequency!");
while (1); // Stop program here
}
CAN.setMode(MCP_NORMAL); // Set to normal CAN mode
delay(100);
sendRemoteRequest(0x100, 8); // Request Total Voltage, Current, Capacity
}
void loop() {
long unsigned int rxId;
byte len = 0;
byte buf[8];
if (CAN.checkReceive() == CAN_MSGAVAIL) {
if (CAN.readMsgBuf(&rxId, &len, buf) == CAN_OK) {
if (rxId == 0x100 && len == 8) {
Serial.print("Received from ID: 0x");
Serial.print(rxId, HEX);
Serial.print(" Data: ");
for (byte i = 0; i < len; i++) {
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println();
// CRC check (NOTE: CRC is LSB first in protocol)
uint16_t receivedCRC = (buf[6]) | (buf[7] << 8); // Little-endian
uint16_t calculatedCRC = crc16_modbus(buf, 6);
if (receivedCRC != calculatedCRC) {
Serial.println("CRC mismatch! Data invalid.");
return;
}
// Extract and convert values
uint16_t voltage_raw = (buf[0] << 8) | buf[1]; // 10mV units
int16_t current_raw = (buf[2] << 8) | buf[3]; // 10mA units, signed
uint16_t capacity_raw = (buf[4] << 8) | buf[5]; // 10mAh units
float voltage = voltage_raw / 100.0; // → Volts
float current = current_raw / 100.0; // → Amps
float capacity = capacity_raw / 100.0; // → Ah
// Display parsed values
Serial.print("Total Voltage: ");
Serial.print(voltage, 2);
Serial.println(" V");
Serial.print("Current: ");
Serial.print(current, 2);
Serial.println(" A");
Serial.print("Remaining Capacity: ");
Serial.print(capacity, 2);
Serial.println(" Ah");
delay(500); // Wait before requesting again
sendRemoteRequest(0x100, 8);
}
}
}
}
// Function to send a remote request frame
void sendRemoteRequest(uint16_t can_id, uint8_t dlc) {
byte dummyData[0]; // Remote frame has no data
if (CAN.sendMsgBuf(can_id, 0, dlc | 0x40, dummyData) == CAN_OK) {
Serial.print("Remote frame sent to 0x");
Serial.println(can_id, HEX);
} else {
Serial.println("Failed to send remote frame");
}
}
Hardware:
- Board: ESP32 Dev Module ([SPECIFY IF DIFFERENT, e.g., DOIT ESP32 DEVKIT V1])
- CAN Module: MCP2515 (with TJA1050 transceiver, 8 MHz crystal)
- BMS: [SPECIFY BMS MODEL, e.g., JBD 4S 100A or generic BMS]
- Wiring:
- ESP32 GPIO5 to MCP2515 CS
- ESP32 SCK (GPIO18) to MCP2515 SCK
- ESP32 MOSI (GPIO23) to MCP2515 SI
- ESP32 MISO (GPIO19) to MCP2515 SO
- ESP32 3.3V to MCP2515 VCC
- Common GND between ESP32, MCP2515, and BMS
- MCP2515 CANH/CANL to BMS CANH/CANL
- BMS powered by JBD 24V 4S LiFePO4 battery pack
- components: 120Ω termination resistor
Issue:
- The Serial Monitor shows [DESCRIBE PROBLEM, e.g., “no data received at all”, “random hex values that don’t make sense”, “CRC mismatch errors every time”, or “voltage reads 0V”].
- Expected behavior: I want to reliably read total voltage, current, and remaining capacity from ID 0x100 every 500ms, as per the BMS protocol (6 data bytes + 2 CRC bytes, high byte first for data, little-endian for CRC).
- The ESP32 and MCP2515 work for a simple CAN loopback test, but not with the BMS.
What I’ve Tried:
- Verified wiring with a multimeter for continuity between ESP32, MCP2515, and BMS.
- Confirmed MCP2515 crystal is 8 MHz, matching the code.
- Added a 120Ω termination resistor between CANH and CANL (or confirmed BMS has one built-in, [SPECIFY WHICH]).
- Tested with different CAN IDs (e.g., 0x101) to check if the BMS responds to other frames.
- Searched the forum for “ESP32 MCP2515 BMS CANBUS” but didn’t find a matching issue.
- Checked BMS manual, which specifies CAN2.0B, 500 kHz baud rate, and 11-bit IDs with CRC-16 (0xA001 polynomial).
