Skip to content

Commit

Permalink
adds temp cells code and small dash changes, forgot to commit
Browse files Browse the repository at this point in the history
  • Loading branch information
PedroRomao3 committed Jan 23, 2025
1 parent b33a845 commit c75f8fa
Show file tree
Hide file tree
Showing 12 changed files with 356 additions and 66 deletions.
Binary file not shown.
47 changes: 47 additions & 0 deletions teensy_cells/include/temp_header.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

#include <FlexCAN_T4.h>
#include "Arduino.h"

#define TOTAL_BOARDS 6
#define DELAY_INTERVAL 500
#define N_NTC 18
#define VDD 5.0
#define RESISTOR_PULLUP 10000.0
#define RESISTOR_NTC_REFERNCE 10000.0 // Resistência a 25°C do NTC
#define TEMPERATURE_DEFAULT_C 25.0
#define TEMPERATURE_DEFAULT_K 298.15
#define NTC_BETA 3971.0
#define MAXIMUM_TEMPERATURE 60.0
#define MASTER_CELL_ID 0x109
#define CELLS_PER_MESSAGE 6
#define CELL_TEMPS_BASE_ID 0x110
#define CAN_BAUD_RATE 500000
#define THERMISTOR_MODULE_NUMBER 0x00
#define NUMBER_OF_THERMISTORS 0x01
#define HIGHEST_THERMISTOR_ID 0x01
#define LOWEST_THERMISTOR_ID 0x00
#define CHECKSUM_CONSTANT 0x39
#define MSG_LENGTH 0x08
#define BMS_THERMISTOR_ID 0x1839F380
#define MAX_INT8_T 127
#define MIN_INT8_T -128
#define ANALOG_MAX 1023
struct BoardData {
int8_t min_temp = MAX_INT8_T;
int8_t max_temp = MIN_INT8_T;
int8_t avg_temp = 0;
bool valid = false;
};

float read_ntc_temperature(int analog_value);
void read_Temperatures();
void check_Temperatures();
int8_t safeTemperatureCast(float temp);
void send_CAN_max_min_avg_Temperatures();
void send_to_BMS(int8_t global_min, int8_t global_max, int8_t global_avg);
void send_CAN_all_cell_temperatures();
void show_Temperatures();
void code_reset();
void can_sniffer(const CAN_message_t& msg);
void calculate_global_stats(int8_t& global_min, int8_t& global_max, int8_t& global_avg);
43 changes: 31 additions & 12 deletions teensy_cells/platformio.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:teensy41]
[env]
platform = teensy
board = teensy41
framework = arduino
board = teensy41
build_flags =
-D THIS_IS_MASTER=false
-D BOARD_ID=0

[env:teensy_master]
extends = env
build_flags =
-D THIS_IS_MASTER=true
-D BOARD_ID=0

[env:teensy1]
extends = env
build_flags = -D BOARD_ID=1 -D THIS_IS_MASTER=false

[env:teensy2]
extends = env
build_flags = -D BOARD_ID=2 -D THIS_IS_MASTER=false

[env:teensy3]
extends = env
build_flags = -D BOARD_ID=3 -D THIS_IS_MASTER=false

[env:teensy4]
extends = env
build_flags = -D BOARD_ID=4 -D THIS_IS_MASTER=false

[env:teensy5]
extends = env
build_flags = -D BOARD_ID=5 -D THIS_IS_MASTER=false
187 changes: 134 additions & 53 deletions teensy_cells/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
#include <FlexCAN_T4.h>

#include "Arduino.h"

#define DELAY_VALUE 500
#define N_NTC 18
#define N_BYTES 1023
#define VDD 5.0
#define RESISTOR_PULLUP 10000.0
#define RESISTOR_NTC_REFERNCE 10000.0 // Resistência a 25°C do NTC
#define TEMPERATURE_DEFAULT_C 25.0
#define TEMPERATURE_DEFAULT_K 298.15
#define NTC_BETA 3971.0
#define MAXIMUM_TEMPERATURE 60.0
#include "../include/temp_header.hpp"

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;

Expand All @@ -20,31 +7,37 @@ int pinNTC_Temp[N_NTC] = {A4, A5, A6, A7, A8, A9, A2, A3, A10,
int ERROR_SIGNAL = 35;

float CELL_TEMP[N_NTC];
float MIN_TEMP;
float MAX_TEMP;

uint32_t CAN_IDS[9] = {0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108};
static BoardData board_temps[TOTAL_BOARDS];

void read_Temperatures() {
int ANALOG_SIGNAL;
float VOLTAGE_DIVIDER;
float RESISTOR_VALUE;
float read_ntc_temperature(int analog_value) {
if (analog_value < 0 || analog_value > 1023) {
return TEMPERATURE_DEFAULT_C;
}
float volatge_divider = analog_value * (VDD / 1023.0);
float resistor_value = (RESISTOR_PULLUP * volatge_divider) / (VDD - volatge_divider);
float temp_kelvin = 1.0f / ((1.0f / TEMPERATURE_DEFAULT_K) +
(log(resistor_value / RESISTOR_NTC_REFERNCE) / NTC_BETA));
return temp_kelvin - 273.15f; // return in celcius
}

MIN_TEMP = 100;
MAX_TEMP = -100;
void read_Temperatures() {
float sum_temp = 0.0;
float min_temp = 100.0f;
float max_temp = -100.0f;

for (int i = 0; i < N_NTC; i++) {
ANALOG_SIGNAL = analogRead(pinNTC_Temp[i]);
VOLTAGE_DIVIDER = ANALOG_SIGNAL * (VDD / 1023.0);
RESISTOR_VALUE = (RESISTOR_PULLUP * VOLTAGE_DIVIDER) / (VDD - VOLTAGE_DIVIDER);
CELL_TEMP[i] = 1 / ((1 / TEMPERATURE_DEFAULT_K) +
(log(RESISTOR_VALUE / RESISTOR_NTC_REFERNCE) /
NTC_BETA)); // fórmula para obter a temperatura do NTC em K
CELL_TEMP[i] = CELL_TEMP[i] - 273.15; // conversão para Celsius
MIN_TEMP = min(MIN_TEMP, CELL_TEMP[i]);
MAX_TEMP = max(MAX_TEMP, CELL_TEMP[i]);
CELL_TEMP[i] = read_ntc_temperature(analogRead(pinNTC_Temp[i]));
min_temp = min(min_temp, CELL_TEMP[i]);
max_temp = max(max_temp, CELL_TEMP[i]);
sum_temp += CELL_TEMP[i];
}
board_temps[BOARD_ID].min_temp = safeTemperatureCast(min_temp);
board_temps[BOARD_ID].max_temp = safeTemperatureCast(max_temp);
board_temps[BOARD_ID].avg_temp = safeTemperatureCast(sum_temp / N_NTC);
board_temps[BOARD_ID].valid = true;
}

void check_Temperatures() {
bool error_flag = false;
for (int i = 0; i < N_NTC; i++) {
Expand All @@ -59,24 +52,74 @@ void check_Temperatures() {
}
}

void send_CAN_Temperatures() {
int8_t safeTemperatureCast(float temp) {
if (temp > 127.0f) return MAX_INT8_T;
if (temp < -128.0f) return MIN_INT8_T;
return static_cast<int8_t>(round(temp));
}

void send_CAN_max_min_avg_Temperatures() {
CAN_message_t msg;
msg.id = MASTER_CELL_ID;
msg.len = 4;

msg.buf[0] = BOARD_ID;
msg.buf[1] = board_temps[BOARD_ID].min_temp;
msg.buf[2] = board_temps[BOARD_ID].max_temp;
msg.buf[3] = board_temps[BOARD_ID].avg_temp;
can1.write(msg);

Serial.print("CAN MSG - ID: 0x109 | Min: ");
Serial.print(static_cast<int8_t>(msg.buf[1]));
Serial.print("°C, Max: ");
Serial.print(static_cast<int8_t>(msg.buf[2]));
Serial.print("°C, Avg: ");
Serial.println(static_cast<int8_t>(msg.buf[3]));
}
void send_to_BMS(int8_t global_min, int8_t global_max, int8_t global_avg) {
CAN_message_t msg;
msg.id = BMS_THERMISTOR_ID;
msg.len = 8;
msg.buf[0] = THERMISTOR_MODULE_NUMBER;
msg.buf[1] = global_min;
msg.buf[2] = global_max;
msg.buf[3] = global_avg;
msg.buf[4] = NUMBER_OF_THERMISTORS;
msg.buf[5] = HIGHEST_THERMISTOR_ID;
msg.buf[6] = LOWEST_THERMISTOR_ID;
msg.buf[7] = msg.buf[1] + msg.buf[2] + msg.buf[3] + msg.buf[4] + msg.buf[5] + msg.buf[6] +
CHECKSUM_CONSTANT + MSG_LENGTH;
can1.write(msg);
// According to documentation we might need to send message to another id as well, although last
// year only this one was used and worked fine
}

void send_CAN_all_cell_temperatures() {
CAN_message_t msg;

for (int i = 0; i < 9; i++) {
msg.id = CAN_IDS[i];
for (int msgIndex = 0; msgIndex < 3; msgIndex++) {
msg.id = BOARD_ID; // TODO: change this to the correct ID if needed
msg.len = 8;
float temp1 = CELL_TEMP[i * 2];
float temp2 = CELL_TEMP[i * 2 + 1];
memcpy(&msg.buf[0], &temp1, sizeof(temp1));
memcpy(&msg.buf[4], &temp2, sizeof(temp2));

msg.buf[0] = BOARD_ID;
msg.buf[1] = msgIndex;

for (int i = 0; i < CELLS_PER_MESSAGE; i++) {
int cellIndex = (msgIndex * CELLS_PER_MESSAGE) + i;
msg.buf[i + 2] = cellIndex < N_NTC ? safeTemperatureCast(CELL_TEMP[cellIndex]) : 0;
}

can1.write(msg);

Serial.print("Enviando via CAN - ID: 0x");
Serial.print(CAN_IDS[i], HEX);
Serial.print(" | Temp1: ");
Serial.print(temp1);
Serial.print("°C, Temp2: ");
Serial.println(temp2);
Serial.print("CAN MSG - ID: 0x");
Serial.print(msg.id, HEX);
Serial.print(" | Board: ");
Serial.print(BOARD_ID);
Serial.print(" | Cells ");
Serial.print(msgIndex * CELLS_PER_MESSAGE + 1);
Serial.print("-");
Serial.println(min((msgIndex + 1) * CELLS_PER_MESSAGE, N_NTC));

delay(100);
}
}
Expand All @@ -99,22 +142,60 @@ void code_reset() {
digitalWrite(ERROR_SIGNAL, LOW);
}

void can_sniffer(const CAN_message_t& msg) {
if (msg.id == MASTER_CELL_ID && msg.len == 4) {
uint8_t board = msg.buf[0];
if (board < TOTAL_BOARDS) {
board_temps[board].min_temp = static_cast<int8_t>(msg.buf[1]);
board_temps[board].max_temp = static_cast<int8_t>(msg.buf[2]);
board_temps[board].avg_temp = static_cast<int8_t>(msg.buf[3]);
board_temps[board].valid = true;
}
}
}

void calculate_global_stats(int8_t& global_min, int8_t& global_max, int8_t& global_avg) {
int sum = 0;
int valid_count = 0;
global_min = MAX_INT8_T;
global_max = MIN_INT8_T;

for (const auto& board : board_temps) {
if (board.valid) {
global_min = min(global_min, board.min_temp);
global_max = max(global_max, board.max_temp);
sum += board.avg_temp;
valid_count++;
}
}
global_avg = valid_count > 0 ? sum / valid_count : 0;
}

void setup() {
Serial.begin(9600);
code_reset();
can1.begin();
can1.setBaudRate(500000);
can1.setBaudRate(CAN_BAUD_RATE);
if (THIS_IS_MASTER) {
can1.enableFIFO();
can1.enableFIFOInterrupt();
can1.setFIFOFilter(REJECT_ALL);
can1.setFIFOFilter(0, MASTER_CELL_ID, STD);
can1.onReceive(can_sniffer);
}
}

void loop() {
read_Temperatures();
check_Temperatures();
send_CAN_Temperatures();

if (!THIS_IS_MASTER) {
send_CAN_max_min_avg_Temperatures();
} else {
int8_t global_min, global_max, global_avg;
calculate_global_stats(global_min, global_max, global_avg);
send_to_BMS(global_min, global_max, global_avg);
}
show_Temperatures();
delay(DELAY_VALUE);
delay(DELAY_INTERVAL);
}

// o que falta adicionar é uma
// "master" de modo a receber os IDs todos de CAN e depois mandar um ID especifico de CAN para a
// BMS(temperatura máxima e minima das celulas),
// depois amanha falo contigo
5 changes: 5 additions & 0 deletions teensy_cells_master/teensy_cells_master/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
10 changes: 10 additions & 0 deletions teensy_cells_master/teensy_cells_master/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
39 changes: 39 additions & 0 deletions teensy_cells_master/teensy_cells_master/include/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

This directory is intended for project header files.

A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.

```src/main.c

#include "header.h"

int main (void)
{
...
}
```

Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.

In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.

Read more about using header files in official GCC documentation:

* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes

https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
Loading

0 comments on commit c75f8fa

Please sign in to comment.