diff --git a/.vscode/settings.json b/.vscode/settings.json index 08ab831..cf3312a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,8 @@ "random": "cpp", "initializer_list": "cpp", "mutex": "cpp", - "regex": "cpp" - } + "regex": "cpp", + "iterator": "cpp" + }, + "r.lsp.promptToInstall": false } \ 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/IOManagement.h b/include/IOManagement.h index 00dd35e..f5fa71b 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 9c6cd04..1c5a318 100644 --- a/include/canSteering.h +++ b/include/canSteering.h @@ -1,15 +1,21 @@ -// #ifndef __CAN_STEERING_H__ -// #define __CAN_STEERING_H__ -// #include "canmanager.h" -// #include "IOManagement.h" +#ifndef __CAN_STEERING_H__ +#define __CAN_STEERING_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(); -// }; +#include +#include "esp32canmanager.h" +#include "IOManagement.h" -// #endif \ No newline at end of file +#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(); + + 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 ac5d618..35debce 100644 --- a/src/canSteering.cpp +++ b/src/canSteering.cpp @@ -1,12 +1,40 @@ -// #include "canSteering.h" -// CANSteering::CANSteering(CAN_TypeDef* canPort, CAN_PINS pins, int frequency) : CANManager(canPort, pins, frequency) {}; +#include "canSteering.h" -// void CANSteering::readHandler(CAN_message_t msg) { - -// } +#define MAX_ANALOG_VALUE 4095 -// 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 +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; + } + + +} + +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..fe54ad0 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; @@ -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) diff --git a/src/main.cpp b/src/main.cpp index fece7b5..4a9b962 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,22 @@ #include #include "display.h" #include "pointer.h" +#include "canSteering.h" + +#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(false); + initIO(); + begin(); // initialize pointer display // drawSdJpeg("/bsr/Jonathan.jpeg", 130, 0); // HeapAnim(); @@ -13,25 +24,17 @@ void setup() { } void loop() { - rotateColors(); - // delay(42); - // drawSdJpeg("/test.jpg", 0, 0); + // rotateColors(); + canSteering.sendSteeringData(); + canSteering.runQueue(CAN_QUEUE_PERIOD); - // HeapAnim(); + float speed = speedsig; - // 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); - // } - // } + 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); } diff --git a/src/pointer.cpp b/src/pointer.cpp index 7dfdfc2..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 @@ -57,4 +59,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