Added thermocouple offset calibration and config crc
This commit is contained in:
@@ -38,6 +38,7 @@ enum Type : uint8_t {
|
||||
DisplayMsgEngineTempHigh,
|
||||
DisplayMsgLapCounterStart,
|
||||
DisplayMsgLapCounterLapTime,
|
||||
DisplayMsgCorruptedConfig,
|
||||
ConfigTrackDetect,
|
||||
ConfigWriteTempTrack,
|
||||
ConfigTrackDelete,
|
||||
@@ -46,6 +47,7 @@ enum Type : uint8_t {
|
||||
ConfigVbatSetLow,
|
||||
ConfigTengSetLow,
|
||||
ConfigTengSetHigh,
|
||||
ConfigTengSetOffset,
|
||||
BatteryCal,
|
||||
TelemetrySendLapPacket,
|
||||
AllConfigUpdated,
|
||||
|
||||
@@ -16,6 +16,7 @@ struct VehicleConfig {
|
||||
float vbat_low_ = 0;
|
||||
float teng_low_ = 0;
|
||||
float teng_high_ = 0;
|
||||
float teng_offset_ = 0;
|
||||
};
|
||||
|
||||
struct LatLng {
|
||||
|
||||
@@ -15,11 +15,25 @@ static const uint16_t TRACK_SLOT_BYTES = 128;
|
||||
static const uint16_t TRACK_BASE_ADDR = CONFIG_ADDR + CONFIG_RESERVED_BYTES;
|
||||
static const uint16_t TRACK_END_ADDR = TRACK_BASE_ADDR + (TRACK_SLOTS * TRACK_SLOT_BYTES);
|
||||
static const uint16_t FREE_AFTER_TRACKS = TOTAL_BYTES - TRACK_END_ADDR;
|
||||
static const uint16_t CRC_BASE_OFFSET = 3072;
|
||||
static const uint16_t CRC_SIZE = sizeof(uint16_t);
|
||||
static const uint16_t CRC_SLOTS = 9;
|
||||
static const uint16_t CRC_END_ADDR = CRC_BASE_OFFSET + (CRC_SLOTS * CRC_SIZE);
|
||||
|
||||
static_assert(TRACK_END_ADDR <= TOTAL_BYTES, "EEPROM layout exceeds physical storage");
|
||||
|
||||
static_assert(TRACK_END_ADDR <= CRC_BASE_OFFSET, "EEPROM layout overlap between tracks and CRC sectors");
|
||||
static_assert(TRACK_END_ADDR <= TOTAL_BYTES || CRC_END_ADDR <= TOTAL_BYTES, "EEPROM layout exceeds physical storage");
|
||||
|
||||
inline uint16_t trackSlotAddr(uint8_t idx) {
|
||||
return TRACK_BASE_ADDR + ((idx - 1) * TRACK_SLOT_BYTES);
|
||||
}
|
||||
|
||||
inline uint16_t configCRCAddr() {
|
||||
return CRC_BASE_OFFSET;
|
||||
}
|
||||
|
||||
inline uint16_t trackCRCAddr(uint8_t idx) {
|
||||
return CRC_BASE_OFFSET + (idx * CRC_SIZE);
|
||||
}
|
||||
|
||||
} // namespace eeprom_layout
|
||||
|
||||
@@ -133,6 +133,10 @@ Cmd::CommandId Cmd::parseCommandName(const char *input) {
|
||||
return ThermoSetHigh;
|
||||
}
|
||||
|
||||
if (strcmp(input, "THERMO_SET_OFFSET") == 0) {
|
||||
return ThermoSetOffset;
|
||||
}
|
||||
|
||||
if (strcmp(input, "DEBUG_UNLOCK") == 0) {
|
||||
return DebugUnlock;
|
||||
}
|
||||
@@ -524,6 +528,33 @@ int Cmd::handleThermoSetHigh(unsigned short argc, char* argv[]) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int Cmd::handleThermoSetOffset(unsigned short argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
#ifdef ERROR
|
||||
if (logger_ != nullptr) {
|
||||
logger_->error("THERMO_SET_OFFSET expects 1 argument");
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
float offset = strtod(argv[1], nullptr);
|
||||
uint32_t task_data;
|
||||
memcpy(&task_data, &offset, sizeof(uint32_t));
|
||||
#ifdef INFO
|
||||
if (logger_ != nullptr) {
|
||||
logger_->info("Setting offset for TENG");
|
||||
}
|
||||
#endif
|
||||
int result = router::send(module::Config, task::ConfigTengSetOffset, task_data);
|
||||
#ifdef ERROR
|
||||
if (result != 0 && logger_ != nullptr) {
|
||||
logger_->error("Failed to queue THERMO_SET_OFFSET config update");
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
int Cmd::handleHelpGlobal(unsigned short argc) {
|
||||
if (argc != 1) {
|
||||
#ifdef ERROR
|
||||
@@ -703,6 +734,9 @@ int Cmd::dispatchCommand(CommandId command, unsigned short argc, char *argv[]) {
|
||||
case ThermoSetHigh:
|
||||
return this->handleThermoSetHigh(argc, argv);
|
||||
|
||||
case ThermoSetOffset:
|
||||
return this->handleThermoSetOffset(argc, argv);
|
||||
|
||||
case DebugUnlock:
|
||||
return this->handleDebugUnlock(argc);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ private:
|
||||
BatterySetLow,
|
||||
ThermoSetLow,
|
||||
ThermoSetHigh,
|
||||
ThermoSetOffset,
|
||||
DebugUnlock,
|
||||
DebugLock,
|
||||
DbgSendBlankLap,
|
||||
@@ -67,6 +68,7 @@ private:
|
||||
int handleBatterySetLow(unsigned short argc, char *argv[]);
|
||||
int handleThermoSetLow(unsigned short argc, char *argv[]);
|
||||
int handleThermoSetHigh(unsigned short argc, char *argv[]);
|
||||
int handleThermoSetOffset(unsigned short argc, char *argv[]);
|
||||
int handleHelpGlobal(unsigned short argc);
|
||||
int handleUnknownCommand(unsigned short argc, char *argv[]);
|
||||
int handleDebugUnlock(unsigned short argc);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "data/track_store.h"
|
||||
#include "telemetry_common/telemetry_common.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
@@ -125,6 +126,11 @@ int Config::writeTengHigh(float value) {
|
||||
return this->writeConfig();
|
||||
}
|
||||
|
||||
int Config::writeTengOffset(float value) {
|
||||
config_.teng_offset_ = value;
|
||||
return this->writeConfig();
|
||||
}
|
||||
|
||||
Config::Config() : logger_(nullptr), valid_config_(true) {}
|
||||
|
||||
Config::Config(SystemLogger *logger) : logger_(logger), valid_config_(true) {}
|
||||
@@ -132,13 +138,28 @@ Config::Config(SystemLogger *logger) : logger_(logger), valid_config_(true) {}
|
||||
Config::~Config() {}
|
||||
|
||||
int Config::readConfig() {
|
||||
uint16_t crc;
|
||||
EEPROM.get(eeprom_layout::CONFIG_ADDR, config_);
|
||||
EEPROM.get(eeprom_layout::configCRCAddr(), crc);
|
||||
int res = crc16_ccitt_check((uint8_t*)&config_, sizeof(config_), crc);
|
||||
if (res != 0) {
|
||||
#ifdef ERROR
|
||||
if (logger_ != nullptr) {
|
||||
logger_->error("Corrupted config, reset and regenerate config required");
|
||||
}
|
||||
#endif
|
||||
router::send(module::Lcd, task::DisplayMsgCorruptedConfig, 5000);
|
||||
return 1;
|
||||
}
|
||||
configGlobalWrite(config_);
|
||||
router::sendAll(module::Config, task::AllConfigUpdated);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Config::writeConfig() {
|
||||
uint16_t crc = crc16_ccitt((uint8_t*)&config_, sizeof(config_));
|
||||
EEPROM.put(eeprom_layout::CONFIG_ADDR, config_);
|
||||
EEPROM.put(eeprom_layout::configCRCAddr(), crc);
|
||||
configGlobalWrite(config_);
|
||||
#ifdef INFO
|
||||
if (logger_ != nullptr) {
|
||||
@@ -302,6 +323,14 @@ int Config::handleActiveTask(unsigned long timeout_ms) {
|
||||
return result;
|
||||
}
|
||||
|
||||
case task::ConfigTengSetOffset: {
|
||||
float offset_value;
|
||||
memcpy(&offset_value, &active_task_.data_, sizeof(float));
|
||||
int result = this->writeTengOffset(offset_value);
|
||||
this->taskComplete();
|
||||
return result;
|
||||
}
|
||||
|
||||
default:
|
||||
// Broadcasts such as AllConfigUpdated may be queued back into Config.
|
||||
// Unsupported tasks must still be completed so the module does not stall.
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
int writeVbatLow(float value);
|
||||
int writeTengLow(float value);
|
||||
int writeTengHigh(float value);
|
||||
int writeTengOffset(float value);
|
||||
|
||||
public:
|
||||
int push(const Task &task) override;
|
||||
|
||||
@@ -378,6 +378,18 @@ int Lcd::renderMsgLapCounterLapTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Lcd::renderMsgCorruptedConfig() {
|
||||
if (!base_rendered_) {
|
||||
this->clear();
|
||||
display_->setCursor(3, 1);
|
||||
this->print("CRITICAL ERROR");
|
||||
display_->setCursor(2, 2);
|
||||
this->print("CONFIG CORRUPTED");
|
||||
base_rendered_ = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Lcd::push(const Task &task) { return queue_.push(task); }
|
||||
|
||||
Lcd::Lcd()
|
||||
@@ -594,6 +606,10 @@ int Lcd::loop(unsigned long timeout_ms) {
|
||||
base_rendered_ = false;
|
||||
activateMessage(screen::MsgLapCounterLapTime, next_task.data_);
|
||||
|
||||
case task::DisplayMsgCorruptedConfig:
|
||||
base_rendered_ = false;
|
||||
activateMessage(screen::MsgCorruptedConfig, next_task.data_);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -668,6 +684,10 @@ int Lcd::loop(unsigned long timeout_ms) {
|
||||
this->renderMsgLapCounterLapTime();
|
||||
break;
|
||||
|
||||
case screen::MsgCorruptedConfig:
|
||||
this->renderMsgCorruptedConfig();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ enum LcdScreen : uint8_t {
|
||||
MsgEngineTempHigh,
|
||||
MsgLapCounterStart,
|
||||
MsgLapCounterLapTime,
|
||||
MsgCorruptedConfig,
|
||||
};
|
||||
|
||||
} // namespace screen
|
||||
@@ -79,6 +80,7 @@ private:
|
||||
int renderMsgEngineTempHigh();
|
||||
int renderMsgLapCounterStart();
|
||||
int renderMsgLapCounterLapTime();
|
||||
int renderMsgCorruptedConfig();
|
||||
|
||||
public:
|
||||
int push(const Task &task) override;
|
||||
|
||||
@@ -36,6 +36,7 @@ int Thermocouple::loop(unsigned long timeout_ms) {
|
||||
configGlobalRead(config);
|
||||
low_ = config.teng_low_;
|
||||
high_ = config.teng_high_;
|
||||
offset_ = config.teng_offset_;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -46,7 +47,7 @@ int Thermocouple::loop(unsigned long timeout_ms) {
|
||||
}
|
||||
|
||||
if (millis() > last_read_at_ + update_interval_) {
|
||||
temperature_ = thermocouple_->readCelsius();
|
||||
temperature_ = thermocouple_->readCelsius() + offset_;
|
||||
tengGlobalWrite(temperature_);
|
||||
last_read_at_ = millis();
|
||||
if (temperature_ > high_) {
|
||||
|
||||
@@ -20,6 +20,7 @@ private:
|
||||
float temperature_;
|
||||
float low_;
|
||||
float high_;
|
||||
float offset_;
|
||||
unsigned long update_interval_ = 1000;
|
||||
unsigned long last_read_at_ = 0;
|
||||
unsigned long warning_sent_at_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user