Todo subido

This commit is contained in:
Álvaro Alcántara Ramírez 2026-08-03 21:52:05 +02:00
parent f0db3a8aeb
commit 27026caf57
87 changed files with 83292 additions and 17 deletions

22
Volante/AAVolante.ino Normal file
View file

@ -0,0 +1,22 @@
#include "can.hpp"
#include "led.hpp"
#include "configuracion.hpp"
CAN can;
void setup(){
Serial.begin(115200);
led_startup();
can.start();
can.start_listening_task();
}
void loop(){
}

181
Volante/can.cpp Normal file
View file

@ -0,0 +1,181 @@
#include "can.hpp"
#include "led.hpp"
#include "configuracion.hpp"
#include <Arduino.h>
static bool driver_installed = false;
void CAN::start() {
Serial.println("Starting CAN Controller...");
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);
g_config.rx_queue_len = 64;
g_config.tx_queue_len = 16;
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
if (twai_driver_install(&g_config, &t_config, &f_config) != ESP_OK) {
Serial.println("Failed to install TWAI driver");
driver_installed = false;
return;
}
Serial.println("TWAI driver installed");
if (twai_start() != ESP_OK) {
Serial.println("Failed to start TWAI driver");
twai_driver_uninstall();
driver_installed = false;
return;
}
Serial.println("TWAI driver started");
uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
if (twai_reconfigure_alerts(alerts_to_enable, nullptr) != ESP_OK) {
Serial.println("Failed to reconfigure alerts");
twai_stop();
twai_driver_uninstall();
driver_installed = false;
return;
}
Serial.println("CAN Alerts reconfigured");
driver_installed = true;
}
CAN::~CAN() {
stop_listening_task();
if (driver_installed) {
twai_stop();
twai_driver_uninstall();
driver_installed = false;
}
}
void CAN::start_listening_task() {
if (_listen_task_handle != nullptr) {
Serial.println("CAN listening task already running");
return;
}
_should_stop_listening = false;
BaseType_t result = xTaskCreate(listenTask, "CAN_Listen_Task", 4096, this, 1, &_listen_task_handle);
if (result == pdPASS) {
Serial.println("CAN listening task created successfully");
} else {
Serial.println("Failed to create CAN listening task");
_listen_task_handle = nullptr;
}
}
void CAN::stop_listening_task() {
if (_listen_task_handle == nullptr) {
return;
}
_should_stop_listening = true;
for (int i = 0; i < 100 && _listen_task_handle != nullptr; i++) {
vTaskDelay(pdMS_TO_TICKS(10));
}
if (_listen_task_handle != nullptr) {
vTaskDelete(_listen_task_handle);
_listen_task_handle = nullptr;
}
Serial.println("CAN listening task stopped");
}
void CAN::listenTask(void *arg) {
CAN *instance = static_cast<CAN *>(arg);
instance->listen_id();
instance->_listen_task_handle = nullptr;
vTaskDelete(nullptr);
}
void CAN::listen_id() {
Serial.println("CAN listening task started");
uint32_t last_can_update = 0;
while (!_should_stop_listening) {
if (!driver_installed) {
vTaskDelay(pdMS_TO_TICKS(1000));
continue;
}
uint32_t alerts_triggered = 0;
twai_read_alerts(&alerts_triggered, 0);
if (alerts_triggered & (TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL)) {
twai_status_info_t twai_status;
twai_get_status_info(&twai_status);
if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
Serial.println("Alert: TWAI controller has become error passive.");
}
if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
Serial.printf("Bus error count: %lu\n", twai_status.bus_error_count);
}
if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
Serial.printf("RX buffered: %lu\t", twai_status.msgs_to_rx);
Serial.printf("RX missed: %lu\t", twai_status.rx_missed_count);
Serial.printf("RX overrun: %lu\n", twai_status.rx_overrun_count);
}
}
if (alerts_triggered & TWAI_ALERT_RX_DATA) {
twai_message_t message;
while (twai_receive(&message, 0) == ESP_OK && !_should_stop_listening) {
if (message.rtr || message.data_length_code < 3) {
taskYIELD();
continue;
}
switch (message.data[0]) {
case 0:
led_show_rpm(message.data[1], message.data[2]);
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 100:
break;
default:
break;
}
taskYIELD();
}
}
vTaskDelay(pdMS_TO_TICKS(5));
}
Serial.println("CAN listening task ending");
}

25
Volante/can.hpp Normal file
View file

@ -0,0 +1,25 @@
#ifndef CAN_HPP
#define CAN_HPP
#include "driver/twai.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
class CAN {
public:
CAN() : _listen_task_handle(nullptr), _should_stop_listening(false) {}
~CAN();
void start();
void start_listening_task();
void stop_listening_task();
void listen_id();
private:
static void listenTask(void *arg);
TaskHandle_t _listen_task_handle;
volatile bool _should_stop_listening;
};
#endif

28
Volante/configuracion.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
/*
--------------------
LEDS
--------------------
*/
#define PIN_LEDS 23
#define NUM_LEDS 10
/*
--------------------
RPM LEDS
--------------------
*/
#define RPM_MIN_LED 8000
#define RPM_MAX_LED 12200
/*
--------------------
CAN
--------------------
*/
#define RX_PIN 13
#define TX_PIN 38

60
Volante/led.cpp Normal file
View file

@ -0,0 +1,60 @@
#include "led.hpp"
#include "configuracion.hpp"
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel tira(NUM_LEDS, PIN_LEDS, NEO_GRB + NEO_KHZ800);
void led_startup() {
tira.begin();
tira.setBrightness(100);
tira.clear();
tira.show();
}
void led_show_rpm(int rpmh, int rpml) {
int rpm=(rpmh * 256) + rpml;
tira.clear();
// Por debajo de las RPM mínimas, todos apagados
if (rpm < RPM_MIN_LED) {
tira.show();
return;
}
// Por encima del máximo, todos azules
if (rpm > RPM_MAX_LED) {
tira.fill(tira.Color(0, 0, 255));
tira.show();
return;
}
// Calcula cuántos LED deben encenderse
int leds_encendidos = map(rpm, RPM_MIN_LED, RPM_MAX_LED, 1, NUM_LEDS);
leds_encendidos = constrain(leds_encendidos, 0, NUM_LEDS);
int primer_tercio = NUM_LEDS / 3;
int segundo_tercio = (NUM_LEDS * 2) / 3;
for (int i = 0; i < leds_encendidos; i++) {
if (i < primer_tercio) {
// Primer tercio: verde
tira.setPixelColor(i, tira.Color(0, 255, 0));
} else if (i < segundo_tercio) {
// Segundo tercio: amarillo
tira.setPixelColor(i, tira.Color(255, 255, 0));
} else {
// Tercer tercio: rojo
tira.setPixelColor(i, tira.Color(255, 0, 0));
}
}
tira.show();
}

4
Volante/led.hpp Normal file
View file

@ -0,0 +1,4 @@
#pragma once
void led_startup();
void led_show_rpm(int rpmh, int rpml);