To use a pH sensor with a microcontroller, you must interface a high-impedance glass electrode through a signal conditioning board that shifts the raw ±414 mV output into a 0–5V (or 0–3.3V) analog range, or use a digital I2C/UART carrier module. You then map the ADC reading to a voltage, apply a two-point calibration slope, and compensate for temperature drift. The exact hardware and math depend entirely on whether you choose an analog conditioning board or a digital smart-sensor.
The Electrochemistry and Signal Output
A standard pH probe consists of a glass measuring electrode and a reference electrode (typically Ag/AgCl). When submerged, hydrogen ions interact with the hydrated gel layer on the outside of the glass bulb, creating a potential difference across the membrane relative to the internal reference solution. According to the Nernst equation, this potential shifts by approximately -59.16 mV per pH unit at 25°C. A neutral solution (pH 7.0) yields 0 mV across the membrane, while acidic solutions generate positive millivolts and alkaline solutions generate negative millivolts.
The raw probe outputs a high-impedance millivolt signal ranging from roughly +414 mV (pH 0) to -414 mV (pH 14). Because microcontrollers like the Arduino Uno (5V logic) or ESP32 (3.3V logic) cannot read negative voltages and lack the giga-ohm input impedance required to prevent loading the probe, you cannot wire a raw BNC probe directly to a GPIO pin. You must use an analog signal conditioning board—which uses an op-amp to offset and amplify the signal to a 0–5V range—or a digital carrier board that handles the electrometer amplification and ADC conversion internally, outputting parsed serial strings over UART or I2C.
Module Comparison and Wiring Pinouts
Choosing the right interface dictates your wiring and code complexity. Analog boards are cheaper but require you to handle ADC noise and calibration math in firmware. Digital EZO modules cost more but handle temperature compensation and calibration internally, returning a clean string like R:5.43.
| Hardware Type | Example Model | Supply Range | Output Signal | Accuracy | Est. Price (2026) |
|---|---|---|---|---|---|
| Raw BNC Probe | Generic E-201-C | N/A | ±414 mV (High Z) | ±0.2 pH | $15 - $25 |
| Analog Conditioner | DFRobot SEN0161 | 5V DC | 0–5V Analog | ±0.1 pH | $45 - $55 |
| Digital Smart Sensor | Atlas Scientific EZO-pH | 3.3V–5V DC | UART / I2C Digital | ±0.002 pH | $135 - $150 |
| Industrial Transmitter | 4-20mA Loop Probe | 12V–24V DC | 4–20 mA Current | ±0.05 pH | $200 - $300 |
Below is the standard wiring for the most common hobbyist module, the DFRobot Analog pH Meter (V1.1 board), connected to a 5V Arduino.
| DFRobot Module Pin | Arduino Uno (5V) | ESP32 DevKit (3.3V) | Function Notes |
|---|---|---|---|
| VCC | 5V | 5V (VIN pin) | Powers the onboard op-amp. Must be stable. |
| GND | GND | GND | Common ground reference. |
| PO (Analog Out) | A0 | GPIO34 (via divider) | 0-5V signal. Do NOT feed 5V directly to ESP32. |
| DO (Digital Out) | Ignore | Ignore | Fires HIGH when pH crosses a physical pot threshold. Useless for logging. |
Raw ADC Math and Two-Point Calibration
Analog pH boards map the -414 mV to +414 mV probe range into a 0V to 5V range. To convert the microcontroller's raw ADC reading into a physical pH unit, you must first convert the ADC integer to a voltage, then apply a linear regression formula derived from calibration buffers. For authoritative buffer standards, always refer to NIST Standard Reference Materials for pH.
Step 1: ADC to Voltage Conversion
Assuming a 10-bit ADC (Arduino Uno) and a 5V reference:
float voltage = analogRead(A0) * (5.0 / 1024.0);
Step 2: Two-Point Calibration Math
Never rely on hardcoded factory offsets; op-amp tolerances and probe aging shift the baseline. You need two calibration points, typically pH 7.00 (neutral) and pH 4.01 (acidic). Submerge the probe in the pH 7.00 buffer, wait 60 seconds for thermal equilibrium, and record the voltage (V1). Repeat for the pH 4.01 buffer (V2).
Calculate the slope (m) and intercept (b) using the standard linear equation y = mx + b:
- Slope (m):
m = (pH2 - pH1) / (V2 - V1) - Intercept (b):
b = pH1 - (m * V1) - Final Equation:
pH = (m * voltage) + b
Worked Numeric Example:
Your pH 7.00 buffer reads 2.52V. Your pH 4.01 buffer reads 4.25V.
m = (4.01 - 7.00) / (4.25 - 2.52) = -2.99 / 1.73 = -1.728 pH/V
b = 7.00 - (-1.728 * 2.52) = 7.00 + 4.354 = 11.354
Your firmware equation is now: float pH = (-1.728 * voltage) + 11.354;
Store m and b in the microcontroller's EEPROM or NVS (Non-Volatile Storage) so you don't have to recalibrate on every reboot. If you are using a digital module like the Atlas Scientific EZO-pH, this math is handled internally; you simply send the Cal,mid,7.00 and Cal,low,4.01 serial commands, and the module stores the slope on its own EEPROM.
High-Impedance Interference and Temperature Drift
The most common failure mode in DIY pH logging isn't bad code; it's electrical noise and thermal drift. The glass bulb of a pH probe has an electrical impedance ranging from 100 MΩ to 1000 MΩ. This extreme impedance turns the probe cable into a highly sensitive antenna for electromagnetic interference (EMI) and capacitive coupling.
Common Interference Sources and Fixes:
- 50/60Hz Mains Hum: If your probe cable runs parallel to AC wiring, the ADC will read a massive oscillating sine wave. Fix: Keep probe cables under 1 meter, use shielded BNC connectors, and implement a software moving-average filter (e.g., averaging 64 sequential ADC reads).
- Water Pump EMI: Brushed DC pumps or AC solenoid valves generate massive inductive spikes when switching. Fix: Physically separate pump power lines from sensor lines, and use flyback diodes across pump terminals.
- Ground Loops: If your fluid is in a grounded metal tank and your Arduino is grounded to earth via a USB PC connection, current will flow through the fluid and the probe reference junction, skewing the millivolt reading. Fix: Power the microcontroller via an isolated DC-DC converter or a battery, breaking the earth ground loop.
Temperature Compensation (ATC)
The Nernst slope of -59.16 mV/pH is only valid at exactly 25°C. As the fluid temperature drops to 0°C, the slope flattens to -54.2 mV/pH; at 100°C, it steepens to -74.0 mV/pH. If you are measuring hydroponic nutrient solutions or brewing kettles where temperatures fluctuate by more than ±5°C, your pH readings will drift significantly. For rigorous applications, integrate a waterproof DS18B20 temperature probe into the same fluid and apply Automatic Temperature Compensation (ATC) in your firmware to dynamically adjust the slope variable m based on the real-time Celsius reading. For deeper theory on how temperature interacts with aqueous solutions, consult the USGS Water Science School guidelines on pH and Water.






