Analog & PWM
Three thin classes for varying signals: ADC (analog in), DAC (analog out), and PWM (pulse-width out). All three follow the HAL rule — construction is the channel setup, and the units are Zephyr’s own: raw counts, millivolts, nanoseconds. No 0–255, no 0–1023.
ADC — ADC
Construction sets up the channel: gain and reference are constructor options, defaulting to the pair your chip’s driver validates against when omitted.
import { ADC } from '@typecad/hal';
import { A1 } from '@typecad/board';
const sense = new ADC(A1, {
gain: ADC.GAIN_1_3,
reference: ADC.REF_INTERNAL,
});
const counts = sense.read(); // raw counts at the chip's resolution
const mv = sense.readMillivolts(); // converted to millivoltsThere is no setReference() — Zephyr applies the reference at channel-setup time, and the class does not pretend otherwise. The gain and reference tokens are Zephyr’s enum names under the ADC. namespace (ADC_GAIN_1_4 ↔ ADC.GAIN_1_4); the token set is generated from the Zephyr headers, so a misspelling is an editor error and an invalid pair is a build error naming the valid tokens for your chip.
DAC — DAC
Construction carries the resolution in bits (omitted = your chip’s channel resolution). write() takes the raw code — 0–255 for an 8-bit channel, 0–4095 for 12-bit:
import { DAC } from '@typecad/hal';
const out = new DAC(DAC0);
out.write(128); // mid-scale on an 8-bit channelPWM — PWM
The period is a required construction fact, in nanoseconds — the channel’s time base exists before any pulse does:
import { PWM } from '@typecad/hal';
const servo = new PWM(6, { periodNs: 20_000_000 }); // 50 Hz
servo.setPulse(1_500_000); // 1.5 ms — center
const dimmer = new PWM(7, { periodNs: 1_000_000 }); // 1 kHz LED dimming
dimmer.setDuty(0.5); // fraction 0.0–1.0setPulse(ns)— the verbatimpwm_set_pulse_dt.setDuty(fraction)— sugar over the constructed period, still one call.setPeriod(ns)— changes the period; the pulse resets to idle, so follow it withsetPulse/setDuty.
On ESP32 targets the PWM channels are assigned at build time to the pins your program actually drives; a pin outside the chip’s PWM-capable set is flagged at build time, naming the pins that can.
When your board’s facts don’t cover a pin — or you know a routing the catalog doesn’t — you can supply the routing yourself: a project facts file or per-construction overrides. Both are facts, not bypasses. See Custom Pin Facts.
API Reference
| Member | Description |
|---|---|
new ADC(pin, opts?) | gain / reference — ADC.GAIN_* / ADC.REF_* tokens. |
read() / readMillivolts() | Raw counts / millivolts. |
new DAC(pin, opts?) | resolution in bits; omitted = chip default. |
write(value) | Raw code at the channel’s resolution. |
new PWM(pin, { periodNs }) | Period is required (ns). |
setPulse(ns) / setDuty(f) / setPeriod(ns) | Pulse control; one Zephyr call each. |
On This Page