Initial telemetry implementation

This commit is contained in:
2026-03-30 22:44:14 +02:00
parent da6b23d78e
commit efd7119b32
16 changed files with 158 additions and 69 deletions

View File

@@ -8,10 +8,10 @@
#include "data/general_store.h"
int Battery::calibrate(const Task &task) {
double actual_voltage;
memcpy(&actual_voltage, &task.data_, sizeof(double));
float actual_voltage;
memcpy(&actual_voltage, &task.data_, sizeof(float));
int adc_read = analogRead(VBAT_PIN);
double cal_factor = actual_voltage / adc_read;
float cal_factor = actual_voltage / adc_read;
uint32_t output_val;
memcpy(&output_val, &cal_factor, sizeof(uint32_t));
router::send(module::Config, task::ConfigVbatCalSet, output_val);

View File

@@ -14,9 +14,9 @@ class Battery : public ModuleBase {
private:
SystemLogger *logger_;
RingBuffer<Task, 16> queue_;
double vbat_ = 0;
double calibration_ = 0;
double low_threshold_ = 0;
float vbat_ = 0;
float calibration_ = 0;
float low_threshold_ = 0;
unsigned long warning_sent_at_ = 0;
unsigned long warning_timeout_ = 10000;
unsigned long update_interval_ = 1000;

View File

@@ -392,7 +392,7 @@ int Cmd::handleBatteryCal(unsigned short argc, char *argv[]) {
#endif
return 1;
}
double vbat = strtod(argv[1], nullptr);
float vbat = strtod(argv[1], nullptr);
uint32_t task_data;
memcpy(&task_data, &vbat, sizeof(uint32_t));
#ifdef INFO
@@ -415,7 +415,7 @@ int Cmd::handleBatteryPrintVbat(unsigned short argc) {
}
#ifdef INFO
double vbat;
float vbat;
vbatGlobalRead(vbat);
if (logger_ != nullptr) {
logger_->info("VBAT: " + String(vbat));
@@ -433,7 +433,7 @@ int Cmd::handleBatterySetLow(unsigned short argc, char* argv[]) {
#endif
return 1;
}
double low = strtod(argv[1], nullptr);
float low = strtod(argv[1], nullptr);
uint32_t task_data;
memcpy(&task_data, &low, sizeof(uint32_t));
#ifdef INFO
@@ -454,7 +454,7 @@ int Cmd::handleThermoSetLow(unsigned short argc, char* argv[]) {
#endif
return 1;
}
double low = strtod(argv[1], nullptr);
float low = strtod(argv[1], nullptr);
uint32_t task_data;
memcpy(&task_data, &low, sizeof(uint32_t));
#ifdef INFO
@@ -475,7 +475,7 @@ int Cmd::handleThermoSetHigh(unsigned short argc, char* argv[]) {
#endif
return 1;
}
double low = strtod(argv[1], nullptr);
float low = strtod(argv[1], nullptr);
uint32_t task_data;
memcpy(&task_data, &low, sizeof(uint32_t));
#ifdef INFO

View File

@@ -99,22 +99,22 @@ int Config::resetConfig() {
return this->writeConfig();
}
int Config::writeVbatCal(double value) {
int Config::writeVbatCal(float value) {
config_.vbat_calibration_ = value;
return this->writeConfig();
}
int Config::writeVbatLow(double value) {
int Config::writeVbatLow(float value) {
config_.vbat_low_ = value;
return this->writeConfig();
}
int Config::writeTengLow(double value) {
int Config::writeTengLow(float value) {
config_.teng_low_ = value;
return this->writeConfig();
}
int Config::writeTengHigh(double value) {
int Config::writeTengHigh(float value) {
config_.teng_high_ = value;
return this->writeConfig();
}
@@ -188,9 +188,9 @@ int Config::taskConfigDetectTrack(unsigned long timeout_ms) {
TrackData track_data;
int result = this->getTrack(task_data.last_checked_, track_data);
if (result == 0) {
double delta_lat = track_data.point_a_.lat_ - task_data.gps_lat_;
double delta_lng = (track_data.point_a_.lng_ - task_data.gps_lng_) * task_data.cos_;
double dist2 = delta_lat * delta_lat + delta_lng * delta_lng;
float delta_lat = track_data.point_a_.lat_ - task_data.gps_lat_;
float delta_lng = (track_data.point_a_.lng_ - task_data.gps_lng_) * task_data.cos_;
float dist2 = delta_lat * delta_lat + delta_lng * delta_lng;
if (dist2 < task_data.sqdiff_ || task_data.smallest_idx_ == 0) {
task_data.smallest_idx_ = task_data.last_checked_;
@@ -255,32 +255,32 @@ int Config::handleActiveTask(unsigned long timeout_ms) {
}
case task::ConfigVbatCalSet: {
double cal_value;
memcpy(&cal_value, &active_task_.data_, sizeof(double));
float cal_value;
memcpy(&cal_value, &active_task_.data_, sizeof(float));
int result = this->writeVbatCal(cal_value);
this->taskComplete();
return result;
}
case task::ConfigVbatSetLow: {
double low_value;
memcpy(&low_value, &active_task_.data_, sizeof(double));
float low_value;
memcpy(&low_value, &active_task_.data_, sizeof(float));
int result = this->writeVbatLow(low_value);
this->taskComplete();
return result;
}
case task::ConfigTengSetLow: {
double low_value;
memcpy(&low_value, &active_task_.data_, sizeof(double));
float low_value;
memcpy(&low_value, &active_task_.data_, sizeof(float));
int result = this->writeTengLow(low_value);
this->taskComplete();
return result;
}
case task::ConfigTengSetHigh: {
double high_value;
memcpy(&high_value, &active_task_.data_, sizeof(double));
float high_value;
memcpy(&high_value, &active_task_.data_, sizeof(float));
int result = this->writeTengHigh(high_value);
this->taskComplete();
return result;

View File

@@ -18,10 +18,10 @@
struct TaskConfigTrackDetectData {
unsigned short last_checked_ = 0;
unsigned short smallest_idx_ = 0;
double cos_ = 0;
double sqdiff_ = 0;
double gps_lat_ = 0;
double gps_lng_ = 0;
float cos_ = 0;
float sqdiff_ = 0;
float gps_lat_ = 0;
float gps_lng_ = 0;
};
class Config : public ModuleBase {
@@ -47,10 +47,10 @@ private:
int writeTrackFromTemp();
int deleteTrack(unsigned short idx);
int resetConfig();
int writeVbatCal(double value);
int writeVbatLow(double value);
int writeTengLow(double value);
int writeTengHigh(double value);
int writeVbatCal(float value);
int writeVbatLow(float value);
int writeTengLow(float value);
int writeTengHigh(float value);
public:
int push(const Task &task) override;

View File

@@ -31,7 +31,7 @@ void Lcd::print(const char c[]) {
display_cleared_ = false;
}
void Lcd::print(double d, int digits) {
void Lcd::print(float d, int digits) {
display_->print(d, digits);
display_cleared_ = false;
}
@@ -151,9 +151,9 @@ int Lcd::renderDriverPrimary() {
GpsData gps_data;
gpsGlobalRead(gps_data);
double vbat;
float vbat;
vbatGlobalRead(vbat);
double teng;
float teng;
tengGlobalRead(teng);
display_->setCursor(0,0);

View File

@@ -53,7 +53,7 @@ private:
void print(const String &msg);
void print(char c);
void print(const char c[]);
void print(double d, int digits = 2);
void print(float d, int digits = 2);
void print(unsigned long l, int base = 10);
void print(long l, int base = 10);
void print(unsigned int i, int base = 10);

View File

@@ -0,0 +1,47 @@
// 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 "telemetry.h"
#include "base/router.h"
#include "data/general_store.h"
int Telemetry::push(const Task &task) { return queue_.push(task); }
Telemetry::Telemetry(HardwareSerial* data_stream) : logger_(nullptr), data_stream_(data_stream) {}
Telemetry::Telemetry(HardwareSerial* data_stream,SystemLogger *logger) : logger_(logger), data_stream_(data_stream) {}
Telemetry::~Telemetry() {}
int Telemetry::init() {
data_stream_->begin(115200);
lora_header_.source_ = 0x01;
lora_header_.dest_ = 0x02;
return 0;
}
int Telemetry::loop() {
unsigned long now = millis();
if (now > last_sent_ + update_interval_) {
TelemetryPacket2 packet;
tengGlobalRead(packet.teng);
vbatGlobalRead(packet.vbat);
GpsData gps;
gpsGlobalRead(gps);
packet.lat = gps.lat_.value_;
packet.lng = gps.lng_.value_;
packet.speed = gps.speed_.value_;
lora_header_.size_ = sizeof(packet);
lora_header_.crc16_ = crc16_ccitt((uint8_t*)&packet, sizeof(packet));
lora_header_.version_ = 2;
uart_header_.size_ = sizeof(packet) + sizeof(lora_header_);
if (data_stream_->availableForWrite()) {
data_stream_->write((uint8_t*)&uart_header_, sizeof(uart_header_));
data_stream_->write((uint8_t*)&lora_header_, sizeof(lora_header_));
data_stream_->write((uint8_t*)&packet, sizeof(packet));
}
last_sent_ = millis();
}
return 0;
}

View 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"
#include "telemetry_common/telemetry_common.h"
#include <Arduino.h>
#include "custom_types.h"
#include "data/gps_store.h"
class Telemetry : public ModuleBase {
private:
SystemLogger *logger_;
RingBuffer<Task, 16> queue_;
HardwareSerial *data_stream_;
unsigned long last_sent_ = 0;
unsigned long update_interval_ = 1000;
TelemetryLoRaHeader lora_header_;
TelemetryUARTHeader uart_header_;
public:
int push(const Task &task) override;
Telemetry(HardwareSerial *data_stream);
Telemetry(HardwareSerial *data_stream, SystemLogger *logger);
~Telemetry();
int init();
int loop();
};

View File

@@ -17,9 +17,9 @@ private:
SystemLogger *logger_;
RingBuffer<Task, 16> queue_;
MAX6675 *thermocouple_;
double temperature_;
double low_;
double high_;
float temperature_;
float low_;
float high_;
unsigned long update_interval_ = 1000;
unsigned long last_read_at_ = 0;
unsigned long warning_sent_at_ = 0;