From c62563a65953a61dfac3eca534be6099a8e295c4 Mon Sep 17 00:00:00 2001 From: Wenmiaojia Date: Sun, 2 Nov 2025 12:31:27 -0600 Subject: [PATCH 1/4] 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/4] 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/4] 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/4] 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); - // } - // } }