Project

General

Profile

Waveform Input » History » Version 1

Adam Klama, 06/21/2026 02:37 PM

1 1 Adam Klama
# Waveform Input
2
3
## Overview
4
A **Waveform Input** generates a **timed value** — a waveform — in response to the
5
edges of another input. When the observed input switches on or off, it plays back a
6
sequence of *(time, value)* points you define. Typical uses are clutch-by-wire
7
**engage on button press** and **release on button release**, **blinker / hazard**
8
lights, and simple **test signals**. It watches an input you already configured and
9
produces a value from it.
10
11
## Prerequisites & hardware
12
- A **source input** to observe — usually a button or switch (for example a
13
  [Digital Input](Digital-Input.md)). Create it first and note its identifier.
14
- The observed input is treated as **digital**: a value **< 512 is LOW**, a value
15
  **≥ 512 is HIGH**.
16
  - A **LOW → HIGH** transition fires the **RISE** trigger.
17
  - A **HIGH → LOW** transition fires the **FALL** trigger.
18
- At startup no transition is detected, so the first trigger can occur no earlier
19
  than the second cycle.
20
21
## Add it in the app
22
1. Add a new input and choose **Waveform Input** as the type.
23
2. Set the **Observed input** to the source you want to watch.
24
3. Give it a clear **alias** (e.g. `Clutch Command`).
25
4. Define the **Rise waveform** and **Fall waveform** as lists of *(time, value)*
26
   points.
27
5. Set the **idle values** and the **repeat** / **minimum repeats** behaviour.
28
29
## Settings reference
30
> Schema: `config/WaveformInputConfigData.proto`.
31
32
| Setting | Meaning | Unit | Range / values | Notes |
33
|---|---|---|---|---|
34
| **Observed input** | The input whose edges trigger the waveforms | — | int32 (input id) | Read as digital: `< 512` LOW, `≥ 512` HIGH. |
35
| **Rise waveform** | Points played on a LOW → HIGH edge | (ms, value) pairs | list of sint32 times + sint32 values | Time stamps in ms; output value at each point. An empty list outputs the idle value. |
36
| **Fall waveform** | Points played on a HIGH → LOW edge | (ms, value) pairs | list of sint32 times + sint32 values | As above, for the falling edge. |
37
| **Rise repeat** | Loop the rise waveform | — | on / off | **Off:** play once, then hold the idle value (or stop early if a new trigger arrives and minimum repeats > 0). **On:** when the timer passes the last point, reset and replay from the start. |
38
| **Fall repeat** | Loop the fall waveform | — | on / off | As above, for the fall waveform. |
39
| **Rise minimum repeats** | Full plays before a new trigger can interrupt the rise waveform | plays | int (`0`, `1`, `n`) | `0` = interruptible as soon as the next trigger is seen; `1` = play at least once fully; `n` = at least n times. **Ignored when Rise repeat is off.** |
40
| **Fall minimum repeats** | Full plays before a new trigger can interrupt the fall waveform | plays | int (`0`, `1`, `n`) | As above, for the fall waveform. |
41
| **Idle value (LOW)** | Output when no waveform is playing and the observed input is LOW | value | sint32 | Held between waveforms. |
42
| **Idle value (HIGH)** | Output when no waveform is playing and the observed input is HIGH | value | sint32 | The input picks LOW or HIGH idle from the observed input's current state. |
43
44
### How a waveform is described
45
Each waveform is a list of **(time, value)** points. After a trigger, a timer starts
46
at `0 ms` and the input outputs the value scheduled for the elapsed time, **linearly
47
interpolating** between points to give a smooth ramp:
48
49
```
50
value
51
 1000 |          ______
52
      |         /
53
    0 |________/
54
      +--------+----+----> time (ms)
55
      0       200  300
56
   points: (0,0) (200,1000) (300,1000)   -> interpolated between points
57
```
58
59
When the timer passes the **last** point, the input either holds the idle value
60
(repeat off) or resets to `0 ms` and plays again (repeat on).
61
62
## Common settings
63
Waveform Input also uses the shared setting — alias. See
64
[Common IO Settings](../Common-IO-Settings.md).
65
66
## Example — clutch engage on press, ramped release on release
67
Watch a clutch button (a [Digital Input](Digital-Input.md)) and drive a clutch
68
command from `0` (open) to `1000` (closed).
69
70
1. Type **Waveform Input**, alias `Clutch Command`, **Observed input** = the
71
   clutch button.
72
2. **Rise waveform** (button pressed → engage quickly):
73
   `(0 ms, 0) → (200 ms, 1000)` — ramps up over 200 ms.
74
3. **Fall waveform** (button released → ramp out gently):
75
   `(0 ms, 1000) → (600 ms, 0)` — ramps down over 600 ms.
76
4. **Rise repeat off**, **Fall repeat off** — each plays once, then holds idle.
77
5. **Idle value (LOW)** `0`, **Idle value (HIGH)** `1000` — so once engaged it
78
   stays closed and once released it stays open.
79
80
For a **hazard light** instead: put a square pulse in the Rise waveform and turn
81
**Rise repeat on** so it blinks continuously until the next trigger.
82
83
## Troubleshooting
84
- **Nothing happens on the first press:** at startup no edge exists; the first
85
  trigger comes no earlier than the second cycle. Toggle the input once.
86
- **Waveform never stops / keeps looping:** **repeat** is on. Turn it off for a
87
  one-shot, or set **minimum repeats** so the next trigger can interrupt it.
88
- **A new press is ignored mid-play:** **minimum repeats** is too high — lower it
89
  (or use `0`) so the next trigger can interrupt.
90
- **Output sits at the wrong level between presses:** check **Idle value (LOW/HIGH)**.
91
- **Ramp too fast or too slow:** adjust the point **timestamps** — the output
92
  interpolates linearly between consecutive points.
93
- **Triggers fire on the wrong edge:** LOW/HIGH is split at **512** — make sure the
94
  observed input crosses that threshold.
95
96
## Related
97
- [Digital Input](Digital-Input.md) — a typical button/switch source to observe.
98
- [Constant Value Input](Constant-Value-Input.md) — a fixed value with no timing.
99
- [Counter Input](Counter-Input.md) — count edges rather than play a waveform.