mirror of
https://github.com/SemvdH/OBD2-car-display.git
synced 2025-12-16 04:31:04 +00:00
finished state machine
This commit is contained in:
@@ -28,32 +28,112 @@ extern uint8_t SmallFont[];
|
|||||||
char should_clear = 1;
|
char should_clear = 1;
|
||||||
char led_state = LOW;
|
char led_state = LOW;
|
||||||
char flag = 0;
|
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 */
|
/* Set the pins for the display and dev board */
|
||||||
/* Standard Arduino Mega/Due shield : <display model>,38,39,40,41 */
|
/* 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() {
|
void on_init_enter()
|
||||||
randomSeed(analogRead(0));
|
{
|
||||||
|
display.clrScr();
|
||||||
|
Serial.println("Entering init state!");
|
||||||
|
}
|
||||||
|
|
||||||
#if (DEBUG == 1)
|
void on_init_run()
|
||||||
Serial.begin(9600);
|
{
|
||||||
#endif
|
Serial.println("Running!");
|
||||||
/* Serial1 is bluetooth module, pin 18 and 19. */
|
if (!flag)
|
||||||
Serial1.begin(115200);
|
{
|
||||||
|
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)
|
void on_init_exit()
|
||||||
Serial.println("Starting");
|
{
|
||||||
#endif
|
Serial.println("Exiting init state!");
|
||||||
|
flag = 0;
|
||||||
|
main_color = 0;
|
||||||
|
display.clrScr();
|
||||||
|
}
|
||||||
|
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
void on_main_enter()
|
||||||
|
{
|
||||||
obd2_timer_init();
|
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()
|
void RTT_Handler()
|
||||||
@@ -62,33 +142,60 @@ void RTT_Handler()
|
|||||||
obd2_timer_reset();
|
obd2_timer_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void setup()
|
||||||
// put your main code here, to run repeatedly:
|
{
|
||||||
while (Serial1.available()) {
|
randomSeed(analogRead(0));
|
||||||
char rec = Serial1.read();
|
|
||||||
#if (DEBUG == 1)
|
|
||||||
Serial.println(rec);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_clear)
|
#if (DEBUG == 1)
|
||||||
{
|
Serial.begin(9600);
|
||||||
display.clrScr();
|
#endif
|
||||||
display.setColor(255, 0, 166);
|
/* Serial1 is bluetooth module, pin 18 and 19. */
|
||||||
display.fillRect(LCD_W/2-200,LCD_H/2-100,LCD_W/2+200,LCD_H/2+100);
|
Serial1.begin(115200);
|
||||||
display.setColor(0, 247, 255);
|
|
||||||
display.print("OBD2 display yeet",CENTER,LCD_H/2);
|
|
||||||
delay(10);
|
|
||||||
should_clear = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!flag)
|
/* Init display */
|
||||||
{
|
display.InitLCD();
|
||||||
led_state = ~led_state;
|
display.setFont(BigFont);
|
||||||
digitalWrite(LED_BUILTIN, led_state);
|
|
||||||
flag = 1;
|
#if (DEBUG == 1)
|
||||||
#if (DEBUG == 1)
|
Serial.println("Starting");
|
||||||
Serial.println("switching led");
|
#endif
|
||||||
#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
|
#define OBD2_DISPLAY_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* display size */
|
/* 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/component/component_rtt.h"
|
||||||
// #include "sam3xa/include/sam3x8e.h"
|
// #include "sam3xa/include/sam3x8e.h"
|
||||||
#include "obd2_timer.h"
|
#include "obd2_timer.h"
|
||||||
|
|
||||||
void obd2_timer_init(void)
|
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*/
|
/* enable the timer: reset the RTT
|
||||||
RTT->RTT_MR = RTT_MR_RTTRST | RTT_MR_ALMIEN | RTT_MR_RTPRES(32768/2);
|
RTT->RTT_MR = RTT_MR_RTTRST;
|
||||||
/* set the alarm value to 0*/
|
/* set the alarm value to 0*/
|
||||||
RTT->RTT_AR = 0;
|
RTT->RTT_AR = 0;
|
||||||
/* enable the interrupt*/
|
}
|
||||||
NVIC_EnableIRQ(RTT_IRQn);
|
|
||||||
|
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()
|
void obd2_timer_reset()
|
||||||
{
|
{
|
||||||
/* To prevent several executions of the interrupt handler,
|
/* To prevent several executions of the interrupt handler,
|
||||||
the interrupt must be disabled in the interrupt handler
|
the interrupt must be disabled in the interrupt handler
|
||||||
and re-enabled when the status register is cleared.
|
and re-enabled when the status register is cleared.
|
||||||
*/
|
*/
|
||||||
/* disable interrupts */
|
/* disable interrupts */
|
||||||
RTT->RTT_MR &= ~RTT_MR_ALMIEN;
|
RTT->RTT_MR &= ~RTT_MR_ALMIEN;
|
||||||
/* clear the status register (reading it clears it)
|
/* clear the status register (reading it clears it)
|
||||||
@@ -30,5 +39,10 @@ void obd2_timer_reset()
|
|||||||
RTT->RTT_MR |= RTT_MR_ALMIEN;
|
RTT->RTT_MR |= RTT_MR_ALMIEN;
|
||||||
/* reset the RTT*/
|
/* reset the RTT*/
|
||||||
RTT->RTT_MR |= RTT_MR_RTTRST;
|
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
|
#ifndef OBD2_TIMER_H
|
||||||
|
#define OBD2_TIMER_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
@@ -10,6 +12,8 @@
|
|||||||
|
|
||||||
void obd2_timer_init();
|
void obd2_timer_init();
|
||||||
void obd2_timer_reset();
|
void obd2_timer_reset();
|
||||||
|
void obd2_timer_enable();
|
||||||
|
void obd2_timer_set_period(__UINT32_TYPE__ period);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,60 @@
|
|||||||
#include "statemachine.h"
|
#include "statemachine.h"
|
||||||
|
|
||||||
state_t none_state =
|
int current_state_id = 0;
|
||||||
{
|
state_t states[STATE_AMOUNT] = {NULL, NULL};
|
||||||
.id = 0,
|
__UINT8_TYPE__ next = 0;
|
||||||
.on_enter = &__state_none,
|
|
||||||
.on_run = &__state_none,
|
|
||||||
.on_exit = &__state_none,
|
|
||||||
|
|
||||||
|
__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
|
#ifndef STATEMACHINE_H
|
||||||
#define STATEMACHINE_H
|
#define STATEMACHINE_H
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#define STATE_INIT 0
|
||||||
|
#define STATE_CAR_INFO 1
|
||||||
|
|
||||||
|
#define STATE_AMOUNT 2 /* change when more states are added */
|
||||||
|
|
||||||
/* two displays:
|
/* two displays:
|
||||||
- initialisation display, shows the state of booting up
|
- initialisation display, shows the state of booting up
|
||||||
- main display, shows the data from the OBD2 scanner
|
- 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.
|
* @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
|
typedef struct SM_STATE
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
int next;
|
||||||
void (*on_enter)();
|
void (*on_enter)();
|
||||||
void (*on_run)();
|
void (*on_run)();
|
||||||
void (*on_exit)();
|
void (*on_exit)();
|
||||||
} state_t;
|
} 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.
|
* @brief Initialises the state machine. Initializes the statemachine struct.
|
||||||
*/
|
*/
|
||||||
void statemachine_init();
|
__UINT8_TYPE__ statemachine_init();
|
||||||
void __state_none()
|
/**
|
||||||
{
|
* @brief Main loop of the state machine. executes the on_run function of the current state.
|
||||||
/* do nothing*/
|
*/
|
||||||
}
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif // !STATEMACHINE_H
|
#endif // !STATEMACHINE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user