mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
Receiving SOC, SOH and Product name
This commit is contained in:
parent
024cc0b9b6
commit
f14f86f6fe
@ -1765,7 +1765,8 @@ void GpioInit(void)
|
||||
ValidSpiPinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too
|
||||
ValidSpiPinUsed(GPIO_ST7789_CS) ||
|
||||
(ValidSpiPinUsed(GPIO_SSD1331_CS) && ValidSpiPinUsed(GPIO_SSD1331_DC)) ||
|
||||
ValidSpiPinUsed(GPIO_SDCARD_CS)
|
||||
ValidSpiPinUsed(GPIO_SDCARD_CS) ||
|
||||
ValidSpiPinUsed(GPIO_MCP2515_CS)
|
||||
);
|
||||
// If SPI_CS and/or SPI_DC is used they must be valid
|
||||
TasmotaGlobal.spi_enabled = (valid_cs) ? SPI_MOSI_MISO : SPI_NONE;
|
||||
|
@ -158,7 +158,7 @@ enum UserSelectablePins {
|
||||
GPIO_MAX7219CLK, GPIO_MAX7219DIN, GPIO_MAX7219CS, // MAX7219 interface
|
||||
GPIO_TFMINIPLUS_TX, GPIO_TFMINIPLUS_RX, // TFmini Plus ToF sensor
|
||||
GPIO_ZEROCROSS,
|
||||
GPIO_MCP2515_CS, // MCP2515 Chip Select
|
||||
GPIO_MCP2515_CS, // MCP2515 Chip Select
|
||||
#ifdef ESP32
|
||||
GPIO_HALLEFFECT,
|
||||
GPIO_EPD_DATA, // Base connection EPD driver
|
||||
@ -462,7 +462,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||
AGPIO(GPIO_SDCARD_CS),
|
||||
#endif // USE_SDCARD
|
||||
#ifdef USE_MCP2515
|
||||
AGPIO(GPIO_MCP2515_CS)
|
||||
AGPIO(GPIO_MCP2515_CS),
|
||||
#endif // USE_MCP2515
|
||||
#endif // USE_SPI
|
||||
|
||||
|
@ -47,8 +47,8 @@
|
||||
#define MCP2515_CLOCK MCP_8MHZ
|
||||
#endif
|
||||
|
||||
#ifndef MCP2515_MAX_MSG
|
||||
#define MCP2515_MAX_MSG 14
|
||||
#ifndef MCP2515_MAX_FRAMES
|
||||
#define MCP2515_MAX_FRAMES 14
|
||||
#endif
|
||||
|
||||
#ifndef MCP2515_BMS_CLIENT
|
||||
@ -60,11 +60,11 @@
|
||||
#endif // MCP2515_BMS_CLIENT
|
||||
|
||||
#ifdef MCP2515_BMS_CLIENT
|
||||
struct BMS_Struct {
|
||||
struct BMS_Struct {
|
||||
uint16_t stateOfCharge;
|
||||
uint16_t stateOfHealth;
|
||||
float battVoltage;
|
||||
float battMilliAmp;
|
||||
float battAmp = 0;
|
||||
float battTemp;
|
||||
char name[17];
|
||||
} bms;
|
||||
@ -72,66 +72,110 @@
|
||||
|
||||
int8_t mcp2515_init_status = 1;
|
||||
|
||||
struct can_frame canMsg;
|
||||
MCP2515 mcp2515;
|
||||
struct can_frame canFrame;
|
||||
MCP2515 *mcp2515 = nullptr;
|
||||
|
||||
char c2h(char c)
|
||||
{
|
||||
return "0123456789ABCDEF"[0x0F & (unsigned char)c];
|
||||
}
|
||||
|
||||
void MCP2515_Init(void) {
|
||||
mcp2515 = new MCP2515(5);
|
||||
if (MCP2515::ERROR_OK != mcp2515.reset()) {
|
||||
if (MCP2515::ERROR_OK != mcp2515->reset()) {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("MCP2515: Failed to reset module"));
|
||||
mcp2515_init_status = 0;
|
||||
}
|
||||
|
||||
if (MCP2515::ERROR_OK != mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ)) {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("MCP2515: Failed to set module bitrate");
|
||||
if (MCP2515::ERROR_OK != mcp2515->setBitrate(MCP2515_BITRATE, MCP2515_CLOCK)) {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("MCP2515: Failed to set module bitrate"));
|
||||
mcp2515_init_status = 0;
|
||||
}
|
||||
|
||||
if (mcp2515_init_status && MCP2515::ERROR_OK != mcp2515.setNormalMode()) {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("MCP2515: Failed to set normal mode");
|
||||
if (mcp2515_init_status && MCP2515::ERROR_OK != mcp2515->setNormalMode()) {
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("MCP2515: Failed to set normal mode"));
|
||||
mcp2515_init_status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MCP2515_Read() {
|
||||
uint8_t nCounter = 0;
|
||||
while (mcp2515.checkReceive() && nCounter <= MCP2515_MAX_MSG) {
|
||||
nCounter++;
|
||||
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
|
||||
bool checkRcv;
|
||||
if(mcp2515_init_status) {
|
||||
|
||||
checkRcv = mcp2515->checkReceive();
|
||||
|
||||
while (checkRcv && nCounter <= MCP2515_MAX_FRAMES) {
|
||||
mcp2515->checkReceive();
|
||||
nCounter++;
|
||||
if (mcp2515->readMessage(&canFrame) == MCP2515::ERROR_OK) {
|
||||
#ifdef MCP2515_BMS_CLIENT
|
||||
#ifdef MCP2515_BMS_FREEDWON
|
||||
switch(canMsg.can_id) {
|
||||
case 0x355:
|
||||
bms.stateOfCharge = canMsg.data[1] << 8 + canMsg.data[0];
|
||||
bms.stateOfHealth = canMsg.data[3] << 8 + canMsg.data[2];
|
||||
break;
|
||||
case 0x356:
|
||||
bms.battVoltage = (canMsg.data[1] << 8 + canMsg.data[0])/100;
|
||||
bms.battMilliAmp = (canMsg.data[3] << 8 + canMsg.data[2])*100;
|
||||
bms.battTemp = ConvertTemp((canMsg.data[5] << 8 + canMsg.data[4])/10); // Convert to fahrenheit if SetOpion8 is set
|
||||
break;
|
||||
case 0x370:
|
||||
case 0x371:
|
||||
for(int i = 0; i < canMsg.can_dlc; i++) {
|
||||
bms.name[i + (8 * canMsg.can_id & 0x1)] = canMsg.data[i]; // If can_id is 0x371 then fill from byte 8 onwards
|
||||
}
|
||||
bms.name[16] = 0; // Ensure that name is null terminated
|
||||
break;
|
||||
default:
|
||||
String canMsg;
|
||||
for(int i = 0; i < canMsg.can_dlc; i++) {
|
||||
canMsg += String(canMsg.data[i], HEX);
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Received message 0x%s from ID 0x%X", canMsg, canMsg.can_id);
|
||||
break;
|
||||
}
|
||||
switch(canFrame.can_id) {
|
||||
// Charge/Discharge parameters
|
||||
case 0x351:
|
||||
break;
|
||||
// State of Charge/Health
|
||||
case 0x355:
|
||||
if(6 >= canFrame.can_dlc) {
|
||||
bms.stateOfCharge = (canFrame.data[1] << 8) + canFrame.data[0];
|
||||
bms.stateOfHealth = (canFrame.data[3] << 8) + canFrame.data[2];
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Unexpected length (%d) for ID 0x355"), canFrame.can_dlc);
|
||||
}
|
||||
break;
|
||||
// Voltage/Current/Temperature
|
||||
case 0x356:
|
||||
if(6 >= canFrame.can_dlc) {
|
||||
bms.battVoltage = (float)((canFrame.data[1] << 8) + canFrame.data[0])/100;
|
||||
bms.battAmp = (float)((canFrame.data[3] << 8) + canFrame.data[2])/10;
|
||||
bms.battTemp = ConvertTemp((float)((canFrame.data[5] << 8) + canFrame.data[4])/10); // Convert to fahrenheit if SetOpion8 is set
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Unexpected length (%d) for ID 0x356"), canFrame.can_dlc);
|
||||
}
|
||||
break;
|
||||
// Battery / BMS name
|
||||
case 0x370:
|
||||
case 0x371:
|
||||
for(int i = 0; i < canFrame.can_dlc; i++) {
|
||||
uint8_t nameStrPos = i + ((canFrame.can_id & 0x1) * 8); // If can_id is 0x371 then fill from byte 8 onwards
|
||||
bms.name[nameStrPos] = canFrame.data[i];
|
||||
}
|
||||
bms.name[16] = 0; // Ensure that name is null terminated
|
||||
break;
|
||||
// Modules status
|
||||
case 0x372:
|
||||
// Min. cell voltage id string
|
||||
case 0x374:
|
||||
// Min. cell temperature id string
|
||||
case 0x376:
|
||||
// Installed capacity
|
||||
case 0x379:
|
||||
// Serial number
|
||||
case 0x380:
|
||||
case 0x381:
|
||||
break;
|
||||
default:
|
||||
char canMsg[17];
|
||||
canMsg[0] = 0;
|
||||
for(int i = 0; i < canFrame.can_dlc; i++) {
|
||||
canMsg[i*2] = c2h(canFrame.data[i]>>4);
|
||||
canMsg[i*2+1] = c2h(canFrame.data[i]);
|
||||
}
|
||||
if(canFrame.can_dlc > 0) {
|
||||
canMsg[(canFrame.can_dlc - 1) * 2 + 2] = 0;
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Received message 0x%s from ID 0x%X"), canMsg, (uint32_t)canFrame.can_id);
|
||||
break;
|
||||
}
|
||||
#endif // MCP2515_BMS_FREEDWON
|
||||
#endif // MCP2515_BMS_CLIENT
|
||||
} else if(mcp2515.checkError()) {
|
||||
uint8_t errFlags = mcp2515.getErrorFlags();
|
||||
mcp2515.clearRXnOVRFlags();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Received error %d", errFlags);
|
||||
break;
|
||||
} else if(mcp2515->checkError()) {
|
||||
uint8_t errFlags = mcp2515->getErrorFlags();
|
||||
mcp2515->clearRXnOVRFlags();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP2515: Received error %d"), errFlags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,10 +189,12 @@ void MCP2515_Show(bool Json) {
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
#ifdef MCP2515_BMS_CLIENT
|
||||
char ampStr[6];
|
||||
dtostrf(bms.battAmp, 5, 1, ampStr);
|
||||
WSContentSend_PD(HTTP_SNS_SOC, bms.name, bms.stateOfCharge);
|
||||
WSContentSend_PD(HTTP_SNS_SOH, bms.name, bms.stateOfHealth);
|
||||
WSContentSend_Voltage(bms.name, bms.battVoltage);
|
||||
WSContentSend_CurrentMA(bms.name, bms.battMilliAmp);
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, ampStr);
|
||||
WSContentSend_Temp(bms.name, bms.battTemp);
|
||||
#endif // MCP2515_BMS_CLIENT
|
||||
#endif // USE_WEBSERVER
|
||||
@ -168,7 +214,7 @@ bool Xsns89(uint8_t function)
|
||||
case FUNC_INIT:
|
||||
MCP2515_Init();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
MCP2515_Read();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
|
Loading…
x
Reference in New Issue
Block a user