I'm basing it off of this board: https://www.longan-labs.cc/1030018.html
Which uses this library: https://github.com/Longan-Labs/Arduino_ ... ree/master
The code block below is the best effort of myself and ChatGPT. Can anyone check my work? I'm really out of my depth here:
Code: Select all
#include <SPI.h>
#include <mcp_canbus.h>
#define SPI_CS_PIN 17
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 250; // 0.25 seconds
const int maxChargePower = 50000; // 50kW in watts
const int targetVoltage = 400; // Target voltage in volts
const int maxVoltage = 398; // Maximum voltage in volts
const int minVoltage = 288; // Minimum voltage in volts
void setup() {
SPI.begin();
if (CAN.begin(CAN_500KBPS) == CAN_OK) {
Serial.begin(9600);
Serial.println("CAN init ok!");
} else {
Serial.println("CAN init fail");
while (1);
}
}
void loop() {
if (millis() - lastSendTime >= sendInterval) {
lastSendTime = millis();
// Receive voltage message
if (CAN_MSGAVAIL == CAN.checkReceive()) {
unsigned char len = 0;
unsigned char buf[8];
CAN.readMsgBuf(&len, buf);
unsigned long canId = CAN.getCanId();
if (canId == 0x522) {
int voltage = (buf[2] << 8) | buf[3]; // Voltage in millivolts
voltage /= 1000; // Convert to volts
// Calculate charge current request
int chargeCurrent = calculateChargeCurrent(voltage);
// Send charge current request
sendChargeCurrentRequest(chargeCurrent);
// Send target voltage
sendTargetVoltage(targetVoltage);
// Calculate and send SOC
int soc = calculateSOC(voltage);
sendSOC(soc);
}
}
}
}
int calculateChargeCurrent(int voltage) {
int chargePower;
if (voltage < 300) {
chargePower = 20000; // 20kW
} else if (voltage < 320) {
chargePower = 35000; // 35kW
} else if (voltage < 376) {
chargePower = maxChargePower; // 50kW
} else if (voltage < maxVoltage) {
chargePower = maxChargePower * (maxVoltage - voltage) / (maxVoltage - 376);
} else {
chargePower = 0;
}
return chargePower / voltage; // Current in amps
}
void sendChargeCurrentRequest(int chargeCurrent) {
unsigned char data[8] = {0};
data[0] = chargeCurrent & 0xFF;
data[1] = (chargeCurrent >> 8) & 0xFF;
CAN.sendMsgBuf(0x300, 0, 8, data);
}
void sendTargetVoltage(int targetVoltage) {
unsigned char data[8] = {0};
data[0] = targetVoltage & 0xFF;
data[1] = (targetVoltage >> 8) & 0xFF;
CAN.sendMsgBuf(0x301, 0, 8, data);
}
int calculateSOC(int voltage) {
return (voltage - minVoltage) * 100 / (maxVoltage - minVoltage);
}
void sendSOC(int soc) {
unsigned char data[8] = {0};
data[0] = soc & 0xFF;
data[1] = (soc >> 8) & 0xFF;
CAN.sendMsgBuf(0x301, 0, 8, data);
}