update temperature messages

This commit is contained in:
Bartosz Wieczorek 2025-04-15 14:19:31 +02:00
parent a634cf5cfe
commit fb083f0538
7 changed files with 152 additions and 132 deletions

View File

@ -7,58 +7,13 @@ enum Error {
NoError = 0;
}
enum ModeOfOperationType {
/**
Device is currently OFF
*/
Off = 0;
/**
In manual operation, no PID loop will be enabled on the device.
In this mode there is no way to set output temperature, you can only set the output
power
Mode will be applied to all channels
*/
Manual = 1;
/**
TODO not implemented ;(
*/
Automatic = 2;
}
/// Request / Response API
message ModeOfOperationRequest
{
// not specyfying this, resulte in a "read only" request
ModeOfOperationType type = 1;
};
message ModeOfOperationResponse
{
oneof resp
{
ModeOfOperationType type = 1;
Error error = 254;
}
}
// only those messages are send
message IngressMessages
{
uint32 requestID = 255; // Unique request ID
oneof data
{
ModeOfOperationRequest modeOfOperationRequest = 1;
}
};
message EgressMessages
{
optional uint32 requestID = 255; // Unique request ID
oneof data
{
ModeOfOperationResponse modeOfOperationResponse = 1;
}
};

View File

@ -12,7 +12,7 @@ enum Error {
NoId = 5;
NoData = 6;
RequestQueueFull =8;
RequestQueueFull = 8;
UnknownId = 7;
}

View File

@ -2,6 +2,23 @@ syntax = "proto3";
package temperature;
/*
messages with name
SetXXX{}
are write only messages
GetXXX{}
are read only messages
XXX{}
are read write messages, meanning that if you set fileds in the message they will be set on device
the value of register will be returned without modification otherwise
each Response message contains a optional Error field, if set the state of the device was not
changed and error code describes what went wrong
*/
enum Error {
NoError = 0;
UnknownChannel = 1;
@ -9,11 +26,34 @@ enum Error {
TemperatureSensorBroken = 3;
}
enum FilterType {
None = 0;
Kalman = 1;
EMA = 2;
Avarage = 3;
}
/* CONFIGURATION */
message SamplerConfig
{
optional uint32 samples = 3; // optional, if ommited return current value
optional uint32 period_ms = 4; // optional
optional uint32 samples = 3;
optional uint32 period_ms = 4;
}
message KalmanFilterParams
{
optional float Q = 1;
optional float R = 2;
}
message EMAFilterParams
{
optional float alpha = 1;
}
message AverageFilterParams
{
optional uint32 samples = 1;
}
/* INTERNAL STRUCTURES */
@ -31,10 +71,10 @@ message TemperatureStatistics
// last update
float temp_c = 1;
// avarage from last nsamples
// average from last nsamples in Celcius
float temp_avg_c = 2;
// standard deviation of temperature on given channel from last nsamples
// standard deviation of temperature on given channel from last nsamples in Celcius
float temp_stddev_c = 3;
// samples taken
@ -42,7 +82,7 @@ message TemperatureStatistics
}
/* CONFIG API */
// Read/Write
message SamplerConfigRequest
{
uint32 channel_id = 1;
@ -52,45 +92,78 @@ message SamplerConfigRequest
message SamplerConfigResponse
{
uint32 channel_id = 1;
oneof data
{
SamplerConfig config = 2;
Error error = 254;
}
SamplerConfig config = 2;
optional Error error = 254;
}
/*
Filter configuration, can be set to any filter, despite what filter is currently enabled
*/
message FilterConfigRequest
{
uint32 channel_id = 1;
// skips info about current parameters in response message
bool skipFullResponse = 5;
optional KalmanFilterParams kalmanFilterParams = 2;
optional EMAFilterParams emaFilterParams = 3;
optional AverageFilterParams averageFilterParams = 4;
}
message FilterConfigResponse
{
uint32 channel_id = 1;
KalmanFilterParams kalmanFilterParams = 2;
EMAFilterParams emaFilterParams = 3;
AverageFilterParams averageFilterParams = 4;
optional Error error = 254;
}
message FilterRequest
{
uint32 channel_id = 1;
optional FilterType filterType = 2;
}
message FilterResponse
{
uint32 channel_id = 1;
FilterType filterType = 2;
optional Error error = 254;
}
// API
// Read
message GetCurrentTemperatureRequest
{
uint32 channel_id = 1;
};
message GetCurrentTemperatureResponse
{
uint32 channel_id = 1;
oneof data
{
TemperatureCurrent temperatureCurrent = 2;
Error error = 254;
}
TemperatureCurrent temperatureCurrent = 2;
optional Error error = 254;
}
// Read
message GetTemperatureRequest
{
uint32 channel_id = 1;
};
message GetTemperatureResponse
{
uint32 channel_id = 1;
oneof data
{
TemperatureStatistics temperatureStats = 2;
Error error = 254;
}
TemperatureStatistics temperatureStats = 2;
optional Error error = 254;
}
// only those messages are send through wire at temperature endpoint
// broadcast
message BroadcastTemperatureStatistics {
uint32 channel_id = 1;
TemperatureStatistics temperatureStats = 2;
}
// only those messages are send through wire.
message IngressMessages
{
uint32 requestID = 255;
@ -102,6 +175,8 @@ message IngressMessages
// configuration
SamplerConfigRequest samplerConfigRequest = 3;
FilterConfigRequest filterConfigRequest = 4;
FilterRequest filterRequest = 5;
}
};
@ -116,8 +191,10 @@ message EgressMessages
// configuration
SamplerConfigResponse samplerConfigResponse = 3;
FilterConfigResponse filterConfigResponse = 4;
FilterResponse filterResponse = 5;
// broadcast
TemperatureStatistics broadcastTemperatureStatistics = 16;
BroadcastTemperatureStatistics broadcastTemperatureStatistics = 16;
}
};

View File

@ -15,9 +15,6 @@ message Utilization
message IngressMessages
{
uint32 requestID = 255;
// oneof data
// {
// }
};
message EgressMessages

View File

@ -1,6 +1,5 @@
#include "common.hpp"
#include "log.hpp"
#include "messenger.hpp"
#include "phase_modulation.hpp"
#include "placement_unique_ptr.hpp"
@ -52,9 +51,6 @@ TStack phaseModulationStack{k_phaseModulationStack, K_THREAD_STACK_SIZEOF(k_phas
/// TODO power measurement thread
/// TODO status led thread, print statues
// adc_channel_cfg adcch1 = ADC_CHANNEL_CFG_DT(DT_NODELABEL(adc_temp));
// extern int z_clock_hw_cycles_per_sec;
template <typename T> class LazyInit {
alignas(T) std::byte _buf[sizeof(T)];
unique_placed_ptr<T> obj;
@ -76,7 +72,6 @@ LazyInit<UARTThread> uartThread;
LazyInit<TemperatureSamplerThread> temperatureSampler;
LazyInit<ZeroCrossDetectionThread> zcd;
LazyInit<PhaseModulationThread> phaseModulation;
struct except : std::exception {};
int main() {
using namespace rims;
@ -104,50 +99,5 @@ int main() {
while (1) {
std::this_thread::sleep_for(std::chrono::seconds{2});
// try {
// throw except{};
// } catch (const except &e) {
// while(1){}
// }
}
// auto getStats = [](auto &diffs) {
// if (diffs.full()) {
// auto sum = std::accumulate(diffs.begin(), diffs.end(), std::chrono::steady_clock::duration{});
// auto average = sum / diffs.size();
// // Compute the standard deviation
// auto variancens = std::chrono::steady_clock::duration{}.count();
// for (const auto &value : diffs) {
// variancens += (value - average).count() * (value - average).count();
// }
// variancens /= diffs.size();
// double std_dev = std::sqrt(variancens);
// printk("avg :%fus stddev :%fus\n", average.count() / 1000.0, std_dev / 1000.0);
// return average;
// }
// return std::chrono::steady_clock::duration{};
// };
// while (1) {
// k_msleep(1000);
// gpio_pin_toggle_dt(&status_pin_spec);
// auto noDetectAvg = getStats(_fallDiffs);
// auto detectAvg = getStats(_risesDiffs);
// auto t = 2 * (noDetectAvg + detectAvg).count() / 1000.0 / 1000.0;
// auto Hz = 1.0 / (t / 1000.0);
// printk("total : %fms, f:%fHz\n", t, Hz);
// if (std::abs(Hz - 50.0) > 0.01) {
// auto nz_clock_hw_cycles_per_sec = int(50.0 * z_clock_hw_cycles_per_sec / Hz);
// auto diff = z_clock_hw_cycles_per_sec - nz_clock_hw_cycles_per_sec;
// printk("old: %d new: %d diff=%d\n", z_clock_hw_cycles_per_sec, z_clock_hw_cycles_per_sec - (diff / 4), diff);
// z_clock_hw_cycles_per_sec -= diff / 4;
// }
// printk("EOL\n");
// }
}

View File

@ -8,6 +8,7 @@
#include <exception>
#include <functional>
#include <numeric>
#include <tuple>
#include <type_traits>
#include "common.hpp"
@ -58,7 +59,7 @@ template <typename T> void PB_encode_egress(const T &tempresp) {
ULOG_DEBUG("Sending SamplerConfigResponse message");
egress.data.samplerConfigResponse = tempresp;
egress.which_data = temperature_EgressMessages_samplerConfigResponse_tag;
} else if constexpr (std::is_same_v<T, TemperatureStatistics>) {
} else if constexpr (std::is_same_v<T, BroadcastTemperatureStatistics>) {
ULOG_DEBUG("Sending TemperatureStatistics message");
egress.data.broadcastTemperatureStatistics = tempresp;
egress.which_data = temperature_EgressMessages_broadcastTemperatureStatistics_tag;
@ -149,8 +150,9 @@ TemperatureSampler::Sample TemperatureSampler::adc_take_sample() const {
template <typename Req, typename Resp> constexpr bool unknownChannelError(const Req &req, Resp &resp) {
if (req.channel_id > ChannelNumber) {
resp.which_data = 254; // error_tag
resp.data.error = temperature_Error_UnknownChannel;
/// fixme
// resp.which_data = 254; // error_tag
// resp.data.error = temperature_Error_UnknownChannel;
return true;
}
return false;
@ -218,8 +220,20 @@ void TemperatureSamplerOrchestrator::event_messageArrived() {
&TemperatureSamplerOrchestrator::handle_samplerConfigRequest
);
constexpr auto filterConfigHandler = std::make_tuple(
temperature_IngressMessages_filterConfigRequest_tag,
temperature_EgressMessages_filterConfigResponse_tag,
&TemperatureSamplerOrchestrator::handle_filterConfigRequest
);
constexpr auto filterHandler = std::make_tuple(
temperature_IngressMessages_filterRequest_tag,
temperature_EgressMessages_filterResponse_tag,
&TemperatureSamplerOrchestrator::handle_filterRequest
);
auto genericHandler = [&](const auto &request, auto &response, auto handler) {
auto fn = std::get<2>(handler);
auto fn = std::get<2>(handler);
std::invoke(fn, this, request, response);
};
@ -246,6 +260,16 @@ void TemperatureSamplerOrchestrator::event_messageArrived() {
resp.which_data = std::get<1>(samplerConfigHandler);
genericHandler(req.data.samplerConfigRequest, resp.data.samplerConfigResponse, samplerConfigHandler);
break;
case std::get<1>(filterConfigHandler):
resp.which_data = std::get<1>(filterConfigHandler);
genericHandler(req.data.filterConfigRequest, resp.data.filterConfigResponse, filterConfigHandler);
break;
case std::get<1>(filterHandler):
resp.which_data = std::get<1>(filterHandler);
genericHandler(req.data.filterRequest, resp.data.filterResponse, filterHandler);
break;
default:
ULOG_WARNING("Got unknown request with id %d", req.which_data);
@ -267,7 +291,7 @@ void TemperatureSamplerOrchestrator::handle_getTemperatureRequest( //
) const {
if (unknownChannelError(req, resp)) return;
resp.data.temperatureStats = _temperatureSamplerChannels[req.channel_id].temperature_statistics();
resp.temperatureStats = _temperatureSamplerChannels[req.channel_id].temperature_statistics();
}
void TemperatureSamplerOrchestrator::handle_getCurrentTemperatureRequest(
@ -277,8 +301,7 @@ void TemperatureSamplerOrchestrator::handle_getCurrentTemperatureRequest(
if (unknownChannelError(req, resp)) return;
resp.channel_id = req.channel_id;
resp.data.temperatureCurrent = _temperatureSamplerChannels[req.channel_id].temperature();
resp.which_data = temperature_GetCurrentTemperatureResponse_temperatureCurrent_tag;
resp.temperatureCurrent = _temperatureSamplerChannels[req.channel_id].temperature();
}
void TemperatureSamplerOrchestrator::handle_samplerConfigRequest( //
@ -353,4 +376,14 @@ void TemperatureSamplerThread::threadMain() {
thread.loop();
}
void TemperatureSamplerOrchestrator::handle_filterConfigRequest(const FilterConfigRequest &req, FilterConfigResponse &resp) const
{
}
void TemperatureSamplerOrchestrator::handle_filterRequest(const FilterRequest &req, FilterResponse &resp) const
{
}
} // namespace rims

View File

@ -25,8 +25,14 @@ using GetCurrentTemperatureRequest = temperature_GetCurrentTemperatureRequest;
using GetCurrentTemperatureResponse = temperature_GetCurrentTemperatureResponse;
using SamplerConfigRequest = temperature_SamplerConfigRequest;
using SamplerConfigResponse = temperature_SamplerConfigResponse;
using TemperatureStatistics = temperature_TemperatureStatistics;
using TemperatureCurrent = temperature_TemperatureCurrent;
using FilterConfigRequest = temperature_FilterConfigRequest;
using FilterConfigResponse = temperature_FilterConfigResponse;
using FilterRequest = temperature_FilterRequest;
using FilterResponse = temperature_FilterResponse;
using TemperatureStatistics = temperature_TemperatureStatistics;
using TemperatureCurrent = temperature_TemperatureCurrent;
using BroadcastTemperatureStatistics = temperature_BroadcastTemperatureStatistics;
class TemperatureSampler {
public:
@ -68,6 +74,8 @@ class TemperatureSamplerOrchestrator {
void handle_getTemperatureRequest(const GetTemperatureRequest &req, GetTemperatureResponse &resp) const;
void handle_getCurrentTemperatureRequest(const GetCurrentTemperatureRequest &req, GetCurrentTemperatureResponse &resp) const;
void handle_samplerConfigRequest(const SamplerConfigRequest &req, SamplerConfigResponse &resp) const;
void handle_filterConfigRequest(const FilterConfigRequest &req, FilterConfigResponse &resp) const;
void handle_filterRequest(const FilterRequest &req, FilterResponse &resp) const;
void action_takeSample();
void action_sendTemperature(uint8_t ch);