Added injection counter module
This commit is contained in:
@@ -16,6 +16,7 @@ enum Id : uint8_t {
|
|||||||
Thermocouple,
|
Thermocouple,
|
||||||
Telemetry,
|
Telemetry,
|
||||||
LapCounter,
|
LapCounter,
|
||||||
|
InjectionCounter,
|
||||||
Count,
|
Count,
|
||||||
Null,
|
Null,
|
||||||
All,
|
All,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ volatile int gps_trigger_global = 0;
|
|||||||
volatile uint32_t last_lap_time_global = 0;
|
volatile uint32_t last_lap_time_global = 0;
|
||||||
volatile uint16_t lap_count_global = 0;
|
volatile uint16_t lap_count_global = 0;
|
||||||
volatile float speed_avg_global = 0;
|
volatile float speed_avg_global = 0;
|
||||||
|
volatile uint16_t injection_ctr_global = 0;
|
||||||
|
|
||||||
void vbatGlobalRead(float &out) { out = vbat_global; }
|
void vbatGlobalRead(float &out) { out = vbat_global; }
|
||||||
|
|
||||||
@@ -33,3 +34,7 @@ void lapCountGlobalWrite(const uint16_t &in) { lap_count_global = in; }
|
|||||||
void speedAvgGlobalRead(float &out) { out = speed_avg_global; }
|
void speedAvgGlobalRead(float &out) { out = speed_avg_global; }
|
||||||
|
|
||||||
void speedAvgGlobalWrite(const float &in) { speed_avg_global = in; }
|
void speedAvgGlobalWrite(const float &in) { speed_avg_global = in; }
|
||||||
|
|
||||||
|
void injectionCtrGlobalRead(uint16_t &out) { out = injection_ctr_global; }
|
||||||
|
|
||||||
|
void injectionCtrGlobalWrite(const uint16_t &in) { injection_ctr_global = in; }
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ extern volatile int gps_trigger_global;
|
|||||||
extern volatile uint32_t last_lap_time_global;
|
extern volatile uint32_t last_lap_time_global;
|
||||||
extern volatile uint16_t lap_count_global;
|
extern volatile uint16_t lap_count_global;
|
||||||
extern volatile float speed_avg_global;
|
extern volatile float speed_avg_global;
|
||||||
|
extern volatile uint16_t injection_ctr_global;
|
||||||
|
|
||||||
void vbatGlobalRead(float& out);
|
void vbatGlobalRead(float& out);
|
||||||
void vbatGlobalWrite(const float& in);
|
void vbatGlobalWrite(const float& in);
|
||||||
@@ -28,3 +29,6 @@ void lapCountGlobalWrite(const uint16_t& in);
|
|||||||
|
|
||||||
void speedAvgGlobalRead(float& out);
|
void speedAvgGlobalRead(float& out);
|
||||||
void speedAvgGlobalWrite(const float& in);
|
void speedAvgGlobalWrite(const float& in);
|
||||||
|
|
||||||
|
void injectionCtrGlobalRead(uint16_t& out);
|
||||||
|
void injectionCtrGlobalWrite(const uint16_t& in);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "modules/thermocouple/thermocouple.h"
|
#include "modules/thermocouple/thermocouple.h"
|
||||||
#include "modules/telemetry/telemetry.h"
|
#include "modules/telemetry/telemetry.h"
|
||||||
#include "modules/lap_counter/lap_counter.h"
|
#include "modules/lap_counter/lap_counter.h"
|
||||||
|
#include "modules/injection_counter/injection_counter.h"
|
||||||
|
|
||||||
|
|
||||||
SystemLogger *logger = new SystemLogger(&Serial);
|
SystemLogger *logger = new SystemLogger(&Serial);
|
||||||
@@ -29,6 +30,7 @@ Battery *battery_module = new Battery(logger);
|
|||||||
Thermocouple *thermocouple_module = new Thermocouple(logger);
|
Thermocouple *thermocouple_module = new Thermocouple(logger);
|
||||||
Telemetry *telemetry_module = new Telemetry(&Serial1, logger);
|
Telemetry *telemetry_module = new Telemetry(&Serial1, logger);
|
||||||
LapCounter *lap_counter_modules = new LapCounter(logger);
|
LapCounter *lap_counter_modules = new LapCounter(logger);
|
||||||
|
InjectionCounter *inj_counter_module = new InjectionCounter(logger);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +45,7 @@ void setup() {
|
|||||||
module_registry[module::Thermocouple] = thermocouple_module;
|
module_registry[module::Thermocouple] = thermocouple_module;
|
||||||
module_registry[module::Telemetry] = telemetry_module;
|
module_registry[module::Telemetry] = telemetry_module;
|
||||||
module_registry[module::LapCounter] = lap_counter_modules;
|
module_registry[module::LapCounter] = lap_counter_modules;
|
||||||
|
module_registry[module::InjectionCounter] = inj_counter_module;
|
||||||
|
|
||||||
display->init();
|
display->init();
|
||||||
display->printMessage("Starting Initialization");
|
display->printMessage("Starting Initialization");
|
||||||
@@ -74,6 +77,7 @@ void setup() {
|
|||||||
display->printMessage("Sensors Init...");
|
display->printMessage("Sensors Init...");
|
||||||
battery_module->init();
|
battery_module->init();
|
||||||
thermocouple_module->init();
|
thermocouple_module->init();
|
||||||
|
inj_counter_module->init();
|
||||||
delay(750);
|
delay(750);
|
||||||
display->printMessage("Sensors Init Complete");
|
display->printMessage("Sensors Init Complete");
|
||||||
delay(750);
|
delay(750);
|
||||||
@@ -95,4 +99,5 @@ void loop() {
|
|||||||
battery_module->loop();
|
battery_module->loop();
|
||||||
thermocouple_module->loop();
|
thermocouple_module->loop();
|
||||||
telemetry_module->loop();
|
telemetry_module->loop();
|
||||||
|
inj_counter_module->loop();
|
||||||
}
|
}
|
||||||
|
|||||||
45
src/modules/injection_counter/injection_counter.cpp
Normal file
45
src/modules/injection_counter/injection_counter.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
// Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#include "injection_counter.h"
|
||||||
|
#include "base/router.h"
|
||||||
|
#include "data/general_store.h"
|
||||||
|
|
||||||
|
int InjectionCounter::push(const Task &task) { return queue_.push(task); }
|
||||||
|
|
||||||
|
InjectionCounter::InjectionCounter() : logger_(nullptr) {};
|
||||||
|
|
||||||
|
InjectionCounter::InjectionCounter(SystemLogger *logger) : logger_(logger) {};
|
||||||
|
|
||||||
|
InjectionCounter::~InjectionCounter() {};
|
||||||
|
|
||||||
|
int InjectionCounter::init() { pinMode(INJ_GPIO, INPUT); }
|
||||||
|
|
||||||
|
int InjectionCounter::loop() {
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
if (now - last_check_ >= check_interval_) {
|
||||||
|
last_check_ = now;
|
||||||
|
|
||||||
|
int val = digitalRead(INJ_GPIO);
|
||||||
|
|
||||||
|
if (val == 1 && last_switch_ == 0 && !waiting_debounce_) {
|
||||||
|
waiting_debounce_ = true;
|
||||||
|
last_switch_time_ = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waiting_debounce_) {
|
||||||
|
if (now - last_switch_time_ >= debounce_) {
|
||||||
|
if (digitalRead(INJ_GPIO) == 1) {
|
||||||
|
counter_++;
|
||||||
|
injectionCtrGlobalWrite(counter_);
|
||||||
|
}
|
||||||
|
waiting_debounce_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_switch_ = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
30
src/modules/injection_counter/injection_counter.h
Normal file
30
src/modules/injection_counter/injection_counter.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
// Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#pragma once
|
||||||
|
#include "base/module_base.h"
|
||||||
|
#include "base/ring_buffer.h"
|
||||||
|
#include "modules/logger/system_logger.h"
|
||||||
|
|
||||||
|
#define INJ_GPIO 37
|
||||||
|
|
||||||
|
class InjectionCounter : public ModuleBase {
|
||||||
|
private:
|
||||||
|
SystemLogger *logger_;
|
||||||
|
RingBuffer<Task, 16> queue_;
|
||||||
|
unsigned long last_check_;
|
||||||
|
unsigned long check_interval_ = 100;
|
||||||
|
unsigned long debounce_ = 100;
|
||||||
|
int last_switch_ = 0;
|
||||||
|
int last_switch_time_ = 0;
|
||||||
|
bool waiting_debounce_ = 0;
|
||||||
|
uint16_t counter_ = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int push(const Task &task) override;
|
||||||
|
InjectionCounter();
|
||||||
|
InjectionCounter(SystemLogger* logger);
|
||||||
|
~InjectionCounter();
|
||||||
|
int init();
|
||||||
|
int loop();
|
||||||
|
};
|
||||||
@@ -88,15 +88,17 @@ int LapCounter::loop() {
|
|||||||
gpsGlobalRead(gps);
|
gpsGlobalRead(gps);
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
float dt = (now - last_average_time_) / 1000.0f;
|
float dt = (now - last_average_time_) / 1000.0f;
|
||||||
|
float speed = gps.speed_.value_;
|
||||||
|
if (speed < 1) speed = 0;
|
||||||
|
|
||||||
continuous_time_sum_ += dt;
|
continuous_time_sum_ += dt;
|
||||||
if (last_average_time_ == 0) {
|
if (last_average_time_ == 0) {
|
||||||
continuous_speed_sum_ += gps.speed_.value_ * dt;
|
continuous_speed_sum_ += speed * dt;
|
||||||
} else {
|
} else {
|
||||||
continuous_speed_sum_ +=
|
continuous_speed_sum_ +=
|
||||||
(gps.speed_.value_ + previous_speed_) * 0.5f * dt;
|
(speed + previous_speed_) * 0.5f * dt;
|
||||||
}
|
}
|
||||||
previous_speed_ = gps.speed_.value_;
|
previous_speed_ = speed;
|
||||||
|
|
||||||
speedAvgGlobalWrite(continuous_speed_sum_ / continuous_time_sum_);
|
speedAvgGlobalWrite(continuous_speed_sum_ / continuous_time_sum_);
|
||||||
|
|
||||||
|
|||||||
@@ -166,10 +166,13 @@ int Lcd::renderDriverPrimary() {
|
|||||||
|
|
||||||
uint16_t num_laps;
|
uint16_t num_laps;
|
||||||
lapCountGlobalRead(num_laps);
|
lapCountGlobalRead(num_laps);
|
||||||
|
|
||||||
float average_speed;
|
float average_speed;
|
||||||
speedAvgGlobalRead(average_speed);
|
speedAvgGlobalRead(average_speed);
|
||||||
|
|
||||||
|
uint16_t inj_ctr;
|
||||||
|
injectionCtrGlobalRead(inj_ctr);
|
||||||
|
|
||||||
if (!base_rendered_) {
|
if (!base_rendered_) {
|
||||||
this->clear();
|
this->clear();
|
||||||
display_->setCursor(0, 0);
|
display_->setCursor(0, 0);
|
||||||
@@ -178,6 +181,9 @@ int Lcd::renderDriverPrimary() {
|
|||||||
display_->setCursor(7, 0);
|
display_->setCursor(7, 0);
|
||||||
this->print("LAPS:");
|
this->print("LAPS:");
|
||||||
|
|
||||||
|
display_->setCursor(0, 1);
|
||||||
|
this->print("INJ:");
|
||||||
|
|
||||||
display_->setCursor(0, 2);
|
display_->setCursor(0, 2);
|
||||||
this->print("SPD:");
|
this->print("SPD:");
|
||||||
|
|
||||||
@@ -204,6 +210,15 @@ int Lcd::renderDriverPrimary() {
|
|||||||
this->print('0');
|
this->print('0');
|
||||||
this->print(num_laps, 10);
|
this->print(num_laps, 10);
|
||||||
|
|
||||||
|
display_->setCursor(4, 1);
|
||||||
|
if (inj_ctr < 100) {
|
||||||
|
this->print('0');
|
||||||
|
if (inj_ctr < 10) {
|
||||||
|
this->print('0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->print(inj_ctr, 10);
|
||||||
|
|
||||||
display_->setCursor(4, 2);
|
display_->setCursor(4, 2);
|
||||||
if (gps_data.speed_.value_ < 10.0)
|
if (gps_data.speed_.value_ < 10.0)
|
||||||
this->print('0');
|
this->print('0');
|
||||||
@@ -291,36 +306,36 @@ int Lcd::renderMsgBatteryLow() {
|
|||||||
|
|
||||||
int Lcd::renderMsgEngineTempLow() {
|
int Lcd::renderMsgEngineTempLow() {
|
||||||
if (!base_rendered_) {
|
if (!base_rendered_) {
|
||||||
this->clear();
|
this->clear();
|
||||||
display_->setCursor(6, 1);
|
display_->setCursor(6, 1);
|
||||||
this->print("WARNING");
|
this->print("WARNING");
|
||||||
display_->setCursor(2, 2);
|
display_->setCursor(2, 2);
|
||||||
this->print("ENGINE TEMP LOW");
|
this->print("ENGINE TEMP LOW");
|
||||||
base_rendered_ = true;
|
base_rendered_ = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lcd::renderMsgEngineTempHigh() {
|
int Lcd::renderMsgEngineTempHigh() {
|
||||||
if (!base_rendered_) {
|
if (!base_rendered_) {
|
||||||
this->clear();
|
this->clear();
|
||||||
display_->setCursor(6, 1);
|
display_->setCursor(6, 1);
|
||||||
this->print("WARNING");
|
this->print("WARNING");
|
||||||
display_->setCursor(2, 2);
|
display_->setCursor(2, 2);
|
||||||
this->print("ENGINE TEMP HIGH");
|
this->print("ENGINE TEMP HIGH");
|
||||||
base_rendered_ = true;
|
base_rendered_ = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lcd::renderMsgLapCounterStart() {
|
int Lcd::renderMsgLapCounterStart() {
|
||||||
if (!base_rendered_) {
|
if (!base_rendered_) {
|
||||||
this->clear();
|
this->clear();
|
||||||
display_->setCursor(5, 1);
|
display_->setCursor(5, 1);
|
||||||
this->print("LAP COUNTER");
|
this->print("LAP COUNTER");
|
||||||
display_->setCursor(6, 2);
|
display_->setCursor(6, 2);
|
||||||
this->print("STARTED");
|
this->print("STARTED");
|
||||||
base_rendered_ = true;
|
base_rendered_ = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -328,36 +343,36 @@ int Lcd::renderMsgLapCounterStart() {
|
|||||||
int Lcd::renderMsgLapCounterLapTime() {
|
int Lcd::renderMsgLapCounterLapTime() {
|
||||||
|
|
||||||
if (!base_rendered_) {
|
if (!base_rendered_) {
|
||||||
uint32_t time_cs;
|
uint32_t time_cs;
|
||||||
lastLapTimeGlobalRead(time_cs);
|
lastLapTimeGlobalRead(time_cs);
|
||||||
|
|
||||||
uint32_t minutes = (time_cs / 6000);
|
uint32_t minutes = (time_cs / 6000);
|
||||||
uint32_t seconds = (time_cs / 100) % 60;
|
uint32_t seconds = (time_cs / 100) % 60;
|
||||||
uint32_t cs = time_cs % 100;
|
uint32_t cs = time_cs % 100;
|
||||||
|
|
||||||
this->clear();
|
this->clear();
|
||||||
|
|
||||||
display_->setCursor(6, 1);
|
display_->setCursor(6, 1);
|
||||||
this->print("LAP TIME");
|
this->print("LAP TIME");
|
||||||
|
|
||||||
display_->setCursor(6, 2);
|
display_->setCursor(6, 2);
|
||||||
|
|
||||||
if (minutes < 10)
|
if (minutes < 10)
|
||||||
this->print('0');
|
this->print('0');
|
||||||
this->print(minutes, 10);
|
this->print(minutes, 10);
|
||||||
|
|
||||||
this->print(':');
|
this->print(':');
|
||||||
|
|
||||||
if (seconds < 10)
|
if (seconds < 10)
|
||||||
this->print('0');
|
this->print('0');
|
||||||
this->print(seconds, 10);
|
this->print(seconds, 10);
|
||||||
|
|
||||||
this->print('.');
|
this->print('.');
|
||||||
|
|
||||||
if (cs < 10)
|
if (cs < 10)
|
||||||
this->print('0');
|
this->print('0');
|
||||||
this->print(cs, 10);
|
this->print(cs, 10);
|
||||||
base_rendered_ = true;
|
base_rendered_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user