From c62563a65953a61dfac3eca534be6099a8e295c4 Mon Sep 17 00:00:00 2001 From: Wenmiaojia Date: Sun, 2 Nov 2025 12:31:27 -0600 Subject: [PATCH 1/5] EC2-104: Integrate CAN steering and speed data into pointer display --- .vscode/settings.json | 3 ++- embedded-pio | 2 +- include/canSteering.h | 19 ++++++++++++++++++- src/canSteering.cpp | 19 ++++++++++++++++++- src/display.cpp | 2 +- src/main.cpp | 21 ++++++++++++++++++++- src/pointer.cpp | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 08ab831..00cd46b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "random": "cpp", "initializer_list": "cpp", "mutex": "cpp", - "regex": "cpp" + "regex": "cpp", + "iterator": "cpp" } } \ No newline at end of file diff --git a/embedded-pio b/embedded-pio index 9e8f34c..a3c2897 160000 --- a/embedded-pio +++ b/embedded-pio @@ -1 +1 @@ -Subproject commit 9e8f34cb83b9d1232a50e24863bb080c85eb7a45 +Subproject commit a3c2897821fcddf6f49f1f63a9b47d88681ab9ca diff --git a/include/canSteering.h b/include/canSteering.h index 9c6cd04..ba81b6d 100644 --- a/include/canSteering.h +++ b/include/canSteering.h @@ -12,4 +12,21 @@ // void sendSteeringData(); // }; -// #endif \ No newline at end of file +// #endif +#ifndef __CAN_STEERING_H__ +#define __CAN_STEERING_H__ + +#include +#include "esp32canmanager.h" +#include "IOManagement.h" + +#define CAN_QUEUE_PERIOD 50 + +class CANSteering : public ESP32CANManager { + public: + CANSteering(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency = DEFAULT_ESP32_CAN_FREQ); + void readHandler(CanFrame msg); + void sendSteeringData(); +}; + +#endif \ No newline at end of file diff --git a/src/canSteering.cpp b/src/canSteering.cpp index ac5d618..de269ce 100644 --- a/src/canSteering.cpp +++ b/src/canSteering.cpp @@ -9,4 +9,21 @@ // void CANSteering::sendSteeringData() { // this->sendMessage(0x300, (void*)&digital_data, sizeof(digital_data)); // this->sendMessage(0x301, (void*)®en_brake, sizeof(float)); -// } \ No newline at end of file +// } +#include "canSteering.h" + +#define MAX_ANALOG_VALUE 4095 + +bool send_success; +CANSteering::CANSteering(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency) : ESP32CANManager(tx, rx, tx_queue, rx_queue, frequency) {}; + +void CANSteering::readHandler(CanFrame msg) { + +} + +void CANSteering::sendSteeringData() { + send_success = true; + float regen_brake_calculation = 3.3 * regen_brake / MAX_ANALOG_VALUE; + send_success &= this->sendMessage(0x300, (void*)&digital_data, sizeof(digital_data)); + send_success &= this->sendMessage(0x301, (void*)®en_brake_calculation, sizeof(float)); +} \ No newline at end of file diff --git a/src/display.cpp b/src/display.cpp index c8d8cce..52aaa9d 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -22,7 +22,7 @@ volatile int old_height = 0; int totalFrames = 0; -TFT_eSPI tft = TFT_eSPI(); +extern TFT_eSPI tft; //Heap pointer for animation frames uint8_t *frameHeap = NULL; diff --git a/src/main.cpp b/src/main.cpp index fece7b5..2563379 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,16 @@ #include #include "display.h" #include "pointer.h" +#include "canSteering.h" + +extern CANSteering canSteering; void setup() { Serial.begin(115200); Serial.println("Starting..."); - initDisplay(false); + initDisplay(true); + begin(); // initialize pointer display + canSteering.begin(); // drawSdJpeg("/bsr/Jonathan.jpeg", 130, 0); // HeapAnim(); @@ -14,6 +19,20 @@ void setup() { void loop() { rotateColors(); + + int angleDeg = canSteering.getSteeringAngle(); + int speed = canSteering.getVehicleSpeed(); + + if(angleDeg >=0){ + updatePointerAngle((double)angleDeg); + }else{ + updatePointer(speed); + } +delay(20); + + + + // rotateColors(); // delay(42); // drawSdJpeg("/test.jpg", 0, 0); diff --git a/src/pointer.cpp b/src/pointer.cpp index 7dfdfc2..e71938f 100644 --- a/src/pointer.cpp +++ b/src/pointer.cpp @@ -57,4 +57,37 @@ void updatePointer(int value) { // converts to degrees and calls angle method double theta = 180.0 * value / MAX_VALUE; updatePointerAngle(theta); +} + +// draw static dial/background for the pointer (ticks, pivot, etc.) +void drawPointerBackground() { + // Ensure background is cleared + tft.fillScreen(BG_COLOR); + + // radius for the tick marks + int radius = length + 8; + + // draw ticks every 10 units (0..100) mapped to 0..180 degrees + for (int v = MIN_VALUE; v <= MAX_VALUE; v += 10) { + double theta = 180.0 * v / MAX_VALUE; + int x1 = pivotX + (radius - 8) * cos(theta * DEG_TO_RAD); + int y1 = pivotY + (radius - 8) * sin(theta * DEG_TO_RAD); + int x2 = pivotX + (radius) * cos(theta * DEG_TO_RAD); + int y2 = pivotY + (radius) * sin(theta * DEG_TO_RAD); + tft.drawLine(x1, y1, x2, y2, TFT_WHITE); + } + + // draw outer semicircle (optional) + // approximate by drawing many points along arc + for (int deg = 0; deg <= 180; deg += 2) { + int x = pivotX + radius * cos(deg * DEG_TO_RAD); + int y = pivotY + radius * sin(deg * DEG_TO_RAD); + tft.drawPixel(x, y, TFT_WHITE); + } + + // pivot center + tft.fillCircle(pivotX, pivotY, 4, TFT_WHITE); + + // redraw current pointer on top of background + updatePointerAngle(currentTheta); } \ No newline at end of file From 110151855cebdde41fe144b56db7b50938a0bef2 Mon Sep 17 00:00:00 2001 From: Wenmiaojia Date: Sun, 2 Nov 2025 15:42:24 -0600 Subject: [PATCH 2/5] Update CAN steering and decoder files --- include/IOManagement.h | 81 +++++++++++++++++++++--------------------- include/canSteering.h | 17 ++------- include/pointer.h | 1 + platformio.ini | 20 +++++------ src/IOManagement.cpp | 74 +++++++++++++++++++------------------- src/canSteering.cpp | 33 +++++++++++------ src/main.cpp | 28 ++++++++------- src/pointer.cpp | 2 ++ 8 files changed, 133 insertions(+), 123 deletions(-) diff --git a/include/IOManagement.h b/include/IOManagement.h index 00dd35e..f1a9e4a 100644 --- a/include/IOManagement.h +++ b/include/IOManagement.h @@ -1,40 +1,41 @@ -// #ifndef __IO_MANAGEMENT_H__ -// #define __IO_MANAGEMENT_H__ - -// #include -// #include "STM32TimerInterrupt_Generic.h" -// #include "adc.h" - -// //Macros for pins -// #define DIRECTION_SWITCH_PIN PB1 -// #define LEFT_BLINK_PIN PA9 -// #define RIGHT_BLINK_PIN PA10 -// #define CRZ_MODE_A_PIN PB6 -// #define CRZ_SET_PIN PB5 -// #define CRZ_RESET_PIN PB4 -// #define HORN_PIN PA0 -// #define REGEN_BRAKE_PIN ADC_CHANNEL_6 // PA1 - -// #define IO_UPDATE_PERIOD 100000 // us - -// struct Digital_Data { -// bool direction_switch : 1; // input -// bool left_blink : 1; // input -// bool right_blink : 1; // input -// bool crz_mode_a : 1; // input -// bool crz_set : 1; // input -// bool crz_reset : 1; // input -// bool horn : 1; // input -// }; - -// extern volatile Digital_Data digital_data; - -// extern volatile float regen_brake; - -// // initialize digital and analog pins -// void initIO(); - -// // read digital and analog inputs -// void readIO(); - -// #endif \ No newline at end of file +#ifndef __IO_MANAGEMENT_H__ +#define __IO_MANAGEMENT_H__ + +#include + +// Macros for pins +#define REGEN_BRAKE_PIN 36 +#define HEADLIGHT_PIN 39 +#define LEFT_BLINK_PIN 34 +#define RIGHT_BLINK_PIN 35 +#define DIRECTION_SWITCH_PIN 32 +#define HORN_PIN 33 +#define CRZ_MODE_A_PIN 25 +#define CRZ_SET_PIN 26 +#define CRZ_RESET_PIN 27 + + +#define IO_UPDATE_PERIOD 100000 // us + +struct Digital_Data { + bool headlight : 1; // input + bool left_blink : 1; // input + bool right_blink : 1; // input + bool direction_switch : 1; // input + bool horn : 1; // input + bool crz_mode_a : 1; // input + bool crz_set : 1; // input + bool crz_reset : 1; // input +}; + +extern volatile Digital_Data digital_data; +extern volatile uint16_t regen_brake; +extern volatile uint16_t number_reads; + +// initialize digital and analog pins, and timer to read pins +void initIO(); + +// ISR to read digital and analog inputs +void IRAM_ATTR readIO(); + +#endif \ No newline at end of file diff --git a/include/canSteering.h b/include/canSteering.h index ba81b6d..1c5a318 100644 --- a/include/canSteering.h +++ b/include/canSteering.h @@ -1,18 +1,4 @@ -// #ifndef __CAN_STEERING_H__ -// #define __CAN_STEERING_H__ -// #include "canmanager.h" -// #include "IOManagement.h" - -// #define CAN_QUEUE_PERIOD 50 -// class CANSteering : public CANManager { -// public: -// CANSteering(CAN_TypeDef* canPort, CAN_PINS pins, int frequency = DEFAULT_CAN_FREQ); -// void readHandler(CAN_message_t msg); -// void sendSteeringData(); -// }; - -// #endif #ifndef __CAN_STEERING_H__ #define __CAN_STEERING_H__ @@ -27,6 +13,9 @@ class CANSteering : public ESP32CANManager { CANSteering(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency = DEFAULT_ESP32_CAN_FREQ); void readHandler(CanFrame msg); void sendSteeringData(); + + int getVehicleSpeed(); + }; #endif \ No newline at end of file diff --git a/include/pointer.h b/include/pointer.h index 1f8f065..672a9ef 100644 --- a/include/pointer.h +++ b/include/pointer.h @@ -22,4 +22,5 @@ void updatePointerAngle(double theta); void updatePointer(int value); +void drawPointerBackground(); #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 48d5eae..167f0ee 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,20 +15,20 @@ framework = arduino lib_deps = bodmer/TFT_eSPI@^2.5.43 bodmer/JPEGDecoder@^2.0.0 + handmade0octopus/ESP32-TWAI-CAN@^1.0.1 lib_extra_dirs = ./embedded-pio build_flags = -D USER_SETUP_LOADED - -D ST7796_DRIVER=1 - -D TFT_MISO=19 - -D TFT_MOSI=23 - -D TFT_SCLK=18 - -D TFT_CS=15 - -D TFT_DC=2 - -D TFT_RST=4 - -D LOAD_GLCD=1 - -D SMOOTH_FONT + -D ST7796_DRIVER=1 + -D TFT_MISO=19 + -D TFT_MOSI=23 + -D TFT_SCLK=18 + -D TFT_CS=15 + -D TFT_DC=2 + -D TFT_RST=4 + -D LOAD_GLCD=1 + -D SMOOTH_FONT -D SPI_FREQUENCY=40000000 -D CONFIG_ESP_TASK_WDT_TIMEOUT_S=15 -D CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=false -D CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=false - ;-D TFT_DMA_ENABLED \ No newline at end of file diff --git a/src/IOManagement.cpp b/src/IOManagement.cpp index 8fb7ef0..948cb8f 100644 --- a/src/IOManagement.cpp +++ b/src/IOManagement.cpp @@ -1,41 +1,43 @@ -// #include "IOManagement.h" +#include "IOManagement.h" -// volatile Digital_Data digital_data = {0, 0, 0, 0, 0, 0, 0}; -// volatile float regen_brake = 0.0f; +volatile Digital_Data digital_data; +volatile uint16_t regen_brake; +volatile uint16_t number_reads = 0; +hw_timer_t *io_timer = NULL; -// STM32TimerInterrupt IOTimer(TIM7); +void initIO() { + // Initialize digital pins + pinMode(HEADLIGHT_PIN, INPUT); + pinMode(LEFT_BLINK_PIN, INPUT); + pinMode(RIGHT_BLINK_PIN, INPUT); + pinMode(DIRECTION_SWITCH_PIN, INPUT); + pinMode(HORN_PIN, INPUT); + pinMode(CRZ_MODE_A_PIN, INPUT); + pinMode(CRZ_SET_PIN, INPUT); + pinMode(CRZ_RESET_PIN, INPUT); -// void initIO() { -// // Initialize digital pins -// pinMode(DIRECTION_SWITCH_PIN, INPUT); -// pinMode(LEFT_BLINK_PIN, INPUT); -// pinMode(RIGHT_BLINK_PIN, INPUT); -// pinMode(CRZ_MODE_A_PIN, INPUT); -// pinMode(CRZ_SET_PIN, INPUT); -// pinMode(CRZ_RESET_PIN, INPUT); -// pinMode(HORN_PIN, INPUT); + // Initialize timer for reading inputs + io_timer = timerBegin(0, // which timer (choose between 0 and 3) + 80, // prescaler + true // counts up + ); + timerAttachInterrupt(io_timer, &readIO, true); + timerAlarmWrite(io_timer, IO_UPDATE_PERIOD, true); + timerAlarmEnable(io_timer); // start the timer +} -// // Initialize analog pins -// initADC(ADC1); +void IRAM_ATTR readIO() { + // Read analog input + regen_brake = analogRead(REGEN_BRAKE_PIN); -// // Initialize timer for reading inputs -// if (IOTimer.attachInterruptInterval(IO_UPDATE_PERIOD, readIO)) { -// printf("IO Timer started \n"); -// } else { -// printf("Failed to start IO Timer \n"); -// } -// } - -// void readIO() { -// // Read digital inputs -// digital_data.direction_switch = digitalRead(DIRECTION_SWITCH_PIN); -// digital_data.left_blink = digitalRead(LEFT_BLINK_PIN); -// digital_data.right_blink = digitalRead(RIGHT_BLINK_PIN); -// digital_data.crz_mode_a = digitalRead(CRZ_MODE_A_PIN); -// digital_data.crz_set = digitalRead(CRZ_SET_PIN); -// digital_data.crz_reset = digitalRead(CRZ_RESET_PIN); -// digital_data.horn = digitalRead(HORN_PIN); - -// // Read analog input -// regen_brake = readADC(REGEN_BRAKE_PIN); -// } \ No newline at end of file + // Read digital inputs + digital_data.headlight = digitalRead(HEADLIGHT_PIN); + digital_data.left_blink = digitalRead(LEFT_BLINK_PIN); + digital_data.right_blink = digitalRead(RIGHT_BLINK_PIN); + digital_data.direction_switch = digitalRead(DIRECTION_SWITCH_PIN); + digital_data.horn = digitalRead(HORN_PIN); + digital_data.crz_mode_a = digitalRead(CRZ_MODE_A_PIN); + digital_data.crz_set = digitalRead(CRZ_SET_PIN); + digital_data.crz_reset = digitalRead(CRZ_RESET_PIN); + number_reads++; +} \ No newline at end of file diff --git a/src/canSteering.cpp b/src/canSteering.cpp index de269ce..35debce 100644 --- a/src/canSteering.cpp +++ b/src/canSteering.cpp @@ -1,23 +1,34 @@ -// #include "canSteering.h" -// CANSteering::CANSteering(CAN_TypeDef* canPort, CAN_PINS pins, int frequency) : CANManager(canPort, pins, frequency) {}; - -// void CANSteering::readHandler(CAN_message_t msg) { - -// } - -// void CANSteering::sendSteeringData() { -// this->sendMessage(0x300, (void*)&digital_data, sizeof(digital_data)); -// this->sendMessage(0x301, (void*)®en_brake, sizeof(float)); -// } #include "canSteering.h" #define MAX_ANALOG_VALUE 4095 +float stuff = 0.0; +float speedsig = 0.0; + bool send_success; CANSteering::CANSteering(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency) : ESP32CANManager(tx, rx, tx_queue, rx_queue, frequency) {}; +int CANSteering::getVehicleSpeed() { + // Placeholder implementation + // In a real scenario, this would extract the vehicle speed from received CAN messages + return 42; // Example speed value +} void CANSteering::readHandler(CanFrame msg) { + switch (msg.identifier){ + case 0x200:{ + stuff = *((float*)msg.data); + break; + } + + case 0x201:{ + speedsig = *((float*)msg.data); + break; + } + default: + break; + } + } diff --git a/src/main.cpp b/src/main.cpp index 2563379..4bb78f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,14 +3,20 @@ #include "pointer.h" #include "canSteering.h" -extern CANSteering canSteering; +#define CAN_TX 21 +#define CAN_RX 22 + +CANSteering canSteering(CAN_TX, CAN_RX, 10, 10, 250); +extern bool send_success; + +extern float stuff; +extern float speedsig; void setup() { Serial.begin(115200); Serial.println("Starting..."); - initDisplay(true); + initIO(); begin(); // initialize pointer display - canSteering.begin(); // drawSdJpeg("/bsr/Jonathan.jpeg", 130, 0); // HeapAnim(); @@ -18,17 +24,15 @@ void setup() { } void loop() { - rotateColors(); + // rotateColors(); + canSteering.runQueue(CAN_QUEUE_PERIOD); + + float speed = speedsig; + + Serial.printf("Speed: %.2f\n", speed); - int angleDeg = canSteering.getSteeringAngle(); - int speed = canSteering.getVehicleSpeed(); - if(angleDeg >=0){ - updatePointerAngle((double)angleDeg); - }else{ - updatePointer(speed); - } -delay(20); + updatePointer(speed); diff --git a/src/pointer.cpp b/src/pointer.cpp index e71938f..3341851 100644 --- a/src/pointer.cpp +++ b/src/pointer.cpp @@ -35,6 +35,8 @@ void begin() { updatePointerAngle(0.0); Serial.println("begin"); + + drawPointerBackground(); // draws static background for pointer } // updates pointer given an angle in degrees From caf41f47c2482a0bc878818d9a7474cf3abe8bb7 Mon Sep 17 00:00:00 2001 From: Porter Fencl Date: Sat, 22 Nov 2025 00:32:37 -0600 Subject: [PATCH 3/5] commented out possible problematic line --- .vscode/settings.json | 3 ++- src/display.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 00cd46b..cf3312a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,5 +14,6 @@ "mutex": "cpp", "regex": "cpp", "iterator": "cpp" - } + }, + "r.lsp.promptToInstall": false } \ No newline at end of file diff --git a/src/display.cpp b/src/display.cpp index 52aaa9d..fe54ad0 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -50,7 +50,7 @@ void countAvailableFrames() { void initDisplay(bool SD_enable){ // Set all chip selects high to avoid bus contention during initialisation of each peripheral - digitalWrite(22, HIGH); // Touch controller chip select (if used) + // digitalWrite(22, HIGH); // Touch controller chip select (if used) digitalWrite(15, HIGH); // TFT screen chip select digitalWrite( 5, HIGH); // SD card chips select, must use GPIO 5 (ESP32 SS) From 62b31442cfdb44e00557ab27d73e5597fe6a02df Mon Sep 17 00:00:00 2001 From: Porter Fencl Date: Sat, 22 Nov 2025 01:12:40 -0600 Subject: [PATCH 4/5] fixed --- include/IOManagement.h | 2 +- src/main.cpp | 28 ++++------------------------ 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/include/IOManagement.h b/include/IOManagement.h index f1a9e4a..f5fa71b 100644 --- a/include/IOManagement.h +++ b/include/IOManagement.h @@ -1,4 +1,4 @@ -#ifndef __IO_MANAGEMENT_H__ + #ifndef __IO_MANAGEMENT_H__ #define __IO_MANAGEMENT_H__ #include diff --git a/src/main.cpp b/src/main.cpp index 4bb78f7..4a9b962 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,36 +25,16 @@ void setup() { void loop() { // rotateColors(); + canSteering.sendSteeringData(); canSteering.runQueue(CAN_QUEUE_PERIOD); float speed = speedsig; Serial.printf("Speed: %.2f\n", speed); + Serial.printf("direction %d\n", digital_data.direction_switch); + Serial.printf("crz set %d\n", digital_data.crz_set); + updatePointer(speed); - - - - // rotateColors(); - // delay(42); - // drawSdJpeg("/test.jpg", 0, 0); - - // HeapAnim(); - - // pointer loop - // if (Serial.available()) { - // String input = Serial.readStringUntil('\n'); - // input.trim(); - - // if (input.startsWith("a")) { // ex: use a10 to set to 10 degrees - // double angle = input.substring(1).toDouble(); - // updatePointerAngle(angle); - // Serial.printf("set to angle: %.2f deg\n", angle); - // } else { - // int value = input.toInt(); // otherwise use integer method - // updatePointer(value); - // Serial.printf("set to value: %d\n", value); - // } - // } } From 5002e7018444c9004b6c3a1e82e8fe9b9b531748 Mon Sep 17 00:00:00 2001 From: Wenmiaojia Date: Sun, 15 Feb 2026 16:00:15 -0600 Subject: [PATCH 5/5] feat: add centered X battery fault icon and CAN parsing --- include/canSteering.h | 2 ++ include/display.h | 1 + platformio.ini | 1 + src/canSteering.cpp | 11 +++++++++++ src/display.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/main.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/include/canSteering.h b/include/canSteering.h index 1c5a318..83a7c25 100644 --- a/include/canSteering.h +++ b/include/canSteering.h @@ -7,6 +7,8 @@ #include "IOManagement.h" #define CAN_QUEUE_PERIOD 50 +//Globla BMS for fault indication, set to true if BPS fault is detected +extern bool bps_fault; class CANSteering : public ESP32CANManager { public: diff --git a/include/display.h b/include/display.h index 7cf9692..48ccc87 100644 --- a/include/display.h +++ b/include/display.h @@ -38,5 +38,6 @@ void HeapDispFrame(int frameIndex); void convertTextToBinaryFrames(const char* textFilePath); +void drawBatteryFault(bool active); #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 167f0ee..af8d526 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,6 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] +monitor_speed = 115200 platform = espressif32 board = esp32dev framework = arduino diff --git a/src/canSteering.cpp b/src/canSteering.cpp index 35debce..13dc091 100644 --- a/src/canSteering.cpp +++ b/src/canSteering.cpp @@ -7,6 +7,7 @@ float stuff = 0.0; float speedsig = 0.0; bool send_success; +bool bps_fault = false; CANSteering::CANSteering(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency) : ESP32CANManager(tx, rx, tx_queue, rx_queue, frequency) {}; int CANSteering::getVehicleSpeed() { // Placeholder implementation @@ -15,6 +16,7 @@ int CANSteering::getVehicleSpeed() { } void CANSteering::readHandler(CanFrame msg) { + Serial.printf("CAN Message Received - ID: 0x%03X, DLC: %d\n", msg.identifier, msg.data_length_code); switch (msg.identifier){ case 0x200:{ stuff = *((float*)msg.data); @@ -25,6 +27,15 @@ void CANSteering::readHandler(CanFrame msg) { speedsig = *((float*)msg.data); break; } + case 0x100:{ + uint16_t failsafe_flags = + (msg.data[0] | + (msg.data[1] << 8)); + + bps_fault = (failsafe_flags & 0x01) != 0; // Check if the least significant bit is set for BPS fault + + break; + } default: break; } diff --git a/src/display.cpp b/src/display.cpp index 52aaa9d..acdd813 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -10,6 +10,25 @@ // JPEG decoder library #include +extern TFT_eSPI tft; +void drawFaultBattery(int x, int y, uint16_t color) { + int w = 40; // Battery body width + int h = 20; // Battery body height + int tipW = 4; // The positive terminal nub width + int pad = 5; // Padding so the X doesn't touch the edges + + // 1. Draw the Battery Outline + tft.drawRect(x, y, w, h, color); + + // 2. Draw the Terminal Tip (centered vertically on the right) + tft.fillRect(x + w, y + (h/4), tipW, h/2, color); + + // 3. Draw the 'X' inside the body + // Line: Top-Left to Bottom-Right + tft.drawLine(x + pad, y + pad, x + w - pad, y + h - pad, color); + // Line: Top-Right to Bottom-Left + tft.drawLine(x + w - pad, y + pad, x + pad, y + h - pad, color); +} // Frame file pattern - will use: /bsr/frame0.bin, /bsr/frame1.bin, etc. const char* FRAME_FILE_PATTERN = "/output_frames/frame%d.bin"; @@ -30,6 +49,24 @@ uint8_t *frameHeap = NULL; //Array of random colors to cycle through uint16_t colors[] = {TFT_RED, TFT_GREEN, TFT_BLUE, TFT_YELLOW, TFT_CYAN, TFT_MAGENTA}; +void drawBatteryFault(bool active){ +static bool lastState = false; + int posX = 43; + int posY = 20; + + if (active != lastState) { + if (active) { + // Draw the Error Battery in Red + drawFaultBattery(posX, posY, TFT_RED); + } else { + // Wipe the area with Black if the fault is cleared + // We clear 45 pixels width to include the battery tip + tft.fillRect(posX, posY, 45, 21, TFT_BLACK); + } + lastState = active; + } +} + void rotateColors() { static uint8_t colorIndex = 0; tft.fillScreen(colors[colorIndex]); diff --git a/src/main.cpp b/src/main.cpp index 4bb78f7..266caf3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,7 @@ #include "pointer.h" #include "canSteering.h" -#define CAN_TX 21 +#define CAN_TX 21 #define CAN_RX 22 CANSteering canSteering(CAN_TX, CAN_RX, 10, 10, 250); @@ -14,12 +14,30 @@ extern float speedsig; void setup() { Serial.begin(115200); + delay(1000); // Wait for serial to initialize + Serial.println("Starting..."); initIO(); begin(); // initialize pointer display + CanFrame testBPS; + testBPS.identifier = 0x100; + testBPS.data_length_code = 2; + testBPS.data[0] = 0x01; // Simulate BMS FAILSAFE ACTIVE + testBPS.data[1] = 0x00; + canSteering.readHandler(testBPS); + + + CanFrame testSpeed; + testSpeed.identifier = 0x201; + testSpeed.data_length_code = 4; + float fakeSpeed = 75.5f; + memcpy(testSpeed.data, &fakeSpeed, 4); + canSteering.readHandler(testSpeed); + // drawSdJpeg("/bsr/Jonathan.jpeg", 130, 0); // HeapAnim(); + Serial.println("Manual Injection Complete. BPS should be YES, Speed should be 75.5"); Serial.println("Setup done."); } @@ -32,7 +50,27 @@ void loop() { Serial.printf("Speed: %.2f\n", speed); - updatePointer(speed); + updatePointer(speed); + + drawBatteryFault(bps_fault); + + Serial.begin(115200); + + // // Temporary test frame + // // CanFrame test; + // // test.identifier = 0x100; + // // test.data_length_code = 2; + + // // Simulate BMS FAILSAFE ACTIVE + // test.data[0] = 0x01; + // test.data[1] = 0x00; + + // canSteering.readHandler(test); + // Serial.println(bps_fault ? "⚠️ BPS WARNING ON" : "BPS OK"); + static unsigned long lastPrint = 0; + if (millis() - lastPrint > 500) { + Serial.printf("LIVE BUS - Speed: %.2f | BPS Fault: %s\n", speed, bps_fault ? "YES" : "NO"); + lastPrint = millis(); @@ -58,3 +96,4 @@ void loop() { // } // } } +}