mirror of
https://github.com/SemvdH/OBD2-car-display.git
synced 2025-12-14 19:51:04 +00:00
finished state machine
This commit is contained in:
@@ -28,32 +28,112 @@ extern uint8_t SmallFont[];
|
||||
char should_clear = 1;
|
||||
char led_state = LOW;
|
||||
char flag = 0;
|
||||
char counter_temp = 0;
|
||||
char main_color = 0;
|
||||
char init_text_i = 0;
|
||||
int init_text_x = 100;
|
||||
char init_text[] = "Initialising...";
|
||||
char text_temp[2] = {'a','\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_CAR_INFO,
|
||||
.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 : <display model>,38,39,40,41 */
|
||||
UTFT display(ILI9486,38,39,40,41);
|
||||
UTFT display(ILI9486, 38, 39, 40, 41);
|
||||
|
||||
void setup() {
|
||||
randomSeed(analogRead(0));
|
||||
void on_init_enter()
|
||||
{
|
||||
display.clrScr();
|
||||
Serial.println("Entering init state!");
|
||||
}
|
||||
|
||||
#if (DEBUG == 1)
|
||||
Serial.begin(9600);
|
||||
#endif
|
||||
/* Serial1 is bluetooth module, pin 18 and 19. */
|
||||
Serial1.begin(115200);
|
||||
void on_init_run()
|
||||
{
|
||||
Serial.println("Running!");
|
||||
if (!flag)
|
||||
{
|
||||
flag = 1;
|
||||
main_color = ~main_color;
|
||||
// display.clrScr();
|
||||
if (main_color)
|
||||
{
|
||||
display.setColor(VGA_RED);
|
||||
display.fillCircle(10,20,100);
|
||||
} else
|
||||
{
|
||||
display.setColor(VGA_TEAL);
|
||||
display.fillCircle(30,50,131);
|
||||
}
|
||||
display.setColor(VGA_AQUA);
|
||||
display.setBackColor(0,0,0);
|
||||
text_temp[0] = init_text[init_text_i];
|
||||
display.print(text_temp, init_text_x, LCD_H / 2);
|
||||
init_text_x += display.getFontXsize();
|
||||
init_text_i++;
|
||||
if (init_text_i > 14)
|
||||
{
|
||||
init_text_i = 0;
|
||||
display.clrScr();
|
||||
}
|
||||
}
|
||||
|
||||
/* Init display */
|
||||
display.InitLCD();
|
||||
display.setFont(BigFont);
|
||||
}
|
||||
|
||||
#if (DEBUG == 1)
|
||||
Serial.println("Starting");
|
||||
#endif
|
||||
void on_init_exit()
|
||||
{
|
||||
Serial.println("Exiting init state!");
|
||||
flag = 0;
|
||||
main_color = 0;
|
||||
display.clrScr();
|
||||
}
|
||||
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
|
||||
obd2_timer_init();
|
||||
void on_main_enter()
|
||||
{
|
||||
obd2_timer_reset();
|
||||
Serial.println("Entering main loop");
|
||||
obd2_timer_set_period(800);
|
||||
}
|
||||
|
||||
void on_main_run()
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
led_state = ~led_state;
|
||||
digitalWrite(LED_BUILTIN, led_state);
|
||||
flag = 1;
|
||||
main_color = ~main_color;
|
||||
if (main_color)
|
||||
display.setColor(255, 0, 166);
|
||||
else
|
||||
display.setColor(78, 181, 72);
|
||||
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);
|
||||
#if (DEBUG == 1)
|
||||
Serial.println("switching led");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void RTT_Handler()
|
||||
@@ -62,33 +142,60 @@ void RTT_Handler()
|
||||
obd2_timer_reset();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
while (Serial1.available()) {
|
||||
char rec = Serial1.read();
|
||||
#if (DEBUG == 1)
|
||||
Serial.println(rec);
|
||||
#endif
|
||||
}
|
||||
void setup()
|
||||
{
|
||||
randomSeed(analogRead(0));
|
||||
|
||||
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;
|
||||
}
|
||||
#if (DEBUG == 1)
|
||||
Serial.begin(9600);
|
||||
#endif
|
||||
/* Serial1 is bluetooth module, pin 18 and 19. */
|
||||
Serial1.begin(115200);
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
led_state = ~led_state;
|
||||
digitalWrite(LED_BUILTIN, led_state);
|
||||
flag = 1;
|
||||
#if (DEBUG == 1)
|
||||
Serial.println("switching led");
|
||||
#endif
|
||||
}
|
||||
/* Init display */
|
||||
display.InitLCD();
|
||||
display.setFont(BigFont);
|
||||
|
||||
#if (DEBUG == 1)
|
||||
Serial.println("Starting");
|
||||
#endif
|
||||
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
|
||||
obd2_timer_init();
|
||||
statemachine_register_state(&init_state, STATE_INIT);
|
||||
statemachine_register_state(&main_state, STATE_CAR_INFO);
|
||||
statemachine_init();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
statemachine_loop();
|
||||
|
||||
counter_temp++;
|
||||
if (counter_temp == 50)
|
||||
{
|
||||
statemachine_next();
|
||||
}
|
||||
|
||||
delay(100);
|
||||
// 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;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#define OBD2_DISPLAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* display size */
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
#include "sam3xa/include/sam3x8e.h"
|
||||
#include "sam3xa/include/component/component_rtt.h"
|
||||
// #include "sam3xa/include/component/component_rtt.h"
|
||||
// #include "sam3xa/include/sam3x8e.h"
|
||||
#include "obd2_timer.h"
|
||||
|
||||
void obd2_timer_init(void)
|
||||
{
|
||||
/* enable the timer: reset the RTT, enable the alarm interrupt, set the prescaler value equal to the processor clock speed*/
|
||||
RTT->RTT_MR = RTT_MR_RTTRST | RTT_MR_ALMIEN | RTT_MR_RTPRES(32768/2);
|
||||
/* set the alarm value to 0*/
|
||||
RTT->RTT_AR = 0;
|
||||
/* enable the interrupt*/
|
||||
NVIC_EnableIRQ(RTT_IRQn);
|
||||
/* enable the timer: reset the RTT
|
||||
RTT->RTT_MR = RTT_MR_RTTRST;
|
||||
/* set the alarm value to 0*/
|
||||
RTT->RTT_AR = 0;
|
||||
}
|
||||
|
||||
void obd2_timer_enable()
|
||||
{
|
||||
/* enable the alarm interrupt*/
|
||||
RTT->RTT_MR |= RTT_MR_ALMIEN;
|
||||
|
||||
/* enable the interrupt*/
|
||||
NVIC_EnableIRQ(RTT_IRQn);
|
||||
}
|
||||
|
||||
void obd2_timer_reset()
|
||||
{
|
||||
/* To prevent several executions of the interrupt handler,
|
||||
the interrupt must be disabled in the interrupt handler
|
||||
and re-enabled when the status register is cleared.
|
||||
*/
|
||||
/* To prevent several executions of the interrupt handler,
|
||||
the interrupt must be disabled in the interrupt handler
|
||||
and re-enabled when the status register is cleared.
|
||||
*/
|
||||
/* disable interrupts */
|
||||
RTT->RTT_MR &= ~RTT_MR_ALMIEN;
|
||||
/* clear the status register (reading it clears it)
|
||||
@@ -30,5 +39,10 @@ void obd2_timer_reset()
|
||||
RTT->RTT_MR |= RTT_MR_ALMIEN;
|
||||
/* reset the RTT*/
|
||||
RTT->RTT_MR |= RTT_MR_RTTRST;
|
||||
|
||||
}
|
||||
|
||||
void obd2_timer_set_period(__UINT32_TYPE__ period)
|
||||
{
|
||||
/* set the prescaler value equal to the clock speed divided by how many milliseconds*/
|
||||
RTT->RTT_MR |= RTT_MR_RTPRES(CLOCK_FREQ / (1000/period));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef OBD2_TIMER_H
|
||||
#define OBD2_TIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "Arduino.h"
|
||||
@@ -10,6 +12,8 @@
|
||||
|
||||
void obd2_timer_init();
|
||||
void obd2_timer_reset();
|
||||
void obd2_timer_enable();
|
||||
void obd2_timer_set_period(__UINT32_TYPE__ period);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,19 +1,60 @@
|
||||
#include "statemachine.h"
|
||||
|
||||
state_t none_state =
|
||||
{
|
||||
.id = 0,
|
||||
.on_enter = &__state_none,
|
||||
.on_run = &__state_none,
|
||||
.on_exit = &__state_none,
|
||||
int current_state_id = 0;
|
||||
state_t states[STATE_AMOUNT] = {NULL, NULL};
|
||||
__UINT8_TYPE__ next = 0;
|
||||
|
||||
__UINT8_TYPE__ statemachine_register_state(state_t *state, int index)
|
||||
{
|
||||
if (index >= STATE_AMOUNT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (state->id != index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
states[index] = *state;
|
||||
return 1;
|
||||
}
|
||||
statemachine_t statemachine =
|
||||
{
|
||||
.current_state =
|
||||
};
|
||||
|
||||
void statemachine_init()
|
||||
__UINT8_TYPE__ statemachine_init()
|
||||
{
|
||||
for (int i = 0; i < STATE_AMOUNT; i++)
|
||||
{
|
||||
if (states[i].id < 0 || states[i].next < 0 || states[i].on_enter == NULL || states[i].on_run == NULL || states[i].on_exit == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
current_state_id = 0;
|
||||
states[current_state_id].on_enter();
|
||||
}
|
||||
|
||||
void statemachine_loop()
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
next = 0;
|
||||
|
||||
if (states[current_state_id].on_exit != NULL)
|
||||
{
|
||||
states[current_state_id].on_exit();
|
||||
}
|
||||
if (states[current_state_id].next >= 0 && states[current_state_id].next != current_state_id)
|
||||
{
|
||||
current_state_id = states[current_state_id].next;
|
||||
}
|
||||
states[current_state_id].on_enter();
|
||||
}
|
||||
|
||||
if (states[current_state_id].on_run != NULL)
|
||||
{
|
||||
states[current_state_id].on_run();
|
||||
}
|
||||
}
|
||||
|
||||
void statemachine_next()
|
||||
{
|
||||
next = 1;
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
#ifndef STATEMACHINE_H
|
||||
#define STATEMACHINE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define STATE_INIT 0
|
||||
#define STATE_CAR_INFO 1
|
||||
|
||||
#define STATE_AMOUNT 2 /* change when more states are added */
|
||||
|
||||
/* two displays:
|
||||
- initialisation display, shows the state of booting up
|
||||
- main display, shows the data from the OBD2 scanner
|
||||
@@ -16,44 +22,39 @@
|
||||
|
||||
/**
|
||||
* @brief State struct. Contains the id of the state, and the functions that are called when the state is entered, running and exited.
|
||||
*/
|
||||
*/
|
||||
typedef struct SM_STATE
|
||||
{
|
||||
int id;
|
||||
int next;
|
||||
void (*on_enter)();
|
||||
void (*on_run)();
|
||||
void (*on_exit)();
|
||||
} state_t;
|
||||
|
||||
/**
|
||||
* @brief Transition struct. Contains the id of the state it transitions to, and the next state.
|
||||
*/
|
||||
typedef struct SM_TRANSITION
|
||||
{
|
||||
int state_id;
|
||||
state_t *next_state;
|
||||
} transition_t;
|
||||
|
||||
/**
|
||||
* @brief State machine struct. Contains the current state and the transitions.
|
||||
*/
|
||||
typedef struct SM_STATE_MACHINE
|
||||
{
|
||||
state_t *current_state;
|
||||
transition_t *transitions; /* Transitions between states. Every state's ID is also it's position in the array.*/
|
||||
|
||||
} statemachine_t;
|
||||
|
||||
/**
|
||||
* @brief Initialises the state machine. Initializes the statemachine struct.
|
||||
*/
|
||||
void statemachine_init();
|
||||
void __state_none()
|
||||
{
|
||||
/* do nothing*/
|
||||
}
|
||||
__UINT8_TYPE__ statemachine_init();
|
||||
/**
|
||||
* @brief Main loop of the state machine. executes the on_run function of the current state.
|
||||
*/
|
||||
void statemachine_loop();
|
||||
|
||||
/**
|
||||
* @brief Changes the state of the state machine to the next state. Calls the exit function of the current state and the enter function of the next state.
|
||||
*/
|
||||
void statemachine_next();
|
||||
|
||||
/**
|
||||
* @brief Registers a state in the state machine.
|
||||
* @param state The state to add
|
||||
* @param index The index of the state in the array. Must be the same as the id of the state.
|
||||
* @return 1 if the state was added successfully, 0 if not.
|
||||
*/
|
||||
__UINT8_TYPE__ statemachine_register_state(state_t *state, int index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif // !STATEMACHINE_H
|
||||
|
||||
Reference in New Issue
Block a user