Loading header...

Exercise: Calibrate a Sensor

This exercise builds a practical calibration workflow. You will collect two known points, compute scale and offset, convert raw ADC readings into engineering units, and verify the result. The example uses a simulated linear displacement sensor so the code can be built on a laptop before being moved to embedded firmware.

Learning Objectives

You will:

  • perform two-point calibration for a linear sensor;
  • implement fixed-point conversion without floating-point dependency;
  • verify zero, span, midpoint, and monotonic behavior;
  • identify offset, gain, noise, saturation, and reversed-wiring faults;
  • document calibration constants with clear units.

Prerequisites

  • Basic ADC concepts: code, resolution, reference voltage, and input range.
  • Basic C programming with integer arithmetic.
  • Ability to compile C code on a host computer or embedded target.
  • A sensor, potentiometer, calibration jig, or simulated voltage source with two known reference points.
  • Safe access to the mechanism with power removed or motion disabled during setup.

Task

A linear displacement sensor is read by an ADC. During calibration:

  • at 0.00 mm, the measured raw code is 820;
  • at 100.00 mm, the measured raw code is 3270.

Write code that converts any raw code to displacement in 0.01 mm units. Clamp the result below zero and above span. Then verify that the midpoint code reports 50.00 mm.

Calibration Formula

For two-point linear calibration:

$$
y = y_0 + (x - x_0)\frac{y_1 - y_0}{x_1 - x_0}
$$

For this exercise, x is raw ADC code and y is position in centi-millimetres.

Buildable Implementation

Save this as sensor_calibration.c and build with a normal C compiler, for example gcc sensor_calibration.c -o sensor_calibration.

#include <stdint.h>
#include <stdio.h>

#define CODE_ZERO 820
#define CODE_SPAN 3270
#define POS_ZERO_CENTI_MM 0
#define POS_SPAN_CENTI_MM 10000

static int32_t code_to_centi_mm(int32_t code) {
    const int32_t code_range = CODE_SPAN - CODE_ZERO;
    const int32_t pos_range = POS_SPAN_CENTI_MM - POS_ZERO_CENTI_MM;

    if (code_range <= 0) {
        return POS_ZERO_CENTI_MM; /* invalid calibration constants */
    }

    if (code <= CODE_ZERO) {
        return POS_ZERO_CENTI_MM;
    }

    if (code >= CODE_SPAN) {
        return POS_SPAN_CENTI_MM;
    }

    return POS_ZERO_CENTI_MM + ((code - CODE_ZERO) * pos_range) / code_range;
}

static void print_position(int32_t code) {
    int32_t pos = code_to_centi_mm(code);
    printf("code=%ld position=%ld.%02ld mm\n",
           (long)code,
           (long)(pos / 100),
           (long)(pos % 100));
}

int main(void) {
    int32_t tests[] = {700, 820, 2045, 3270, 3400};
    const unsigned count = sizeof(tests) / sizeof(tests[0]);

    for (unsigned i = 0; i < count; ++i) {
        print_position(tests[i]);
    }

    return 0;
}

Expected Behavior

Raw code Expected position Reason
700 0.00 mm clamped below calibrated zero
820 0.00 mm zero reference
2045 50.00 mm midpoint because it is halfway between 820 and 3270
3270 100.00 mm span reference
3400 100.00 mm clamped above calibrated span

Verification Steps

  1. With motion disabled, place the mechanism at the zero reference and record several raw readings.
  2. Place the mechanism at the span reference and record several raw readings.
  3. Confirm that CODE_SPAN is greater than CODE_ZERO; otherwise the sensor direction or constants are wrong.
  4. Build and run the program.
  5. Verify zero, midpoint, and span outputs.
  6. Move the mechanism slowly and confirm that position changes monotonically.
  7. Repeat readings at the same position to estimate noise and repeatability.
  8. Store calibration constants with date, units, sensor ID, and mechanical setup notes.

Common Failure Symptoms

Symptom Likely cause First check
zero reads nonzero wrong zero point, preload, offset drift log raw code at zero
span is wrong but zero is correct wrong span point or gain calculation recompute code range
output decreases with travel sensor direction reversed compare zero and span codes
value jumps randomly loose connector, noisy supply, ADC reference noise inspect raw codes before filtering
value saturates early sensor range or mechanical travel mismatch measure voltage at both endpoints
works on bench but not in machine mounting changed calibration recalibrate after installation

Debugging Guidance

  • Print raw ADC code before printing calibrated position.
  • Confirm ADC reference voltage, sensor supply voltage, and input range.
  • Move the mechanism slowly while watching raw code; it should be smooth and monotonic.
  • Check cable shield termination and strain relief before adding software filtering.
  • Average several samples only after wiring and range are correct.
  • Use fixed-width integer types and check multiplication range before increasing span units.
  • Reject calibration constants that produce zero or negative span.

Extension Challenge

Add a third verification point at 75.00 mm. The expected raw code is:

$$
x_{75} = 820 + 0.75(3270 - 820) = 2657.5
$$

Use either 2657 or 2658 as the nearest integer test code. If the converted value is outside +/-0.50 mm, report a calibration warning. Then add EEPROM or flash storage for calibration constants with a checksum or version field.

Explained Solution

Two-point calibration fits a straight line between a known zero point and a known span point. The zero code defines offset. The difference between span and zero codes defines gain. The implementation subtracts the zero code, multiplies by the engineering-unit span, divides by the code span, and clamps outside the calibrated travel. Clamping avoids unsafe extrapolated positions, but it should not hide a wiring or travel-range fault during commissioning.

Summary

Calibration turns raw sensor values into trustworthy engineering units. The workflow is measure known points, compute scale and offset, verify intermediate points, check repeatability, preserve constants with clear units, and debug raw measurements before trusting filtered values.

Further Reading

  • NIST Engineering Statistics Handbook, calibration concepts.
  • Texas Instruments application notes on sensor calibration and linearization.
  • IEC 60770 transmitter performance methods for industrial-process measurement.

Mind Map

mindmap root((Sensor Calibration)) Core task Two known points Raw code to mm Clamp safe range Formula y equals y0 plus x minus x0 times span ratio Code span equals 3270 minus 820 Position unit 0.01 mm x75 about 2658 Implementation Fixed point C Reject bad constants Log raw first Store units Verification Zero Midpoint Span Monotonic travel Repeatability Common mistakes Reversed sensor Wrong reference Filtering before debug Cal before mounting