Multiplex the Analog PIN on ESP8266/ESP32 Without Any Additional Components

by XuancongW in Circuits > Arduino

379 Views, 0 Favorites, 0 Comments

Multiplex the Analog PIN on ESP8266/ESP32 Without Any Additional Components

multiplex0.png
multiplex1.png

Unlike ESP32, ESP8266 has only one A0 analog input port, so is it possible to read analog input from multiple resistive sensor probes? The answer is YES. @breagan22 has provided a workable solution by adding diodes for current isolation. However, that method requires additional electronic components. In this tutorial, we claim that under the condition that all sensor probes are resistive in nature and are not too far away from the common range of 10K-300K, it is possible to use a more elegant solution without using any additional electronic components (Method A), not even the voltage-divider resistor that is connected in series to each sensor probe.

Supplies

1.jpg

Here are the components we used:

  • Any ESP8266 development board, here, we use a WEMOS D1-mini
  • A computer with Arduino IDE installed and a USB cable connected to the ESP8266
  • A breadboard with electrical wires and resistors package (optional for Method A)
  • Sensor probe 1, a thermistor
  • Sensor probe 2, a photo-resistor
  • Sensor probe 3, a variable resistor
  • Multi-meter (optional)

Initialize All GPIO Ports As INPUT

pinMode(GPIO0, INPUT);
pinMode(GPIO4, INPUT);
pinMode(GPIO5, INPUT);
pinMode(GPIO14, INPUT);

GPIO input port has very high impedance, the current is in the micro-amphere range. By setting all these ports to INPUT, this effectively isolates all sensor probes.

Set Common PULLUP to All Components

pinMode(GPIO14, INPUT_PULLUP);

According to ESP8266 specification, INPUT_PULLUP has internal resistance between 30K-100K. Therefore, this effectively connects the common terminal of all sensor probes to VCC via a resistor of 30K-100K. However, since the other terminal of all sensor probes are connected to INPUT, no current flows through sensor probes, none of the sensors is activated yet.


Reading a Particular Sensor - Method 1

pinMode(GPIO5, OUTPUT_OPEN_DRAIN);
delay(500);
int value = analogRead(A0);
pinMode(GPIO5, INPUT);


Firstly, we need to open drain on the 2nd terminal of the target sensor probe, this effectively pull that pin to ground, allowing current to flow through the target sensor. After waiting for some time for the voltage to stabilize, we can read voltage from the A0 pin. At the end, remember to disable the sensor by setting the pin mode back to INPUT.

Reading a Particular Sensor - Method 2

pinMode(GPIO5, OUTPUT);
digitalWrite(GPIO5, LOW);
delay(500);
int value = analogRead(A0);
pinMode(GPIO5, INPUT);


The other way to allow current to flow through the target sensor is to write digital LOW to the other pin. The difference is that the internal resistance between that 2nd pin and ground is lower in the case of OUTPUT_OPEN_DRAIN. In practice, you can choose between Method 1 and 2 depending on your sensor probe's resistance characteristics. If your sensor probes have very small resistance variation, you should use OUTPUT_OPEN_DRAIN to increase the current so that the voltage variation is more obvious.

Limitation and Conclusion

In Method A, since A0 is directly connected to the 1st pin of all sensor probes, the effective voltage-divider resistor that is connected in series to all sensors, is the same as the INPUT_PULLUP internal resistance (that is 30K-100K). Since different chips, different ports have different INPUT_PULLUP internal resistance, you need to calibrate every sensor output value on each device. In conclusion, using this way of multiplexing, you need (N+2) ports (including A0) for N sensors in total.

In the application scenario where different sensor probes requires very different voltage-divider resistor (or far away from the 10K-300K resistance range), then you have to adopt Method B, where you need (N*2+1) ports (including A0) for N sensors in total. The principle is the same except that you need to respectively digitalWrite(HIGH) and pinMode(OUTPUT_OPEN_DRAIN) for the sensor you select and set all other ports as INPUT, each time you access one specific sensor. Method B also requires less calibration because all sensor probes and voltage-divider resistors have fixed and known resistance.