Vehicle Control Unit 0.01
This is the c library for controlling the car.
Loading...
Searching...
No Matches
Macros | Functions | Variables
Telemetry.c File Reference
#include "../../Inc/Utils/Telemetry.h"
#include "../../Inc/Utils/MessageFormat.h"
#include "../../Inc/Utils/Common.h"
#include <string.h>
Include dependency graph for Telemetry.c:

Go to the source code of this file.

Macros

#define MAX_TELEMETRY_SIGNALS   100
 

Functions

void initTelemetry (void)
 
TelemetrySignalregisterTelemetrySignal (const char *name, TelemetryType type, UnitId unit_id, uint32_t expected_rate_ms, float custom_min, float custom_max)
 
void sendTelemetryValue (TelemetrySignal *signal, float value)
 
void checkTelemetryHealth (void)
 
void handleTelemetryConfigRequest (void)
 
const char * getCategoryName (UnitCategory category)
 
const char * getTypeName (TelemetryType type)
 
void sendCANTelemetryData (TelemetrySignal *signal, uint32_t can_id, uint8_t *data, uint8_t dlc)
 

Variables

static TelemetrySignal signals [MAX_TELEMETRY_SIGNALS]
 
static uint16_t num_signals = 0
 
static bool telemetry_initialized = false
 

Macro Definition Documentation

◆ MAX_TELEMETRY_SIGNALS

#define MAX_TELEMETRY_SIGNALS   100

Definition at line 6 of file Telemetry.c.

Function Documentation

◆ checkTelemetryHealth()

void checkTelemetryHealth ( void  )

Definition at line 111 of file Telemetry.c.

111 {
112 uint32_t now = HAL_GetTick();
113
114 for (uint16_t i = 0; i < num_signals; i++) {
115 TelemetrySignal* sig = &signals[i];
116 if (!sig->enabled) continue;
117
118 uint32_t time_since_update = now - sig->last_update;
119 uint32_t stale_threshold = sig->expected_rate_ms * 3;
120
121 if (time_since_update > stale_threshold) {
122 const UnitDefinition* unit = getUnitDefinition(sig->unit_id);
123 sendMessage("TelemetryHealth", MSG_WARNING,
124 "Signal stale: %s (last update %dms ago, expected every %dms)",
125 sig->name, time_since_update, sig->expected_rate_ms);
126 }
127 }
128}
@ MSG_WARNING
Definition: MessageFormat.h:12
void sendMessage(const char *sender, MessageType type, const char *format,...)
Definition: MessageFormat.c:5
static TelemetrySignal signals[MAX_TELEMETRY_SIGNALS]
Definition: Telemetry.c:8
static uint16_t num_signals
Definition: Telemetry.c:9
const UnitDefinition * getUnitDefinition(UnitId unit_id)
Definition: Units.c:78
uint32_t expected_rate_ms
Definition: Telemetry.h:21
char name[32]
Definition: Telemetry.h:18
UnitId unit_id
Definition: Telemetry.h:20
uint32_t last_update
Definition: Telemetry.h:22
Here is the call graph for this function:

◆ getCategoryName()

const char * getCategoryName ( UnitCategory  category)

Definition at line 161 of file Telemetry.c.

161 {
162 switch (category) {
163 case UNIT_CATEGORY_VOLTAGE: return "Voltage";
164 case UNIT_CATEGORY_CURRENT: return "Current";
165 case UNIT_CATEGORY_PRESSURE: return "Pressure";
166 case UNIT_CATEGORY_TEMPERATURE: return "Temperature";
167 case UNIT_CATEGORY_POSITION: return "Position";
168 case UNIT_CATEGORY_SPEED: return "Speed";
169 case UNIT_CATEGORY_TIME: return "Time";
170 case UNIT_CATEGORY_FREQUENCY: return "Frequency";
171 case UNIT_CATEGORY_STATUS: return "Status";
172 default: return "Other";
173 }
174}
@ UNIT_CATEGORY_STATUS
Definition: Units.h:27
@ UNIT_CATEGORY_FREQUENCY
Definition: Units.h:25
@ UNIT_CATEGORY_TIME
Definition: Units.h:24
@ UNIT_CATEGORY_TEMPERATURE
Definition: Units.h:21
@ UNIT_CATEGORY_PRESSURE
Definition: Units.h:20
@ UNIT_CATEGORY_POSITION
Definition: Units.h:22
@ UNIT_CATEGORY_SPEED
Definition: Units.h:23
@ UNIT_CATEGORY_VOLTAGE
Definition: Units.h:18
@ UNIT_CATEGORY_CURRENT
Definition: Units.h:19
Here is the caller graph for this function:

◆ getTypeName()

const char * getTypeName ( TelemetryType  type)

Definition at line 177 of file Telemetry.c.

177 {
178 switch (type) {
179 case TELEMETRY_SENSOR: return "SENSOR";
180 case TELEMETRY_OUTPUT: return "OUTPUT";
181 case TELEMETRY_CAN_TX: return "CAN_TX";
182 case TELEMETRY_CAN_RX: return "CAN_RX";
183 case TELEMETRY_STATUS: return "STATUS";
184 case TELEMETRY_DEBUG: return "DEBUG";
185 default: return "UNKNOWN";
186 }
187}
@ TELEMETRY_DEBUG
Definition: Telemetry.h:14
@ TELEMETRY_STATUS
Definition: Telemetry.h:13
@ TELEMETRY_OUTPUT
Definition: Telemetry.h:10
@ TELEMETRY_CAN_TX
Definition: Telemetry.h:11
@ TELEMETRY_CAN_RX
Definition: Telemetry.h:12
@ TELEMETRY_SENSOR
Definition: Telemetry.h:9
Here is the caller graph for this function:

◆ handleTelemetryConfigRequest()

void handleTelemetryConfigRequest ( void  )

Definition at line 130 of file Telemetry.c.

130 {
131 sendMessage("Telemetry", MSG_DEBUG, "Configuration requested by GUI");
132
133 // Send total count first
134 sendMessage("TelemetryConfig", MSG_DEBUG, "TotalSignals:%d", num_signals);
135
136 // Send each signal configuration
137 for (uint16_t i = 0; i < num_signals; i++) {
138 TelemetrySignal* sig = &signals[i];
139 const UnitDefinition* unit = getUnitDefinition(sig->unit_id);
140
141 // Send comprehensive configuration
142 sendMessage("TelemetryConfig", MSG_CONFIG,
143 "Signal:%s;Unit:%s;Category:%s;Type:%d;Rate:%d;Min:%.2f;Max:%.2f;Decimals:%d;AbsMin:%.2f;AbsMax:%.2f",
144 sig->name,
145 unit->symbol,
146 getCategoryName(unit->category), // Helper function to get category name
147 unit->data_type,
148 sig->expected_rate_ms,
149 sig->custom_min,
150 sig->custom_max,
151 unit->decimal_places,
152 unit->absolute_min,
153 unit->absolute_max);
154 }
155
156 // Send end marker
157 sendMessage("TelemetryConfig", MSG_DEBUG, "ConfigComplete:1");
158}
@ MSG_DEBUG
Definition: MessageFormat.h:14
@ MSG_CONFIG
Definition: MessageFormat.h:18
const char * getCategoryName(UnitCategory category)
Definition: Telemetry.c:161
float custom_max
Definition: Telemetry.h:24
float custom_min
Definition: Telemetry.h:23
UnitDataType data_type
Definition: Units.h:33
float absolute_min
Definition: Units.h:35
uint8_t decimal_places
Definition: Units.h:39
UnitCategory category
Definition: Units.h:34
char symbol[8]
Definition: Units.h:31
float absolute_max
Definition: Units.h:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initTelemetry()

void initTelemetry ( void  )

Definition at line 12 of file Telemetry.c.

12 {
13 memset(signals, 0, sizeof(signals));
14 num_signals = 0;
16
17 // Initialize units system
18 initUnits();
19
20 sendMessage("Telemetry", MSG_DEBUG, "Telemetry utility initialized");
21}
static bool telemetry_initialized
Definition: Telemetry.c:10
void initUnits(void)
Definition: Units.c:74
Here is the call graph for this function:
Here is the caller graph for this function:

◆ registerTelemetrySignal()

TelemetrySignal * registerTelemetrySignal ( const char *  name,
TelemetryType  type,
UnitId  unit_id,
uint32_t  expected_rate_ms,
float  custom_min,
float  custom_max 
)

Definition at line 23 of file Telemetry.c.

25 {
27 return NULL;
28 }
29
31 const UnitDefinition* unit = getUnitDefinition(unit_id);
32
33 strncpy(sig->name, name, sizeof(sig->name) - 1);
34 sig->name[sizeof(sig->name) - 1] = '\0';
35 sig->type = type;
36 sig->unit_id = unit_id;
37 sig->expected_rate_ms = expected_rate_ms;
38 sig->last_update = HAL_GetTick();
39 sig->enabled = true;
40
41 // Use custom limits if provided, otherwise use unit defaults
42 if (custom_min != custom_max) {
43 sig->custom_min = custom_min;
44 sig->custom_max = custom_max;
45 sig->use_custom_limits = true;
46 } else {
49 sig->use_custom_limits = false;
50 }
51
53
54 sendMessage("Telemetry", MSG_DEBUG, "Registered: %s (%s) [%s] - %dms",
55 name, unit->symbol, getTypeName(type), expected_rate_ms);
56 return sig;
57}
const char * getTypeName(TelemetryType type)
Definition: Telemetry.c:177
#define MAX_TELEMETRY_SIGNALS
Definition: Telemetry.c:6
bool use_custom_limits
Definition: Telemetry.h:25
TelemetryType type
Definition: Telemetry.h:19
float default_warning_min
Definition: Units.h:37
float default_warning_max
Definition: Units.h:38
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendCANTelemetryData()

void sendCANTelemetryData ( TelemetrySignal signal,
uint32_t  can_id,
uint8_t *  data,
uint8_t  dlc 
)

Definition at line 190 of file Telemetry.c.

190 {
191 if (signal == NULL || !signal->enabled ||
192 (signal->type != TELEMETRY_CAN_TX && signal->type != TELEMETRY_CAN_RX)) {
193 return;
194 }
195
196 // Update timestamp
197 signal->last_update = HAL_GetTick();
198
199 // Format data as hex string
200 char hex_data[17] = {0}; // 8 bytes * 2 chars + null terminator
201 for (int i = 0; i < dlc && i < 8; i++) {
202 sprintf(&hex_data[i*2], "%02X", data[i]);
203 }
204
205 MessageType msg_type = (signal->type == TELEMETRY_CAN_TX) ? MSG_CAN_TX : MSG_CAN_RX;
206 sendMessage("CAN", msg_type, "ID:0x%03X;DLC:%d;Data:%s", can_id, dlc, hex_data);
207}
MessageType
Definition: MessageFormat.h:8
@ MSG_CAN_RX
Definition: MessageFormat.h:16
@ MSG_CAN_TX
Definition: MessageFormat.h:15
Here is the call graph for this function:

◆ sendTelemetryValue()

void sendTelemetryValue ( TelemetrySignal signal,
float  value 
)

Definition at line 59 of file Telemetry.c.

59 {
60 if (signal == NULL || !signal->enabled) {
61 return;
62 }
63
64 const UnitDefinition* unit = getUnitDefinition(signal->unit_id);
65
66 // Update timestamp
67 signal->last_update = HAL_GetTick();
68
69 // Handle different telemetry types using the generic sendMessage()
70 switch (signal->type) {
72 // Validate and send sensor data
73 if (!validateUnitValue(signal->unit_id, value)) {
74 sendMessage(signal->name, MSG_ERROR, "Value exceeds physical limits: %.3f %s",
75 value, unit->symbol);
76 return;
77 }
78
79 // Check warning limits
80 float min_limit = signal->use_custom_limits ? signal->custom_min : unit->default_warning_min;
81 float max_limit = signal->use_custom_limits ? signal->custom_max : unit->default_warning_max;
82
83 if (value < min_limit || value > max_limit) {
84 sendMessage(signal->name, MSG_WARNING, "Value out of range: %.3f %s (range: %.1f-%.1f)",
85 value, unit->symbol, min_limit, max_limit);
86 }
87
88 // Send using generic sendMessage - no special sendSensorValue() needed!
89 sendMessage(signal->name, MSG_SENSOR_VALUE, "Value:%.3f;Unit:%s", value, unit->symbol);
90 break;
91
93 sendMessage(signal->name, MSG_OUTPUT_VALUE, "Value:%.0f;Unit:%s", value, unit->symbol);
94 break;
95
97 sendMessage(signal->name, MSG_SYSTEM_STATUS, "Value:%.3f;Unit:%s", value, unit->symbol);
98 break;
99
100 case TELEMETRY_DEBUG:
101 sendMessage(signal->name, MSG_DEBUG, "Value:%.3f;Unit:%s", value, unit->symbol);
102 break;
103
104 case TELEMETRY_CAN_TX:
105 case TELEMETRY_CAN_RX:
106 // CAN data handled separately through sendCANTelemetryData()
107 break;
108 }
109}
@ MSG_ERROR
Definition: MessageFormat.h:13
@ MSG_OUTPUT_VALUE
Definition: MessageFormat.h:10
@ MSG_SENSOR_VALUE
Definition: MessageFormat.h:9
@ MSG_SYSTEM_STATUS
Definition: MessageFormat.h:11
bool validateUnitValue(UnitId unit_id, float value)
Definition: Units.c:94
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ num_signals

uint16_t num_signals = 0
static

Definition at line 9 of file Telemetry.c.

◆ signals

Definition at line 8 of file Telemetry.c.

◆ telemetry_initialized

bool telemetry_initialized = false
static

Definition at line 10 of file Telemetry.c.