Compare commits

...

13 Commits

9 changed files with 315 additions and 12 deletions

2
.clang-format Normal file
View File

@@ -0,0 +1,2 @@
BasedOnStyle: LLVM
BreakBeforeBraces: Attach

View File

@@ -12,3 +12,7 @@
platform = atmelavr
board = megaatmega2560
framework = arduino
monitor_speed = 115200
lib_deps =
marcoschwartz/LiquidCrystal_I2C@^1.1.4
mikalhart/TinyGPSPlus@^1.1.0

14
src/custom_types.h Normal file
View File

@@ -0,0 +1,14 @@
#include <inttypes.h>
#define CONFIG_MAGIC 0xBEEF
typedef struct vehicle_config{
uint16_t magic = CONFIG_MAGIC;
bool auto_detect_track = true;
uint8_t num_tracks = 0;
uint8_t selected_track = 0;
};
typedef struct track_data {
char name[64];
};

5
src/flags.h Normal file
View File

@@ -0,0 +1,5 @@
#define INFO
#define WARN
#define ERROR
#define DEBUG
#define DEEP_DEBUG

View File

@@ -1,18 +1,42 @@
#include "flags.h"
#include "modules/config/config.h"
#include "modules/gps/gps.h"
#include "modules/lcd/lcd.h"
#include "modules/logger/system_logger.h"
#include <Arduino.h>
// put function declarations here:
int myFunction(int, int);
system_logger *logger_output = new system_logger(&Serial);
lcd *driver_display = new lcd(logger_output);
gps *gps_module = new gps(&Serial2, logger_output);
config *system_config = new config(logger_output);
void setup() {
// put your setup code here, to run once:
int result = myFunction(2, 3);
driver_display->init();
driver_display->print_message("Starting Initialization");
delay(1000);
driver_display->print_message("Serial Init...");
Serial.begin(115200);
delay(500);
driver_display->print_message("Serial Init Complete");
delay(500);
driver_display->print_message("Config Init...");
int result = system_config->auto_init();
delay(500);
if (result != 0) {
driver_display->print_message("Configuration Read Failed");
} else {
driver_display->print_message("Config Init Complete");
}
delay(500);
driver_display->print_message("GPS Init...");
gps_module->init();
delay(500);
driver_display->print_message("GPS Init Complete");
}
void loop() {
// put your main code here, to run repeatedly:
}
// put function definitions here:
int myFunction(int x, int y) {
return x + y;
}
void loop() { gps_module->parse_task(500); }

View File

@@ -0,0 +1,46 @@
#pragma once
#include "custom_types.h"
#include "flags.h"
#include "modules/logger/system_logger.h"
#include <EEPROM.h>
class config {
private:
vehicle_config _config;
system_logger *_logger;
bool _valid_config;
public:
config();
config(system_logger *logger);
~config();
int auto_init();
};
config::config() : _logger(nullptr), _valid_config(true) {}
config::config(system_logger *logger) : _logger(logger), _valid_config(true) {}
config::~config() {}
int config::auto_init() {
EEPROM.get(0, _config);
if (_config.magic != CONFIG_MAGIC) {
#ifdef WARN
if (_logger != nullptr) {
_logger->warn("Config invalid, overwriting");
}
#endif
vehicle_config clean_config;
EEPROM.put(0, clean_config);
EEPROM.get(0, _config);
if (_config.magic != CONFIG_MAGIC) {
#ifdef ERROR
if (_logger != nullptr) {
_logger->error("Config write failed, EEPROM may be burnt");
}
#endif
return 1;
}
}
_valid_config = true;
return 0;
}

59
src/modules/gps/gps.h Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include "TinyGPSPlus.h"
#include "flags.h"
#include "modules/logger/system_logger.h"
class gps {
private:
TinyGPSPlus *_gps;
HardwareSerial *_data_stream;
system_logger *_logger;
bool _lock_valid = false;
unsigned long _last_lock = 0;
public:
gps(HardwareSerial *data_stream);
gps(HardwareSerial *data_stream, system_logger *logger);
~gps();
int parse_task(unsigned long timeout_ms = 500);
int init();
};
gps::gps(HardwareSerial *data_stream) : _data_stream(data_stream), _logger(nullptr){
_data_stream = data_stream;
_gps = new TinyGPSPlus();
}
gps::gps(HardwareSerial *data_stream, system_logger *logger)
: _data_stream(data_stream), _logger(logger) {
_gps = new TinyGPSPlus();
}
gps::~gps() {
_data_stream = nullptr;
delete _gps;
}
int gps::init() {
_data_stream->begin(9600);
return 0;
}
int gps::parse_task(unsigned long timeout_ms) {
unsigned long timeout = millis() + timeout_ms;
while (_data_stream->available() > 0) {
if (_gps->encode(_data_stream->read())) {
_lock_valid = true;
_last_lock = millis();
}
if (millis() > timeout) {
#ifdef DEBUG
if (_logger != nullptr) {
_logger->debug("GPS Parser timed out, exiting task");
}
#endif
return 1;
}
}
return 0;
}

68
src/modules/lcd/lcd.h Normal file
View File

@@ -0,0 +1,68 @@
#pragma once
#define MOD "modules/lcd/lcd.h"
#include "flags.h"
#include "modules/logger/system_logger.h"
#include <LiquidCrystal_I2C.h>
class lcd {
private:
LiquidCrystal_I2C *_display;
system_logger *_logger = nullptr;
public:
lcd();
lcd(system_logger *logger);
~lcd();
int init();
int print_message(String message);
};
lcd::lcd() { _display = new LiquidCrystal_I2C(0x27, 20, 4); }
lcd::lcd(system_logger *logger) {
_display = new LiquidCrystal_I2C(0x27, 20, 4);
_logger = logger;
}
lcd::~lcd() {}
int lcd::init() {
#ifdef DEEP_DEBUG
if (_logger != nullptr) {
_logger->debug(String(MOD) + ": LCD init Begin");
}
#endif
_display->init();
_display->backlight();
_display->clear();
_display->setCursor(0, 0);
#ifdef DEEP_DEBUG
if (_logger != nullptr) {
_logger->debug(String(MOD) + ": LCD init End");
}
#endif
return 0;
}
int lcd::print_message(String message) {
#ifdef DEEP_DEBUG
if (_logger != nullptr) {
_logger->debug(String(MOD) + ": LCD print_message Begin");
}
#endif
_display->clear();
_display->setCursor(0, 0);
_display->print(message);
#ifdef INFO
if (_logger != nullptr) {
_logger->info(message);
}
#endif
#ifdef DEEP_DEBUG
if (_logger != nullptr) {
_logger->debug(String(MOD) + ": LCD print_message End");
}
#endif
return 0;
}
#undef MOD

View File

@@ -0,0 +1,81 @@
#pragma once
#include <Arduino.h>
#include "flags.h"
class system_logger
{
private:
HardwareSerial *_output;
int print_message(String pre, String message);
public:
system_logger(HardwareSerial *output);
~system_logger();
#ifdef INFO
int info(String message);
#endif
#ifdef WARN
int warn(String message);
#endif
#ifdef ERROR
int error(String message);
#endif
#ifdef DEBUG
int debug(String message);
#endif
#ifdef DEEP_DEBUG
int deep_debug(String message);
#endif
};
system_logger::system_logger(HardwareSerial *output)
{
_output = output;
}
system_logger::~system_logger()
{
}
int system_logger::print_message(String pre, String message) {
if (_output->availableForWrite()) {
_output->print(millis());
_output->print(pre);
_output->println(message);
return 0;
}
return 1;
}
#ifdef INFO
int system_logger::info(String message) {
return this->print_message(" [INFO] ", message);
}
#endif
#ifdef WARN
int system_logger::warn(String message) {
return this->print_message(" [WARNING] ", message);
}
#endif
#ifdef ERROR
int system_logger::error(String message) {
return this->print_message(" [ERROR] ", message);
}
#endif
#ifdef DEBUG
int system_logger::debug(String message) {
return this->print_message(" [DEBUG] ", message);
}
#endif
#ifdef DEEP_DEBUG
int system_logger::deep_debug(String message) {
return this->print_message(" [DEEP_DEBUG] ", message);
}
#endif