Electronics, programming & other stuff

Analog to digital converter without ADC

There are some low cost systems in which the reading of some sensors, potentiometers or other analog devices is required, by using a cheap microcontroller without integrated analog to digital converter.

Adding an external ADC might require more microcontroller pins, more space in the PCB or more software complexity (for instance, I2C routines may be needed if that's the used bus).

If there aren't many requirements regarding resolution, accuracy, lineality, sample time, the solution is to use an RC circuit, and measure the time it takes to charge (similar to a double ramp ADC)

RC circuit

The resistor may be changed to a thermistor (PTC or NTC) if the temperature is the variable to be measured, or a LDR to measure luminosity. It's also possible to use a capacitive sensor, by using a fixed resistor.

It's needed to have a bidirectional pin in the microcontroller, which also should allow to set a high impedance (High-Z) state

The principle is the following::

  • Set the terminal to high for around 1ms, to charge the capacitor
  • Set the terminal in high z state and measure how long the capacitor holds the charge.
  • Repeat the cycle according to the desired sample rate.
Charge discharge RC cycle

A small way to program it would be the following:

uint16_t time=0;
PIN_LOAD = 1; delay1ms(); PIN_LOAD = 0; //Charge the capacitor
while(PIN_LOAD == 0) time++; //Wait for the discharge

The 16 bit output should then be scaled to get a correct value according to the resistor. To avoid wasting CPU time in the while loop, an internal capture module may be used to easily count the interval during which the pin was in a high state. This method works best with pins that feature Schmitt Trigger capability, since it helps to remove the dependance of the supply voltage in the measured times.