rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
servo_screen.c File Reference

The servo bench screen. More...

#include "servo_screen.h"
#include <string.h>
#include "kst_panel.h"
#include "outputs.h"
#include "servo_limrun.h"
#include "servo_sweep.h"
#include "supply_screen.h"
#include "ui_keypad.h"
#include "ui_plot.h"
#include "ui_slider.h"
#include "ui_tabs.h"
#include "ui_textkey.h"
#include "ui_text.h"
#include "ui_value_gate.h"
#include "ui_widgets.h"
#include "servo_screen_core_int.h"

Macros

#define SAMPLE_HZ   20.0f
#define RATES(a)

Functions

static float half_travel_us (bool below)
float svs_deg_to_us_f (float deg)
 The angle deg as a pulse, us, through the profile, the trim, REVERSE and the ends; svs_deg_to_us() rounds it.
uint16_t svs_deg_to_us (float deg)
 The angle deg as a pulse, us, rounded.
float us_to_deg_f (float us)
servo_map_t svs_map_now (void)
 The mapping in force now.
float svs_map_cmd_to_us (const servo_map_t *m, float cmd)
 A command of m's range as a pulse, us.
float svs_map_us_to_deg (const servo_map_t *m, float us)
 A pulse as m's angle, degrees, held to its TRAVEL.
float svs_us_to_cmd (float us)
 A pulse as the far end's command, 0..OUT_SPAN of the range a command carries, and back.
float svs_cmd_to_us (float cmd)
 A far-end command, 0 to OUT_SPAN, as a pulse, us.
float svs_rest_deg (void)
 The angle the pin drives on an armed bench while nothing commands it: the outputs layer's rest for a surface.
void release (void)
uint16_t svs_slew_of (int pct)
 SPEED as the bench's slew.
void post (servo_cmd_kind_t kind, uint16_t us)
void reissue (void)
bool svs_command (float deg)
 A position from an input, refused while the value is not live.
void svs_drop_motion (void)
 A motion command still waiting is dropped as the bench stops driving; a release, an arm and a disarm stay.
void apply_profile (int t, uint16_t hz)
 A profile goes into force: a type with its own pulse widths when it is a different type, and a frame rate no faster than its pulses allow.
void ask_profile (int t, uint16_t hz)
 A profile asked for: one that can destroy a servo not made for it opens the warning, and goes into force only once that has been held; any other goes into force at once.
void servo_invalidate (void)
static void reset (void)
 The screen at its start: the state cleared, STANDARD PWM at 50Hz, and the output card's controls, the strip, the sessions, the plot and SETTINGS' tabs laid out.
void test_tell (void)
void servo_screen_on_testing (void(*told)(bool running))
void svs_ask_disarm (void)
 DISARM asked of an armed bench: the value leaves LIVE now.
void servo_screen_service (void)
void servo_screen_clock (uint32_t now_ms)
static void leave (void)
static void enter (void)
static void cancel (void)
static void tick (float dt_s)
static void event (const touch_event_t *evt)
static bool back (void)
const ui_screen_t * servo_screen (void)

Variables

static const uint16_t k_std_rates [] = { 50, 60, 100, 150, 200, 250, 300, 333 }
static const uint16_t k_cyc_rates [] = { 50, 120, 200, 333 }
static const uint16_t k_tail_rates [] = { 200, 333, 560 }
const servo_type_t k_types []
static const ui_text_id_t k_pages [PG_COUNT]
static const ui_plot_series_t k_power [PS_COUNT]
servo_screen_state_t s
static void(*) s_testing_told (bool running)
static bool s_testing_last
static const ui_screen_t k_screen

Detailed Description

The servo bench screen.

The horn is the control: dragging the drawn arm commands the servo, and the arm is drawn at the measured position, so a servo that is slow, stuck or fighting a linkage lags the finger by that much.

A workbench (ui_workbench.h): the strip under the band shows LIVE, the dial; TEST, the run cards; SETTINGS, the servo's type, frame rate and pulse widths, the sweep and the device under test. The right card is the output card on every task. The strip, the TEST page and the TARGET row are servo_workbench.c; the pages of rows and the panels they open are servo_settings_panel.c; the state and the layout the files share are servo_screen_int.h. This file is the state, the profiles, the command and the screen's hooks; the sweep and the frame step are servo_screen_sweep.c, what the panel reports servo_screen_link.c, the presses servo_screen_touch.c and the drawing servo_screen_draw.c, with servo_screen_core_int.h between them.

A type or a frame rate that can destroy a servo not made for it – a heli profile, anything above 60Hz – is applied only after a warning held for two seconds, and is never kept past a restart.

START TEST, on TEST's AUTOMATIC TEST card, runs the automatic test (servo_test.h): the screen hands it the supply's samples and the clock, and does what it asks – the servo's position, SUPPLY's set points and output – through the same paths a finger uses. The run's code is servo_test_panel.c. START LIMIT RUN, on the LIMIT RUN card, runs the limit run (servo_limrun.h) the same way; its code is servo_limit_panel.c.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ RATES

#define RATES ( a)
Value:
(a), (uint8_t)(sizeof(a) / sizeof((a)[0]))

Function Documentation

◆ apply_profile()

void apply_profile ( int t,
uint16_t hz )

A profile goes into force: a type with its own pulse widths when it is a different type, and a frame rate no faster than its pulses allow.

Parameters
tthe profile's index in k_types
hzthe frame rate asked for

◆ ask_profile()

void ask_profile ( int t,
uint16_t hz )

A profile asked for: one that can destroy a servo not made for it opens the warning, and goes into force only once that has been held; any other goes into force at once.

Parameters
tthe profile's index in k_types
hzthe frame rate asked for

◆ servo_invalidate()

void servo_invalidate ( void )

Drop the cached chrome, so the next frame repaints it.

◆ servo_screen_clock()

void servo_screen_clock ( uint32_t now_ms)

The panel's millisecond clock, every frame before the tick: the clock the supply's readings are stamped with (supply_state_t.taken_ms), so a travel time is measured on one clock. Without it the screen's own is used.

◆ servo_screen_on_testing()

void servo_screen_on_testing ( void(* told )(bool running))

told is called with true when a run of the automatic test starts and with false when it ends, inside the call that starts or ends it – a touch event, a window, a supply sample, the meter, the link, a tick – and not at the next frame. The panel's control task writes no bench log row between the two (log_cadence_bench_run()). NULL for none. It is called from the task that runs the screen and must not call back into it.

◆ servo_screen_service()

void servo_screen_service ( void )

Every frame, whichever screen is up: a run's end is seen, and SUPPLY's set points go back to what they were before it once its OFF has gone, a sample taken after that shows the output off, no ON is on its way and OUTPUT ON is not being held, here or on SUPPLY – unless they were set since it ended.

◆ svs_cmd_to_us()

float svs_cmd_to_us ( float cmd)

A far-end command, 0 to OUT_SPAN, as a pulse, us.

Parameters
cmdthe command
Returns
the pulse, us

◆ svs_command()

bool svs_command ( float deg)

A position from an input, refused while the value is not live.

Parameters
degthe angle asked for, degrees; held to TRAVEL
Returns
true when the position was posted

◆ svs_deg_to_us()

uint16_t svs_deg_to_us ( float deg)

The angle deg as a pulse, us, rounded.

Parameters
degthe angle, degrees
Returns
the pulse, us

◆ svs_deg_to_us_f()

float svs_deg_to_us_f ( float deg)

The angle deg as a pulse, us, through the profile, the trim, REVERSE and the ends; svs_deg_to_us() rounds it.

Parameters
degthe angle, degrees
Returns
the pulse, us

◆ svs_map_cmd_to_us()

float svs_map_cmd_to_us ( const servo_map_t * m,
float cmd )

A command of m's range as a pulse, us.

Parameters
mthe mapping
cmdthe command, 0 to OUT_SPAN
Returns
the pulse, us

◆ svs_map_now()

servo_map_t svs_map_now ( void )

The mapping in force now.

Returns
the mapping

◆ svs_map_us_to_deg()

float svs_map_us_to_deg ( const servo_map_t * m,
float us )

A pulse as m's angle, degrees, held to its TRAVEL.

Parameters
mthe mapping
usthe pulse, us
Returns
the angle, degrees

◆ svs_rest_deg()

float svs_rest_deg ( void )

The angle the pin drives on an armed bench while nothing commands it: the outputs layer's rest for a surface.

Returns
the angle, degrees

◆ svs_slew_of()

uint16_t svs_slew_of ( int pct)

SPEED as the bench's slew.

Parameters
pctSPEED, %
Returns
channel-span units a second; 0 at 100%, which is no slew

◆ svs_us_to_cmd()

float svs_us_to_cmd ( float us)

A pulse as the far end's command, 0..OUT_SPAN of the range a command carries, and back.

Parameters
usthe pulse, us
Returns
the command, 0 to OUT_SPAN

Variable Documentation

◆ k_pages

const ui_text_id_t k_pages[PG_COUNT]
static
Initial value:
= {
TX_SV_PG_OUTPUT, TX_SV_PG_SWEEP, TX_SV_PG_DUT,
}

◆ k_power

const ui_plot_series_t k_power[PS_COUNT]
static
Initial value:
= {
{ "V", "V", 0, 2, 5.0f, 0 },
{ "A", "A", 0, 2, 0.5f, 0 },
{ "W", "W", 0, 1, 5.0f, 0 },
}

◆ k_screen

const ui_screen_t k_screen
static
Initial value:
= {
.title = "SERVO",
.reset = reset,
.enter = enter,
.leave = leave,
.tick = tick,
.event = event,
.cancel = cancel,
.render = svs_render,
.back = back,
.safe_at = svs_safe_at,
}
static void event(const touch_event_t *evt)
One touch event: the tabs are the screen's one control.
Definition analyser_screen.c:242
static void cancel(void)
The panel could not hand over every touch event, so this screen's record of the glass is stale.
Definition analyser_screen.c:658
static void reset(void)
The screen's state cleared: CHANNELS shown, nothing decoded, the tabs laid out.
Definition analyser_screen.c:176
static bool back(void)
The home tag: over the keypad it is CANCEL.
Definition balance_screen.c:251
static void leave(void)
The screen is left: the keypad closes, with nothing typed taken.
Definition balance_screen.c:264
static void tick(float dt_s)
Time passed: the acknowledge flash runs on by dt_s.
Definition busfault_screen.c:359
void svs_render(gfx_canvas_t *c, int buffer_index)
The frame: what changed since buffer_index was last drawn.
Definition servo_screen_draw.c:935
bool svs_safe_at(int x, int y)
Whether a DOWN at (x, y) lands on a control whose press stops what the bench drives.
Definition servo_screen_touch.c:45

◆ k_types

const servo_type_t k_types[]
Initial value:
= {
{ "STANDARD PWM", 1000, 1500, 2000, RATES(k_std_rates), 50, 0, false },
{ "NARROW 760", 660, 760, 860, RATES(k_std_rates), 50, 0, false },
{ "WIDE", 800, 1500, 2200, RATES(k_std_rates), 50, 0, false },
{ "HELI CYCLIC", 820, 1520, 2220, RATES(k_cyc_rates), 333, 333, true },
{ "HELI TAIL 760", 410, 760, 1110, RATES(k_tail_rates), 560, 560, true },
}