finished state machine

This commit is contained in:
Sem van der Hoeven
2023-10-30 23:45:38 +01:00
parent 892ea7d725
commit ef4ed9b617
6 changed files with 264 additions and 96 deletions

View File

@@ -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;
// }
}

View File

@@ -2,7 +2,8 @@
#define OBD2_DISPLAY_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* display size */

View File

@@ -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));
}

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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