rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
bench_state.h
Go to the documentation of this file.
1
15#pragma once
16
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
20
21#include "link_pages.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
28#define BENCH_CHW_CHANNELS 12u
29
40typedef struct {
41 uint16_t window;
42 uint16_t ok;
43 uint16_t no_current;
44 uint16_t no_voltage;
45 int16_t mean_ma[BENCH_CHW_CHANNELS];
46 int16_t max_ma[BENCH_CHW_CHANNELS];
47 uint16_t min_mv[BENCH_CHW_CHANNELS];
49
54typedef struct {
55 float voltage;
56 float current;
57 float power;
58 float rpm;
59 float temp_esc;
60 float temp_motor;
61 float charge_mah;
62 float energy_wh;
63
64 /* Peaks and sag, tracked by the end that has the fast samples. */
65 float voltage_min;
66 float current_max;
67 float power_max;
68 float rpm_max;
69
70 uint16_t flags;
79 uint8_t counted;
80 bool valid;
90
91 /*
92 * The ESC's own telemetry while the INA228 is BENCH's source
93 * (LINK_BN_SENSED), from the SENSE page: voltage and current, each
94 * valid with its bit in esc_ok (LINK_SN_ESC_VOLTAGE_OK,
95 * LINK_SN_ESC_CURRENT_OK). Not on the BENCH page; without SENSED the
96 * BENCH numbers are the ESC's and these are not used.
97 */
100 uint8_t esc_ok;
107
108 /*
109 * One 50ms window of the INA3221's channels, from SERVO_WIN (CH1) and
110 * SERVO_SENSE, for the log: servo_new while it has not been written to
111 * a row, so each window reaches the log once, keyed by its number.
112 * Per channel the mean and highest current in mA, signed, and the
113 * lowest bus voltage in mV, as the page carries them; bit n-1 of
114 * servo_ok says CHn's window holds readings. Bit n-1 of
115 * servo_no_current says it holds no current sample, and of
116 * servo_no_voltage no voltage sample: the figures of that quantity
117 * read 0 and are not readings, and the log leaves their cells empty.
118 * SERVO_WIN says which for CH1; SERVO_SENSE's flags do not, and both
119 * stay 0 for a channel read from it. Not on the BENCH page.
120 */
121 bool servo_new;
122 uint8_t servo_ok;
123 uint8_t servo_no_current;
124 uint8_t servo_no_voltage;
125 uint16_t servo_window;
126 int16_t servo_mean_ma[3];
127 int16_t servo_max_ma[3];
128 uint16_t servo_min_mv[3];
135
142static inline bool bench_state_simulated(const bench_state_t *b)
143{
144 return b != NULL && (b->flags & LINK_BN_SIMULATED) != 0;
145}
146
159void bench_state_from_regs(bench_state_t *b, const uint16_t *regs,
160 uint8_t offset, uint8_t count);
161
168void bench_state_to_regs(const bench_state_t *b, uint16_t *regs);
169
182void bench_state_run_starts(bench_state_t *b, uint16_t *regs);
183
196void bench_state_log_row(const bench_state_t *b, bool whole,
197 bench_state_t *out);
198
205
220void bench_state_set_esc(bench_state_t *b, bool v_ok, float volts,
221 bool i_ok, float amps, bool clipped);
222
235bool bench_state_esc_voltage(const bench_state_t *b, float *out);
244bool bench_state_esc_current(const bench_state_t *b, float *out);
245
255bool bench_state_ina_voltage(const bench_state_t *b, float *out);
263bool bench_state_ina_current(const bench_state_t *b, float *out);
264
270#define BENCH_FINE_MAH_TOL 2.0f
271#define BENCH_FINE_WH_TOL 0.2f
272
278#define BENCH_CHARGE_MAH_MAX 65535.0f
279#define BENCH_ENERGY_WH_MAX 6553.5f
280
294void bench_state_fine_totals(bench_state_t *b, int32_t charge_cmah,
295 uint32_t energy_cwh);
296
301#define BENCH_COUNTED_CHARGE 0x01u
306#define BENCH_COUNTED_ENERGY 0x02u
307
309#define BENCH_TOTALS_MAX_STEP_S 1.0f
310
332typedef struct {
333 float mah;
334 float wh;
335 uint8_t counted;
336 float run_s;
338
347#define BENCH_TOTALS_SETTLE_S 0.1f
348
355
374 float dt_s, bool driving);
375
383
395
396/*
397 * How stale a speed may be before it stops being reported.
398 *
399 * Frames go out at a kilohertz, so a reply older than this is not a slow
400 * update but an ESC that has stopped answering -- unplugged, or one that
401 * never did bidirectional DShot. A held-over speed on a stopped motor is
402 * exactly the plausible wrong number this bench exists to avoid.
403 */
404#define BENCH_RPM_STALE_MS 200u
405
406/*
407 * How old an extended-telemetry reading may be before the field goes empty.
408 *
409 * Longer than BENCH_RPM_STALE_MS because the rates are not the same: an ESC
410 * answers every frame with a period and interleaves temperature, voltage and
411 * current between them a few times a second. Holding those to the speed's
412 * window would blank fields that are arriving exactly as the protocol sends
413 * them.
414 */
415#define BENCH_EDT_STALE_MS 2000u
416
418typedef struct {
419 bool ok;
420 uint16_t count;
421 uint32_t age_ms;
423
437
455
456#ifdef __cplusplus
457}
458#endif
void bench_state_fine_totals(bench_state_t *b, int32_t charge_cmah, uint32_t energy_cwh)
With LINK_BN_TOTALS_OK, the INA228's totals in the SENSE page's finer steps – charge_cmah in 0....
Definition bench_state.c:355
void bench_state_run_starts(bench_state_t *b, uint16_t *regs)
A run starts: the totals of the last one go, in b and in the BENCH page regs built from it – charge a...
Definition bench_state.c:131
void bench_state_from_telem(bench_state_t *b, const bench_telem_t *t)
The live readings of b and their valid bits from t, for the IOmcu's sample.
Definition bench_state.c:407
void bench_totals_count(bench_totals_t *t, const bench_state_t *b, float dt_s, bool driving)
Add dt_s of b's readings, while driving, and only what its flags mark measured: charge from a current...
Definition bench_state.c:193
void bench_state_to_regs(const bench_state_t *b, uint16_t *regs)
Encode into a BENCH page, for the IOmcu and for round-trip tests.
Definition bench_state.c:110
bool bench_state_esc_current(const bench_state_t *b, float *out)
The ESC's own current, from the same source as bench_state_esc_voltage().
Definition bench_state.c:318
void bench_totals_show(const bench_totals_t *t, bench_state_t *b)
Write the totals into b, over whatever its source put there.
Definition bench_state.c:241
void bench_state_from_regs(bench_state_t *b, const uint16_t *regs, uint8_t offset, uint8_t count)
Decode a BENCH page into b.
Definition bench_state.c:81
bool bench_state_esc_voltage(const bench_state_t *b, float *out)
The ESC's own voltage and current, whichever page carries them: the SENSE page's while the INA228 is ...
Definition bench_state.c:311
bool bench_state_ina_voltage(const bench_state_t *b, float *out)
The INA228's own voltage and current: BENCH's while it is the source.
Definition bench_state.c:345
void bench_state_set_esc(bench_state_t *b, bool v_ok, float volts, bool i_ok, float amps, bool clipped)
The ESC's own figures while the INA228 is the source: from the SENSE page's ESC registers,...
Definition bench_state.c:251
void bench_totals_reset(bench_totals_t *t)
A run begins: nothing counted.
Definition bench_state.c:183
bool bench_state_ina_current(const bench_state_t *b, float *out)
The INA228's own current: BENCH's while it is the source.
Definition bench_state.c:350
void bench_state_log_row(const bench_state_t *b, bool whole, bench_state_t *out)
One row of the bench log from b, into out.
Definition bench_state.c:145
void bench_state_track_peaks(bench_state_t *b)
Take the live readings into the peaks.
Definition bench_state.c:382
void bench_state_reset_peaks(bench_state_t *b)
Clear the peaks without disturbing the live readings.
Definition bench_state.c:167
#define BENCH_CHW_CHANNELS
The INA3221 channels SENSE_WIN_A and SENSE_WIN_B carry (4.25).
Definition bench_state.h:28
static bool bench_state_simulated(const bench_state_t *b)
True when the numbers are modelled rather than measured.
Definition bench_state.h:142
One 50ms window of every INA3221 channel, from SENSE_WIN_A and SENSE_WIN_B (protocol 4....
Definition bench_state.h:40
One extended-telemetry reading as the DShot driver holds it.
Definition bench_state.h:418
uint32_t age_ms
Definition bench_state.h:421
bool ok
Definition bench_state.h:419
uint16_t count
Definition bench_state.h:420
The bench readings in the units a person reads: V, A, W and rpm, with their peaks.
Definition bench_state.h:54
float rpm
Definition bench_state.h:58
uint8_t counted
Which of charge_mah and energy_wh the panel has counted this run (BENCH_COUNTED_*).
Definition bench_state.h:79
float charge_mah
Definition bench_state.h:61
float voltage
Definition bench_state.h:55
bool sag_seeded
Whether voltage_min is a measurement yet.
Definition bench_state.h:89
uint16_t flags
Definition bench_state.h:70
float energy_wh
Definition bench_state.h:62
bool valid
Definition bench_state.h:80
float esc_voltage
Definition bench_state.h:98
float temp_esc
Definition bench_state.h:59
float temp_motor
Definition bench_state.h:60
bool clipped
The INA228 read its current at the end of its range in the last window or since the arm (SENSE FLAGS ...
Definition bench_state.h:106
bench_chw_t chw
The same window of every channel the map reads, ok 0 for none: on the row of servo_window,...
Definition bench_state.h:133
float current
Definition bench_state.h:56
float esc_current
Definition bench_state.h:99
float power
Definition bench_state.h:57
The ESC's telemetry as the IOmcu reads it at a sample: raw, with each reading's age and whether there...
Definition bench_state.h:428
uint32_t erpm_age_ms
Definition bench_state.h:432
bench_edt_reading_t current
Definition bench_state.h:434
uint16_t poles
Definition bench_state.h:429
uint32_t erpm
Definition bench_state.h:431
bool erpm_ok
Definition bench_state.h:430
bench_edt_reading_t voltage
Definition bench_state.h:433
bench_edt_reading_t temperature
Definition bench_state.h:435
A run's charge and energy, counted by the panel.
Definition bench_state.h:332
uint8_t counted
Definition bench_state.h:335
float run_s
Definition bench_state.h:336