Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
.cache/*
/.vscode
/.idea
compile_commands.json
1,040 changes: 1,040 additions & 0 deletions compile_commands.json

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions include/apps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @file apps.h
* @brief Accelerator Pedal Position Sensor interface for plausibility checks and pedal mapping.
* @author Asher Olgeirson (UCD Formula Student)
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#ifndef APPS_H
#define APPS_H

/* Accelerator Pedal Position Sensor \
See T.11.8 and T.11.9 for more info \
Requirments: \
- Detect implausibility where there is a 10% difference or more between the \
two sensors \
- Shut down main motors when implausibility exists for 100ms or more \
- Fail safe (shut down main motors) when short to ground or supply, open, \
mechanicaly impossible, or otherwise broken \
- Fail safe within 500ms of detecting a failure \
\
*/

#include <Arduino.h>
#include <utility>

namespace APPS {

enum class AppsStatus { OK, Implausible, Fault };

struct AppsReading {
AppsReading(AppsStatus status, double value, double APPS1, double APPS2) {
this->status = status;
this->value = value;
this->APPS1 = APPS1;
this->APPS2 = APPS2;
}

AppsStatus status;
double value; // This could work as an std::optional<double>, but the risk of
// bad optional access exceptions outweighs the advantage
double APPS1;
double APPS2;
};

//@breif Returns pedal position (%) or -1.0 on implausibility
//@return An AppsReading struct containing validity and pedal position
// Do not trust .value without first checking that .status is OK
AppsReading get_apps_reading();

//@breif T.11.8 compliance. Accepts a pair of APPS1 and APPS2 in order
bool check_plausiblity(std::pair<float, float> percentages);

//@breif T.11.9 compliance. Accepts a pair of APPS1 and APPS2 in order
bool check_integrity(std::pair<float, float> raws);

//@breif reads raw values without adjusting or normalizing
std::pair<float, float> get_raw_values();

//@breif converts raw values to percentages. First position in input pair
//becomes first position in return pair and vice versa
std::pair<float, float> get_percentage_values(std::pair<float, float> raws);

constexpr int DEBUG_MODE = 2; // 0: Off, 1: implausibility only, 2: all

// TODO: Get real measurements
extern const double PEDAL_MIN;
// TODO: Get real measurements
extern const double PEDAL_MAX;
constexpr int APPS_1_PIN = A6;
constexpr int APPS_2_PIN = A7;

// How many MS since an implausibility was detecting
inline int implausibility_start = 0;

// TODO: Get real measurements
// Define pedal calibration constants
// These are RAW ADC values (not voltages), since values DECREASE when
// pressed
constexpr int APPS1_RAW_MIN = 473; // Value when pedal is fully pressed (100%)
constexpr int APPS1_RAW_MAX = 750; // Value when pedal is released (0%)
constexpr int APPS2_RAW_MIN = 468; // Value when pedal is fully pressed (100%)
constexpr int APPS2_RAW_MAX = 750; // Value when pedal is released (0%)

// APPS
constexpr float APPS_PLAUSIBILITY_THRESHOLD = 10.0f; // T11.8.9
constexpr float APPS_BRAKE_CONFLICT_THRESHOLD = 25.0f; // percent threshold for brake conflict logic

const unsigned long PLAUSIBILITY_TIMEOUT_MS =
100; // Max time for APPS implausibility (Rule EV.5.6.3)
const unsigned long BRAKE_PLAUSIBILITY_TIMEOUT_MS =
500; // Max time for APPS/Brake implausibility (Rule

} // namespace APPS
#endif // APPS_H
54 changes: 54 additions & 0 deletions include/brake_light.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @file brake_light.h
* @brief Header file for brake light control based on brake pressure and deceleration.
* @author Charlie Zhang (UCD Formula Student)
* @date 2025/2026
*/


#pragma once
#include <Arduino.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

namespace BrakeLight {

inline constexpr int DEBUG_MODE = 1; // 0: off, higher values increase verbosity

// --- Pin definitions (update if needed) ---
constexpr int BRAKE_PRESSURE_SENSOR_PIN_FRONT = A0; // TODO: correct analog pin
constexpr int BRAKE_PRESSURE_SENSOR_PIN_REAR = A1; // TODO: correct analog pin
constexpr int BRAKE_LIGHT_PIN = LED_BUILTIN; // TODO: correct output pin

// --- Thresholds (placeholder values, calibrate on car) ---
static constexpr int BRAKE_THRESHOLD_DELTA = 10; // TODO: ADC counts above idle
static constexpr int BRAKE_LIGHT_HYSTERESIS = 6; // TODO: counts below threshold to turn off
static constexpr float REGEN_DECEL_THRESHOLD = 1.0f; // m/s^2
static constexpr float FORWARD_TILT_DEG = 6.0f; // degrees

// --- IMU calibration ---
static constexpr uint16_t IMU_CALIB_SAMPLES = 1500; // TODO: tune boot time vs stability
static constexpr float ACCEL_EWMA_ALPHA = 0.2f; // low-pass smoothing factor

struct BrakeData {
int front_pressure;
int rear_pressure;
int combined_pressure;
bool brake_active; // true when brake light logic is ON
float decel_ms2;
float tilt_deg;
};

// --- Function declarations ---
void init();
BrakeData update(); // returns current readings
void recalibrate_idle();
bool initialize_mpu();
void calibrate_imu_rest();
float compute_forward_tilt_deg(float ay_ms2, float az_ms2);
float read_decel_ms2(float ax_ms2);

// Query current brake light state (true when logic is ON)
bool is_active();

} // namespace BrakeLight
19 changes: 19 additions & 0 deletions include/dashboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @file dashboard.h
* @brief Declares the Nextion dashboard interface for telemetry and sensor pages.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#pragma once
#include <Arduino.h>
#include <Nextion.h>

namespace Dashboard {
void init(HardwareSerial &serial = Serial1);
void updateTelemetry(float speed, int rpm, bool rtdActive);
void updateSensors(float apps1, float apps2,
float brakeFront, float brakeRear);
void updateAcceleratorBar(float accelPercent);
void updateBrakeLightBar(bool brakeActive);
} // namespace Dashboard
17 changes: 17 additions & 0 deletions include/dashboard_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @file dashboard_helpers.h
* @brief Helper utilities for updating Nextion dashboard widgets.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#ifndef DASHBOARD_HELPERS_H
#define DASHBOARD_HELPERS_H

#include <Nextion.h>

void setText(NexText &obj, const char *value);
void setText(NexText &obj, float value, int decimals = 1);
void setBar(NexProgressBar &obj, int value);

#endif
36 changes: 36 additions & 0 deletions include/header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @file header.h
* @brief Global configuration constants and pin assignments for the testing ECU.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#pragma once
#include <Arduino.h>

// ====== GLOBAL FLAGS ======
constexpr bool DEBUG_MODE = true; // Enable Serial debug output

// ====== PIN ASSIGNMENTS ======
constexpr int RTD_BUTTON_PIN = 22; // Momentary Ready-to-Drive button
constexpr int BUZZER_PIN = 23; // RTD buzzer output

// ====== CAN SETTINGS ======
constexpr unsigned int CAN_BAUD_RATE = 500000;
constexpr unsigned int CAN_TIMEOUT_MS = 500;

// ====== TIMING ======
constexpr unsigned int STATUS_REQ_INTERVAL_MS = 20;
constexpr unsigned int RPM_REQ_INTERVAL_MS = 20;

// ====== SPEED LIMITER ======
// Top speed limit in km/h and taper band where torque linearly reduces to 0
constexpr float SPEED_LIMIT_KMH = 20.0f; // adjust as needed
constexpr float SPEED_LIMIT_TAPER_KMH = 3.0f; // linear taper band below limit
constexpr float SPEED_LIMIT_HYST_KMH = 0.5f; // optional hysteresis for re-enable
// Slew rate to avoid jerky torque changes when limiting (counts per second)
constexpr int SPEED_SLEW_COUNTS_PER_SEC = 8000; // adjust to taste

// ====== UI / DEBUG ======
constexpr unsigned int DASHBOARD_UPDATE_INTERVAL_MS = 100; // Nextion refresh cadence
constexpr unsigned int DEBUG_PRINT_INTERVAL_MS = 1000; // Serial debug cadence
13 changes: 13 additions & 0 deletions include/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @file helpers.h
* @brief Utility helpers shared across ECU modules.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#pragma once
#include <Arduino.h>

namespace Helper {
float rpm_to_kmh(float rpm);
}
19 changes: 19 additions & 0 deletions include/logging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @file logging.h
* @brief SD-card logging interface for CAN traffic capture.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#pragma once
#include <Arduino.h>
#include <SD.h>
#include <FlexCAN_T4.h>

// Logs CAN frames, generates filenames, and streams to Serial2 (ESP)
namespace Logging {
void init(); // Mount SD + open new log file
void logCANFrame(const CAN_message_t &msg, const char *dir);
void flush();
void close();
}
34 changes: 34 additions & 0 deletions include/motor_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @file motor_controller.h
* @brief Interface for Bamocar D3 motor controller management over CAN.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#pragma once
#include <Arduino.h>

namespace MotorController {

inline constexpr int DEBUG_MODE = 1; // 0 disables module logging

// Bamocar torque scaling
inline constexpr int16_t MAX_TORQUE_COUNTS = 32767; // full-scale command
inline constexpr float MAX_TORQUE_PERCENT = 100.0f;

// Init pins and CAN. rtdButtonPin is active-low. buzzerPin optional (-1 to disable)
void init();

// Call each loop
void update();

// Request torque. Ignored until readyToDrive is true
void setTorque(int16_t torqueCounts);

// Query
bool ready();
bool faulted();
int rpm();
float dcBus();

}
29 changes: 29 additions & 0 deletions include/nextion_ids.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @file nextion_ids.h
* @brief Defines Nextion component identifiers used by the dashboard module.
* @author Shane Whelan (UCD Formula Student)
* @date 2025/2026
*/

#ifndef NEXTION_IDS_H
#define NEXTION_IDS_H

// ---------- Page 2 – Driving Info ----------
#define PAGE_TELEMETRY 2
#define KMH_TXT_NAME "kmh_txt"
#define RPM_TXT_NAME "rpm_txt"
#define RTDSTATUS_TXT_NAME "rtdstatus_txt"

// ---------- Page 4 – Sensor Diagnostics ----------
#define PAGE_SENSORS 4
#define APPS1_TXT_NAME "apps1_txt"
#define APPS2_TXT_NAME "apps2_txt"
#define BRAKE_FRONT_TXT_NAME "brakefront_txt"
#define BRAKE_REAR_TXT_NAME "brakerear_txt"

// ---------- Page 5 – Accelerator ----------
#define PAGE_ACCEL 5
#define ACCEL_BAR_NAME "accel_bar"
#define BRAKE_LIGHT "brake_light" // is type bar, but will only be set to 0 or 100

#endif // NEXTION_IDS_H
Loading