Loading header...

Exercise: Build a Sensor Acquisition Chain

This exercise turns the data-conversion lessons into a complete measurement path. You will specify a sensor front end, choose ADC settings, implement conversion code, and verify expected behavior with known inputs.

Learning Objectives

You will:

  • map a sensor voltage range to ADC codes;
  • choose a reference, input filter, and sampling rate;
  • write buildable conversion code;
  • verify calibration and failure behavior;
  • debug noise, clipping, and scaling errors.

Prerequisites

  • ADC resolution, quantization, and reference-voltage concepts.
  • Basic C programming for embedded systems.
  • Ability to measure DC voltage with a multimeter.
  • A development board with an ADC, or a simulator that can feed sample codes.

Task

Build a temperature acquisition chain for an analog sensor with output range 0.5 V to 2.5 V, representing 0 degree C to 100 degree C. Use a 12-bit ADC with 3.3 V reference. Sample at 100 samples/s and report temperature in centi-degrees Celsius.

Required design decisions:

  1. ADC reference: 3.3 V.
  2. Input protection: series resistor plus clamp strategy appropriate to your board.
  3. Input filter: choose a low-pass cutoff near 10 Hz.
  4. Firmware: convert raw ADC code to millivolts and temperature.
  5. Verification: test at 0.5 V, 1.5 V, and 2.5 V.

Implementation

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

#define ADC_BITS 12u
#define ADC_MAX  ((1u << ADC_BITS) - 1u)
#define VREF_MV  3300u
#define SENSOR_MIN_MV 500
#define SENSOR_MAX_MV 2500

static uint32_t adc_to_mv(uint16_t code) {
    return ((uint32_t)code * VREF_MV + (ADC_MAX / 2u)) / ADC_MAX;
}

static int32_t mv_to_centi_c(uint32_t mv) {
    if (mv <= SENSOR_MIN_MV) return 0;
    if (mv >= SENSOR_MAX_MV) return 10000;
    return (int32_t)((mv - SENSOR_MIN_MV) * 10000u /
                     (SENSOR_MAX_MV - SENSOR_MIN_MV));
}

int main(void) {
    uint16_t tests[] = {621, 1861, 3102};
    for (unsigned i = 0; i < 3; ++i) {
        uint32_t mv = adc_to_mv(tests[i]);
        int32_t tc = mv_to_centi_c(mv);
        printf("code=%u mv=%lu temp=%ld.%02ld C\n",
               tests[i], (unsigned long)mv,
               (long)(tc / 100), (long)(tc % 100));
    }
    return 0;
}

Approximate ADC code:

$$
code = \frac{V_{IN}}{V_{REF}}(2^N-1)
$$

Expected Behavior

Input ADC code Expected temperature
0.5 V 621 0 degree C
1.5 V 1861 50 degree C
2.5 V 3102 100 degree C

Small rounding differences are acceptable if they are documented.

Verification Steps

  1. Calculate expected codes for the three test voltages.
  2. Build and run the C code on a host computer.
  3. Feed the board ADC from a known voltage source or divider.
  4. Log at least 100 samples at each test point.
  5. Confirm average value, min/max noise, and no clipping.
  6. Disconnect or short the input safely and confirm fault handling.
  7. Repeat while nearby digital loads, relays, radios, or motors are active.

Common Failure Symptoms

Symptom Likely cause
temperature reads too high everywhere wrong reference voltage or scaling
correct at one point but wrong slope sensor min/max constants wrong
noisy output poor grounding, missing filter, long wires
stuck near 0 or 100 input clipping or ADC channel mismatch
changes when motor runs return-current or EMI coupling

Debugging Guidance

  • Print raw code before converting to engineering units.
  • Measure ADC pin voltage directly.
  • Verify VREF with a meter.
  • Check integer overflow and rounding.
  • Temporarily average more samples to separate random noise from scale error.
  • Disable nearby switching loads to isolate coupling problems.

Extension Challenge

Add two-point calibration. Store measured code at 0 degree C and 100 degree C, then compute temperature from the calibrated slope instead of fixed voltage limits.

Explained Solution

The ADC maps 0 V to code 0 and 3.3 V to code 4095. The sensor uses only 0.5 V to 2.5 V, so the code range is approximately 621 to 3102. Firmware first converts code to millivolts, then linearly maps 500 mV to 0 degree C and 2500 mV to 100 degree C. Clamping prevents impossible values from propagating when the input is slightly outside the calibrated range.

Summary

A sensor acquisition chain includes input scaling, reference choice, filtering, sampling rate, firmware conversion, calibration, and noisy-environment verification.

Further Reading

  • STMicroelectronics and Microchip ADC notes on source impedance and sampling time.
  • Texas Instruments Analog Engineer's Circuit Cookbook.
  • Analog Devices data conversion handbook chapters on grounding and references.

Mind Map

mindmap root((Sensor Chain Exercise)) Core task Sensor 05 to 25 V ADC 12 bit 33 V Temperature 0 to 100 C Sample 100 per second Formulas Code equals Vin over Vref times 2N minus 1 mV equals code times Vref over 4095 Temp from linear slope fc equals 1 over 2 pi R C Implementation Scale raw code Clamp limits Log samples Add calibration Verification Test 05 V Test 15 V Test 25 V Check noise Enable real loads Common mistakes Wrong Vref Channel mismatch Integer overflow No fault handling