Skip to main content

Analog Inputs

Wiring potentiometers, slide pots and hall-effect sensors to an ESP32 for throttles, trim wheels, and panel dimmers — and turning their jittery readings into a steady 0–1 value.

Analog Sensor Types

A button or switch is either on or off. An analog input reports a position anywhere along its travel: how far the throttle lever is pushed, where the trim wheel sits, how bright the panel lights should be. The sensor turns that position into a voltage between 0 V and 3.3 V, and the ESP32's analog-to-digital converter (ADC) reads it as a number from 0 to 4095. At its widest setting (11 dB attenuation) the ADC tops out at about 3.1 V, so the last few degrees of a pot's travel all read 4095. Calibration sets the real end points, so that doesn't matter.

SensorExampleCockpit use
Rotary potentiometer10 kΩ linear (B10K), 16 mm or 24 mmPanel dimmers, rudder trim, cabin temperature
Slide potentiometer60–100 mm travel, 10 kΩ linearThrottle, mixture and prop levers, flap lever
Hall-effect sensorSS49E or DRV5055 (3.3 V version) with a magnetYokes, pedals and levers that must never wear out
Multi-turn potentiometer10-turn wirewoundElevator trim wheel with many turns end to end
Wiring
3.3 V GPIO 34 GND Potentiometer 10 kΩ linear (B) wiper → ADC1 pin 0 V … ~3.1 V = 0 … 4095 100 nF

A potentiometer is a voltage divider. Its two outer legs go to 3.3 V and GND, and the middle leg (the wiper) goes to the ESP32 pin. As the shaft turns, the wiper voltage moves between 0 V and 3.3 V. Swap the outer legs if the value runs the wrong way, or leave the wiring and swap the ends in calibration instead.

Potentiometer legConnect to
Outer leg 13.3 V
Wiper (middle)ADC1 pin, e.g. GPIO 34 — optional 100 nF capacitor to GND at the pin
Outer leg 2GND

Hall-effect sensors

A linear hall sensor such as the SS49E or the 3.3 V DRV5055 (DRV5055A1–A4) has three legs: VCC, GND and OUT. Pick one rated for 3.3 V and power it from 3.3 V, so its output never exceeds what the ADC tolerates, then wire OUT to an ADC1 pin. Parts that need 5 V, such as the A1324, would need a voltage divider on OUT. Fix a small neodymium magnet to the moving part so it sweeps past the sensor face. The output sits near half the supply with no field and moves up or down with the magnet's pole, so expect a usable range well inside 0–4095 — calibration takes care of that.

More analog inputs than ADC1 pins

A CD4067 16-channel multiplexer puts sixteen potentiometers on one ADC pin plus four select lines. Wire each wiper to a mux channel and the mux signal pin to an ADC1 pin. See the I/O expanders page for the mux wiring.

Arduino Code — Basic Read

analogRead() returns 0–4095 at 12-bit resolution. Dividing by 4095 gives a 0–1 value that does not depend on the ADC's resolution.

// Read a potentiometer on an ADC1 pin and print a 0–1 value
const int POT_PIN = 34;          // ADC1 — keeps working while WiFi is on

void setup() {
    Serial.begin(115200);
    analogReadResolution(12);    // 0–4095
    analogSetPinAttenuation(POT_PIN, ADC_11db);  // widest range, about 0–3.1 V
}

void loop() {
    int raw = analogRead(POT_PIN);
    float value = raw / 4095.0f;
    Serial.println(value, 3);
    delay(20);
}
Calibration, Deadband & Centre Deadzone

Raw readings are never as clean as the basic sketch suggests. Three things turn them into a value a simulator can use:

SettingWhat it fixesTypical value
Calibration (min / max) A lever whose linkage only turns the pot part of the way, e.g. from 180 to 3900. Those readings become 0 and 1. Set min above max to reverse the direction. Measured per lever
Centre A self-centring part such as a yoke or rudder pedals, whose rest point is not exactly at half travel Reading at rest
Centre deadzoneSmall wobble around the centre of a spring-centred axis0–0.2 of the travel
Deadband An idle ADC pin jitters by a few counts all the time; changes smaller than the deadband are not reported 0.005 (0.5 %), range 0.001–0.1
// Oversample, smooth, calibrate and only report real movement
const int   POT_PIN  = 34;
const int   RAW_MIN  = 180;      // reading at one end of the travel
const int   RAW_MAX  = 3900;     // reading at the other end
const float DEADBAND = 0.005f;   // ignore changes smaller than 0.5 %

float smoothed = 0;
float lastSent = -1;

int oversample(int pin) {
    long sum = 0;
    for (int i = 0; i < 16; i++) {
        sum += analogRead(pin);
    }
    return sum / 16;
}

void setup() {
    Serial.begin(115200);
    analogReadResolution(12);
    smoothed = oversample(POT_PIN);
}

void loop() {
    smoothed += (oversample(POT_PIN) - smoothed) * 0.2f;   // simple low-pass

    float value = (smoothed - RAW_MIN) / float(RAW_MAX - RAW_MIN);
    value = constrain(value, 0.0f, 1.0f);

    if (fabs(value - lastSent) >= DEADBAND) {
        lastSent = value;
        Serial.println(value, 3);
    }
    delay(20);                    // at most 50 reports a second
}

On a CockpitConnect controller you don't write this: the board oversamples, smooths and calibrates every Analog Input itself, then reports a value from 0 to 1 — only when it moves by more than the deadband, and at most 50 times a second. You set the calibration, centre deadzone and deadband per pin in the Flow Builder, and a Mapping's map transform takes 0–1 to the dataref's range.

Cockpit Applications
ApplicationSensorNotes
Throttle quadrantSlide pot or rotary pot on the lever pivotCalibrate idle and full power; one ADC1 pin per lever
Panel & flood light dimmersRotary pot, linearMap 0–1 straight to the brightness ratio dataref
Yoke and rudder pedalsHall sensor and magnetCalibrate the centre and add a small centre deadzone
Elevator trim wheelMulti-turn potOr an encoder, if the wheel has no end stops
Flap lever with detentsRotary potA range lookup turns the position into flap settings