Analog & PWM
Cuttlefish provides high-level, board-independent helpers for working with varying signals — the same code works across boards. These are divided into Analog Input (reading voltages via an ADC, an analog-to-digital converter that reads a voltage as a number) and Pulse Width Modulation (PWM — pulse-width modulation, how you dim an LED or run a motor slowly; approximating an analog output).
Analog Input (ADC)
Analog input allows you to read a voltage from a pin and convert it into a digital value. Cuttlefish supports both raw ADC readings and direct voltage measurements.
Basic Reading
To read from an analog pin, switch it to an input first; the returned handle carries the analog methods.
import { A0, UART0, delay } from '@typecad/board';
const serial = UART0.begin(9600);
const sensor = A0.asInput();
while (true) {
// Read raw value (e.g., 0-1023 on Arduino Uno)
const raw = sensor.readAnalog();
serial.println(`Raw ADC: ${raw}`);
delay(100);
}Voltage Sensing
Cuttlefish can automatically convert raw ADC values into volts based on the board’s reference voltage and resolution.
// Read actual voltage (e.g., 2.5 for a 5V system at half-scale)
const voltage = sensor.readVoltage();
serial.println(`Voltage: ${voltage}V`);Configuration
You can query the hardware resolution or set the reference voltage if the microcontroller supports it.
const bits = sensor.getAnalogResolution(); // returns e.g., 10
sensor.setAnalogReference('internal'); // set the ADC reference (e.g. 'internal', 3.3, 5.0)Pulse Width Modulation (PWM)
PWM allows you to simulate an analog output by rapidly toggling a digital pin. It is commonly used for dimming LEDs, controlling motor speed, or driving servos.
Simple PWM
The .pwm() method accepts a percentage (0 to 100), making your code independent of the underlying hardware’s PWM resolution (whether it’s 8-bit, 10-bit, or 16-bit).
import { D9 } from '@typecad/board';
// D9 is a PWM-capable pin on most boards
const led = D9.asOutput();
// Set brightness to 50%
led.pwm(50);PWM Fade Example
Cuttlefish’s percentage-based API simplifies fading logic across different hardware.
import { D9, delay } from '@typecad/board';
const led = D9.asOutput();
let percent = 0;
let direction = 1;
while (true) {
led.pwm(percent);
percent += direction;
if (percent <= 0 || percent >= 100) {
direction *= -1;
}
delay(20);
}API Reference
Analog Methods (Input)
Available on pins switched to input via .asInput() that have ADC capabilities.
| Method | Returns | Description |
|---|---|---|
readAnalog() | number | Returns the raw ADC value (e.g., 0-1023 or 0-4095). |
readVoltage() | number | Returns the measured voltage in Volts. |
getAnalogResolution() | number | Returns the ADC resolution in bits. |
setAnalogReference(v) | void | Sets the ADC reference voltage (e.g., 3.3, 5.0). |
PWM Methods (Output)
Available on pins switched to output via .asOutput() that have PWM hardware.
| Method | Parameters | Description |
|---|---|---|
pwm(percent) | percent: number | Sets the PWM duty cycle as a percentage (0.0 to 100.0). |
getPwmFrequency() | — | Returns the current PWM frequency in Hz. |
getPwmResolution() | — | Returns the PWM timer resolution in bits. |
Capability Guarding
One of Cuttlefish’s core strengths is static capability validation. Because pins are typed, the transpiler will catch errors if you try to use PWM or Analog methods on pins that lack the hardware support. Switching a pin to output or input exposes only the methods that pin’s hardware actually supports.
import { D4, D9, A0 } from '@typecad/board';
const notPwm = D4.asOutput();
notPwm.pwm(50); // Error: D4 does not support PWM on this board
const led = D9.asOutput();
led.pwm(50); // OK: D9 is a PWM-capable pin
const sensor = A0.asInput();
sensor.readAnalog(); // OK: A0 is an analog pin
const nine = D9.asInput();
nine.readAnalog(); // Error: D9 does not have an ADCAdvanced Examples
1. Potentiometer-Controlled LED Brightness
Mapping an analog input directly to a PWM output is trivial with the normalized percentage API.
import { A0, D9, delay } from '@typecad/board';
const pot = A0.asInput();
const led = D9.asOutput();
while (true) {
// Read raw value (0-1023 on Uno)
const val = pot.readAnalog();
// Map raw 10-bit range to 0-100%
const brightness = (val / 1023) * 100;
led.pwm(brightness);
delay(10);
}2. Battery Voltage Monitor
Using readVoltage() simplifies logic by removing the need for manual bit-to-voltage math.
import { A1, delay } from '@typecad/board';
const sense = A1.asInput();
const dividerRatio = 2.0; // Assuming a 10k/10k voltage divider
while (true) {
const vSense = sense.readVoltage();
const vBat = vSense * dividerRatio;
if (vBat < 3.4) {
// Logic for low battery
}
delay(1000);
}On This Page