add temp calc

This commit is contained in:
Lene Marquardt 2025-03-26 15:50:46 +01:00
parent 583b4059aa
commit 93e36a9738
2 changed files with 22 additions and 185 deletions

View File

@ -348,190 +348,5 @@ HAL_StatusTypeDef amsReadCellVoltages(Cell_Module (*module)[N_BMS]) {
(*module)[i].cellVoltages[15] = mV_from_ADBMS6830(rxbuffer[offset + 0] | (rxbuffer[offset + 1] << 8));
}
return HAL_OK;
}
// Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i]
// bytes long
HAL_StatusTypeDef amsSendI2C(const uint8_t addresses[static N_BMS], uint8_t* data[static N_BMS],
const uint8_t datalens[static N_BMS], uint32_t bms_mask) {
uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {};
// COMM register works in 3 bytes max per go, interleaved with control information
uint8_t max_datalen = 0;
for (size_t i = 0; i < N_BMS; i++) {
if (datalens[i] > max_datalen) {
max_datalen = datalens[i];
}
}
for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << i))) {
buffer[offset + 0] = I2C_SEND_NOTRANSFER;
buffer[offset + 2] = I2C_SEND_NOTRANSFER;
buffer[offset + 4] = I2C_SEND_NOTRANSFER;
continue;
}
}
size_t packet_count =
((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0); // number of 3 byte packets needed to send all data
for (size_t i = 0; i < (packet_count * 3); i++) { //i - 1 is the number of data bytes sent so far (1 byte for the address)
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
if (i == 0) {
buffer[offset + 0] = I2C_SEND_START;
buffer[offset + 1] = addresses[j] << 1; // shift the address left by 1 to make space for the R/W bit
continue;
}
// add data to the buffer
// case 1: the last group of 3 bytes contained the last data byte, so we need to send a stop
if (datalens[j] - (int)i == -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_STOP;
continue;
}
// case 2: we are more than one byte past the end, so we don't need to send any data
if (datalens[j] - (int)i < -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_NOTRANSFER;
continue;
}
// case 3: we are still sending data
buffer[offset + ((i % 3) * 2)] = I2C_SEND;
buffer[offset + ((i % 3) * 2) + 1] = data[j][i - 1];
}
// send the data
if (i % 3 == 0 && i != 0) {
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72); // wait 72 cycles for the I2C transfer to complete (datasheet page 43)
// TODO: not sure if this is correct for a daisy chain
}
}
// send the last packet
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72);
return HAL_OK;
}
// Each selected BMS must have a corresponding address, and the data array for that BMS must be at least datalens[i]
// bytes long
HAL_StatusTypeDef amsReadI2C(const uint8_t addresses[static N_BMS], uint8_t* data[static N_BMS],
const uint8_t datalens[static N_BMS], uint32_t bms_mask) {
uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {};
uint8_t max_datalen = 0;
for (size_t i = 0; i < N_BMS; i++) {
if (datalens[i] > max_datalen) {
max_datalen = datalens[i];
}
}
for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << i))) {
buffer[offset + 0] = I2C_SEND_NOTRANSFER;
buffer[offset + 2] = I2C_SEND_NOTRANSFER;
buffer[offset + 4] = I2C_SEND_NOTRANSFER;
continue;
}
}
size_t packet_count = ((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0);
for (size_t i = 0; i < (packet_count * 3);
i++) { // i - 1 is the number of data bytes sent so far (1 byte for the address)
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
if (i == 0) {
buffer[offset + 0] = I2C_SEND_START;
buffer[offset + 1] = addresses[j] << 1 | 0x01; // shift the address left by 1 to make space for the R/W bit
continue;
}
// add data to the buffer
// case 1: the last group of 3 bytes contained the last data byte, so we need to send a stop
if (datalens[j] - (int)i == -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_STOP;
continue;
}
// case 2: we are more than one byte past the end, so we don't need to receive any data
if (datalens[j] - (int)i < -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_NOTRANSFER;
continue;
}
// case 3: we are still receiving data
buffer[offset + ((i % 3) * 2)] = I2C_SEND_ACK;
}
// send the command data
if (i % 3 == 0 && i != 0) {
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72); // wait 72 cycles for the I2C transfer to complete (datasheet page 43)
// TODO: not sure if this is correct for a daisy chain
// read the data
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
for (size_t k = 0; k < 3; k++) {
if (datalens[j] - (int)i < -1) {
continue;
}
data[j][i - 1 + k] = buffer[offset + (k * 2) + 1];
}
}
}
}
// send the last packet
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72);
// read the data
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
for (size_t k = 0; k < 3; k++) {
if (datalens[j] - (int)max_datalen < -1) {
continue;
}
data[j][max_datalen - 1 + k] = buffer[offset + (k * 2) + 1];
}
}
return HAL_OK;
}

View File

@ -0,0 +1,22 @@
// calculate Temperature for NTCLE413 Temperature Sensors
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define R0 10000 //Ohm
#define BETA 3435 //Kelvin
#define T0 298.15 //Kelvin
float calcTemp(int16_t vref2, int16_t adcVoltage){
float r_ntc = R0/((vref2/adcVoltage)-1);
float temp = r_ntc / R0; // (R/Ro)
temp = logf(temp); // ln(R/Ro)
temp /= BETA; // 1/B * ln(R/Ro)
temp += 1.0 / (T0 + 273.15); // + (1/To)
temp = 1.0 / temp; // Invert
temp -= 273.15; // convert to °C
return temp;
}