Telemetria WiFi+SD

This commit is contained in:
Alejandro Guerrero 2026-07-28 00:59:03 +02:00
parent 7c069efa14
commit 4b58b1ec97
6 changed files with 181 additions and 152 deletions

View file

@ -1,6 +1,6 @@
/**
* @file can.cpp
* @author Raúl Arcos Herrera
* @author Raul Arcos Herrera
* @brief This file contains the implementation of the CAN Controller class for Link G4+ ECU.
*/
@ -8,8 +8,7 @@
// Volcado en crudo de TODOS los mensajes del bus, a la velocidad a la que
// llegan. Satura los 115200 baudios y frena la tarea de escucha, asi que solo
// debe activarse para depurar el bus. Con esto a 1 no se leen las lineas
// [TRAMA n] del data_processor, que son las utiles para localizar canales
// debe activarse para depurar el bus.
#define VOLCADO_CRUDO_CAN 0
static bool driver_installed = false;
@ -47,7 +46,6 @@ void CAN::start() {
return;
}
// TWAI driver is now successfully installed and started
driver_installed = true;
}
@ -69,7 +67,7 @@ void CAN::start_listening_task() {
"CAN_Listen_Task", // Task name
4096, // Stack size (words)
this, // Task parameter (this CAN instance)
1, // Priority (lowered from 5 to 1)
1, // Priority
&_listen_task_handle // Task handle
);
@ -88,7 +86,6 @@ void CAN::stop_listening_task() {
if (_listen_task_handle != NULL) {
_should_stop_listening = true;
// Wait for task to finish (max 1 second)
for (int i = 0; i < 100; i++) {
if (_listen_task_handle == NULL) {
break;
@ -96,7 +93,6 @@ void CAN::stop_listening_task() {
vTaskDelay(pdMS_TO_TICKS(10));
}
// Force delete if still running
if (_listen_task_handle != NULL) {
vTaskDelete(_listen_task_handle);
_listen_task_handle = NULL;
@ -128,21 +124,17 @@ twai_message_t CAN::createBoolMessage(bool b0, bool b1, bool b2, bool b3, bool b
void CAN::listen() {
Serial.println("CAN listening task started");
// Continuous loop for the thread
while (!_should_stop_listening) {
if (!driver_installed) {
// Driver not installed
vTaskDelay(pdMS_TO_TICKS(1000));
continue;
}
// Check if alert happened
uint32_t alerts_triggered;
twai_read_alerts(&alerts_triggered, 0); // Reduced timeout for more responsiveness
twai_read_alerts(&alerts_triggered, 0);
twai_status_info_t twaistatus;
twai_get_status_info(&twaistatus);
// Handle alerts
if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
Serial.println("Alert: TWAI controller has become error passive.");
}
@ -190,8 +182,6 @@ void CAN::listen() {
Serial.println("");
#endif
if (!(message.rtr)) {
// Send to data processor based on first byte (maintaining original logic)
switch (message.data[0]) {
case 0:
_data_processor->send_serial_frame_0(message.data[1], message.data[2], message.data[3], message.data[4], message.data[5], message.data[6], message.data[7]);
@ -223,5 +213,5 @@ void CAN::listen() {
Serial.println("CAN listening task ending");
_listen_task_handle = NULL;
vTaskDelete(NULL); // Delete this task
vTaskDelete(NULL);
}

View file

@ -1,76 +1,90 @@
#include "../include/data_processor.hpp"
char* DataProcessor::process(std::vector<float> data) {
// Implementación del procesamiento de datos si es necesario
return nullptr; // Placeholder
return nullptr;
}
void DataProcessor::send_serial(byte type, unsigned int value) { //Como parámetros se pasan el ID (type), que es el ID establecido al inicio del código para el dato que se quiera enviar. Ej: RPM_ID -> 0x51; y se envía el valor de dicho dato.
byte dato[8] = { 0x5A, 0xA5, 0x05, 0x82, 0x00, 0x00, 0x00, 0x00 }; //Se establece un arreglo de bytes con los primeros datos necesarios para que la pantalla lo interprete como mensaje (En la Wiki hay tutoriales que lo explican a fondo), como ser la longitud y el tipo de mensaje.
dato[4] = type; //Se configura en el mensaje el ID correspondiente al dato a enviar.
dato[6] = (value >> 8) & 0xFF; //Se configura el dato en los últimos 2 bytes.
void DataProcessor::send_serial(byte type, unsigned int value) {
byte dato[8] = { 0x5A, 0xA5, 0x05, 0x82, 0x00, 0x00, 0x00, 0x00 };
dato[4] = type;
dato[6] = (value >> 8) & 0xFF;
dato[7] = value & 0xFF;
Serial.write(dato, 8); //Se envía serialmente el mensaje, indicando su longituden bytes para ello.
Serial.write(dato, 8);
}
//RPM + TPS + vBatt + ECT
void DataProcessor::send_serial_frame_0(int rpmh, int rpml, int tpsh, int tpsl, int vbatth, int vbattl, int ect){
//Calculos necesarios para obtener bien el formato de los valores necesarios
// RPM + TPS + vBatt + ECT
void DataProcessor::send_serial_frame_0(int rpmh, int rpml, int tpsh, int tpsl, int vbatth, int vbattl, int ect) {
int rpm = (rpmh * 256) + rpml;
double vbatt = ((vbatth * 256) + vbattl) / 100.0;
int tps = (tpsh * 256) + tpsl;
int tps = (tpsh * 256) + tpsl;
//Serial.printf("TRAMA: 0\n");
//Serial.printf("RPM: %d | VBATT: %f | TPS: %d | ECT: %d\n", rpm, vbatt, tps, ect);
// Actualizamos las variables globales para que puedan ser leidas por el protocolo UDP
this->current_ect_value = ect;
this->current_rpm_value = rpm;
this->current_vbatt_value = vbatt;
this->current_tps_value = tps;
flushToSD();
}
void DataProcessor::send_serial_frame_1(int lmbh, int lmbl, int lmbth, int lmbtl, int fuelh, int fuell, int gear){
void DataProcessor::send_serial_frame_1(int lmbh, int lmbl, int lmbth, int lmbtl, int fuelh, int fuell, int gear) {
float lambda = ((lmbh * 256) + lmbl) / 100.0;
float lambdaTarget = ((lmbth * 256) + lmbtl) / 100.0;
float presionComb = ((fuelh * 256) + fuell) / 100.0;
//Serial.printf("TRAMA: 1\n");
//Serial.printf("LAMBDA: %f | LAMBDA TARGET: %f | PRESION COMBUSTIBLE: %f\n", lambda, lambdaTarget, presionComb);
this->current_lambda_value = lambda;
this->current_lambda_obj_value = lambdaTarget;
this->current_pcomb_value = presionComb;
//this->current_marcha_value
flushToSD();
}
void DataProcessor::send_serial_frame_2(int shut, int fan, int lmbch, int lmbcl, int brakeh, int brakel, int aux1){
void DataProcessor::send_serial_frame_2(int shut, int fan, int lmbch, int lmbcl, int brakeh, int brakel, int aux1) {
float freno = (brakeh * 256) + brakel;
//Serial.printf("TRAMA: 2\n");
//Serial.printf("FRENO: %f\n", freno);
this->current_freno_del_value = freno;
flushToSD();
}
void DataProcessor::send_serial_frame_3(int oilth, int oiltl, int oilph, int oilpl, int maph, int mapl, int dig1){
void DataProcessor::send_serial_frame_3(int oilth, int oiltl, int oilph, int oilpl, int maph, int mapl, int dig1) {
float tempOil = ((oilth * 256) + oiltl) / 100.0;
float presionOil = ((oilph * 256) + oilpl) / 100.0;
float map = ((maph * 256) + mapl) / 100.0;
//Serial.printf("TRAMA: 3\n");
//Serial.printf("TEMP OIL: %f | PRESION OIL: %f | MAP: %f\n", tempOil, presionOil, map);
this->current_taceite_value = tempOil;
this->current_paceite_value = presionOil;
this->current_map_value = map;
flushToSD();
}
void DataProcessor::send_serial_frame_4(int dig3, int dig4, int dig5, int dig6, int dig7, int dig8, int dig9){
void DataProcessor::send_serial_frame_4(int dig3, int dig4, int dig5, int dig6, int dig7, int dig8, int dig9) {
}
// --- ESCRITURA SD ---
void DataProcessor::flushToSD() {
if (_sd && _logFile && _logFile->isOpen()) {
char buffer[256];
int len = snprintf(buffer, sizeof(buffer),
"%lu,%d,%d,%.1f,%.2f,%.1f,%.2f,%.1f,%.2f,%.1f,%.3f,%.3f\n",
millis(),
current_ect_value,
current_rpm_value,
current_tps_value,
current_vbatt_value,
current_freno_del_value,
current_pcomb_value,
current_taceite_value,
current_paceite_value,
current_map_value,
current_lambda_value,
current_lambda_obj_value);
_logFile->write(buffer, len);
if (millis() - _last_sync_time > _sync_interval_ms) {
_logFile->sync();
_last_sync_time = millis();
}
}
}