/** Program to create a car monitor display using: - Arduino Due - a TFT display (https://www.tinytronics.nl/shop/en/displays/tft/3.5-inch-tft-display-320*480-pixels-mega-compatible-ili9486) - ELM327 Bluetooth OBD2 scanner - FSC-DB004 (BT 836B) bluetooth module */ #include "Arduino.h" /* include UTFT library */ #include #include // #include "obd2_timer.h" #include "obd2_display.h" #include "statemachine.h" #define DEBUG 1 // #define RTT_MR 0x400E1A30U /* pins */ #define PIN_BT_RX 19 #define PIN_BT_TX 18 #define PIN_BT_STATE 3 /* connected/disconnected state of BT */ #define MS(x) x * 1000 #define S(x) MS(x) * 1000 #define INIT_TEXT_WIDTH 15 #define FLAG_INIT_UPDATE_TEXT_POS 0x01 #define FLAG_INIT_CLEAR_POS 0x02 #define FLAG_INIT_UPDATE_PERCENT_POS 0x03 extern uint8_t BigFont[]; extern uint8_t SmallFont[]; extern uint8_t OCR_A_Extended_M[]; char should_clear = 1; char led_state = LOW; char init_flag = 0; char init_text_i = -1; int init_text_x = 100; char init_text[] PROGMEM = "Initialising..."; char text_temp[2] = {'a', '\0'}; int init_percent = 0; void on_init_enter(); void on_init_run(); void on_init_exit(); void on_main_enter(); void on_main_run(); void __state_none() { /* do nothing */ } state_t init_state = { .id = STATE_INIT, .next = STATE_INIT, .on_enter = &on_init_enter, .on_run = &on_init_run, .on_exit = &on_init_exit}; state_t main_state = { .id = STATE_CAR_INFO, .next = STATE_CAR_INFO, .on_enter = &on_main_enter, .on_run = &on_main_run, .on_exit = &__state_none}; /* Set the pins for the display and dev board */ /* Standard Arduino Mega/Due shield : ,38,39,40,41 */ UTFT display(ILI9486, 38, 39, 40, 41); /****************************/ /*INIT STATE*/ /****************************/ void on_init_enter() { display.clrScr(); Timer0.attachInterrupt(update_init_text); Timer0.start(MS(200)); // TODO change to update when initializing bluetooth.. Timer1.attachInterrupt(update_percent_test); Timer1.start(MS(60)); Serial.println("Entering init state!"); } void on_init_run() { if (init_flag & (1 << FLAG_INIT_CLEAR_POS)) { init_flag &= ~(1 << FLAG_INIT_CLEAR_POS); display.setColor(VGA_BLACK); /*clear only initializing text*/ display.print(" ",(display.getDisplayXSize() / 2) - (INIT_TEXT_WIDTH * display.getFontXsize() / 2),display.getDisplayYSize() / 2 + 50); } if (init_flag & (1 << FLAG_INIT_UPDATE_TEXT_POS)) { init_flag &= ~(1 << FLAG_INIT_UPDATE_TEXT_POS); display.setColor(VGA_AQUA); int x_position = (display.getDisplayXSize() / 2 - (INIT_TEXT_WIDTH * display.getFontXsize() / 2)) + (init_text_i * display.getFontXsize()); Serial.println(x_position); text_temp[0] = init_text[init_text_i]; display.print(text_temp, x_position, display.getDisplayYSize() / 2 + 50); // print as string with one character } if (init_flag & (1 << FLAG_INIT_UPDATE_PERCENT_POS)) { init_flag &= ~(1 << FLAG_INIT_UPDATE_PERCENT_POS); int percent_x_pos = (display.getDisplayXSize() / 2 - (INIT_TEXT_WIDTH * display.getFontXsize() / 2)) + (INIT_TEXT_WIDTH * display.getFontXsize()); display.setColor(VGA_BLACK); /*clear text region for percent*/ display.print(" ", percent_x_pos, display.getDisplayYSize() / 2 + 50); display.setColor(VGA_FUCHSIA); char *percent_text = (char *)malloc(3 * sizeof(char)); sprintf(percent_text, "%d", init_percent); display.print(percent_text, percent_x_pos, display.getDisplayYSize() / 2 + 50); display.print("%", percent_x_pos + 3 * display.getFontXsize(), display.getDisplayYSize() / 2 + 50); free(percent_text); } } void on_init_exit() { Serial.println("Exiting init state!"); display.clrScr(); Timer0.stop(); } /****************************/ /*MAIN STATE*/ /****************************/ void on_main_enter() { Serial.println("Entering main loop"); } void on_main_run() { delay(500); Serial.println("main!"); } void update_init_text() { init_text_i++; if (init_text_i == 15) { init_text_i = 0; init_flag |= (1 << FLAG_INIT_CLEAR_POS); } init_flag |= (1 << FLAG_INIT_UPDATE_TEXT_POS); } void update_percent_test() { init_percent++; if (init_percent > 100) { init_percent = 0; } init_flag |= (1 << FLAG_INIT_UPDATE_PERCENT_POS); } void setup() { /* TODO change for TRNG (section 42 of datasheet)*/ randomSeed(analogRead(0)); #if (DEBUG == 1) Serial.begin(9600); #endif /* Serial1 is bluetooth module, pin 18 and 19. */ Serial1.begin(115200); /* Init display */ display.InitLCD(); display.setFont(OCR_A_Extended_M); #if (DEBUG == 1) Serial.println("Starting"); #endif pinMode(LED_BUILTIN, OUTPUT); statemachine_register_state(&init_state, STATE_INIT); statemachine_register_state(&main_state, STATE_CAR_INFO); statemachine_init(); } void loop() { statemachine_loop(); // Serial.println("Running"); // delay(10); // while (Serial1.available()) // { // char rec = Serial1.read(); // #if (DEBUG == 1) // Serial.println(rec); // #endif // } // if (should_clear) // { // display.clrScr(); // display.setColor(255, 0, 166); // display.fillRect(LCD_W / 2 - 200, LCD_H / 2 - 100, LCD_W / 2 + 200, LCD_H / 2 + 100); // display.setColor(0, 247, 255); // display.print("OBD2 display yeet", CENTER, LCD_H / 2); // delay(10); // should_clear = 0; // } }