NAV Navbar
cpp python shell


Measure pH with an easy to use probe interface



I2C Connections

Connection to the device is as follows:

pH Probe Interface Master device
3.3/5v 3.3 - 5V

Temperature Probe Connections

The temperature probe comes with a 3-wire header. The VCC pin is labeled with a triangle.

pH Probe Interface Temperature Probe
(pin 2)
(pin 3)

Getting Started

To start developing for the device, you need to install the library. Two are provided, one for the Arduino framework, and the other for python3 on the Raspberry Pi.

Raspberry Pi

Before you can run anything, you will need to enable software I2C, as the Pi’s hardware implementation has a clock-stretching bug that will prevent it from working with the pH probe.

  1. sudo nano /boot/config.txt and scroll to the bottom
  2. Add


replacing <pin> with whatever pin you’d like to use. Refer here for the pin functions, you will need to use the orange GPIO xx labels in the picture to locate the pins. As an example, to use GPIO 17 as SDA and GPIO 27 as SCL, your line will look like this


Alternatively, you can choose to use the existing I2C pins, but using a software implementation of I2C, by pasting dtoverlay=i2c-gpio. If you go this route, you will need to edit line #4 from

ph = phprobe(3), to ph = phprobe(1)

  1. ctrl + x to exit, y to save, and enter to confirm the filename.
  2. Reboot

The shell Example

An interactive shell interface is provided with both frameworks and is a quick and easy way to get started using the device. You will find the equivalent commands in the code area to the right when applicable. Upload it to your master device and start a serial terminal. You will be presented with a > prompt where you can enter commands and receive a response, similar to a shell command line or REPL. It is often quicker to experiment with things this way rather than rewriting, compiling, and uploading new versions every time.

Changing the I2C Address

If needed, the I2C address can be changed by calling setI2CAddress(). The device will permanently change it’s address and continue to use it after a power reset. If you forget the new address, you will need to use an I2C bus scanner to locate it again.


Single Point

#include <phProbe.h>
pH_Probe pH;

from phprobe import phprobe

pH = phprobe(3)

  cal 7.0

Single point calibration determines a percentage-difference between the measured pH and the pH passed to the calibrateSingle() function. After calling it, the results are saved in the device’s EEPROM and used automatically.

Dual Point

Alternatively, you can use dual point calibration between two predesignated points. Two calibration solutions are required, the low and high values you expect to measure between.

pH.calibrateProbeLow(4.0);  // after measurement, clean probe and place in high solution
pH.calibrateProbeLow(4.0) # after measurement, clean probe and place in high solution
  low 4.0
  high 7.0
  1. Determine the lowest and highest measurement you expect. For example, the lowest level you might measure would be pH 4.0 and the highest might be pH of 7.0. These points will be referred to as referenceLow and referenceHigh
  2. Put the pH probe in a calibration solution at referenceLow and wait for readings to stabilize, call calibrateProbeLow(). Do the same for referenceHigh by calling ‘calibrateProbeHigh’.
  3. By default, the device does not use dual points. A call to useDualPoint() must be made to enable. Once set, it will continue to use it automatically.

You can also set all four values directly using setDualPointCalibration().

  dp 1

Each call to measurepH() will use the calibration to adjust the reading. It can be disabled by pH.useDualPoint(false);


Temperature Compensation

  tc 1
  tc 0

Temperature compensation can be used to adjust for the temperature effect on the probe. With the temperature probe connected, the device will take a temperature measurement and use it to correct the subsequent pH measurement. After calling useTempCompensation(), the passed value is saved and automatically used. A new temperature measurement is taken before a pH measurement is taken.

Measurement Time

A pH measurement takes 1.1 seconds. A temperature measurement takes 750ms.

Probe Maintenance

pH probes require regular care. There is a fluid junction that makes an electrical connection with the solution to be measured. If a probe is left continuously submerged, the junction could potentially leak the buffer fluid from inside the probe. This is less likely as the buffer solution in uFire probes are gel filled, though trade-off is they are not refillable. The concentration of sodium chloride could change over time, slowly decreasing accuracy. This can be compensated for by recalibrating the probe, but eventually, the probe will no longer be serviceable.

The junction can become clogged by debris or buildup. To clear a clogged junction, soak the probe in a 1:1 bleach solution. You can also use vinegar to help remove deposits on the probe.

More Help

If you have any questions, find a bug, or have any suggestions on improvements, go to this project’s GitHub page and submit an Issue or Pull Request. Or you can send an email to

Class Members

public float pH


public float tempC

Temperature in C

public float tempF

Temperature in F

public long mV

Milli-volts from pH probe

Class Functions

public float measurepH()

Starts a pH measurement.


A value of -1 means the probe is disconnected or there was an error reading the probe.



public float measureTemp()

Starts a temperature measurement.


tempC and tempF are updated

A value of -127 means the device is not connected.


temperature in C

public void calibrateSingle(float solutionpH)

Calibrates the probe using a single point.

cal 7.0

The result will be saved in the device’s EEPROM and used automatically.

public void calibrateProbeLow(float solutionpH)

Calibrates the dual-point values for the low reading and saves them in the devices’s EEPROM.

low 4.0


public void calibrateProbeHigh(float solutionpH)

Calibrates the dual-point values for the high reading and saves them in the devices’s EEPROM.

high 7.0


public void setDualPointCalibration(float refLow,float refHigh,float readLow,float readHigh)

Sets all the values for dual point calibration and saves them in the devices’s EEPROM.

pH_Probe::setDualPointCalibration(4.0, 7.0, 3.8, 7.2);
ph.setDualPointCalibration(4.0, 7.0, 3.8, 7.2)


public float getCalibrateOffset()

Retrieves the single-point offset from the device.

float z = pH_Probe::getCalibrateOffset();
z = ph.getCalibrateOffset()


the probe’s offset

public void useTemperatureCompensation(bool b)

Configures device to use temperature compensation or not.

tc 1


public bool usingTemperatureCompensation()

Determines if temperature compensation is being used.

bool usingTemp = pH_Probe::usingTemperatureCompensation();
usingTemp = ph.usingTemperatureCompensation()


true if using compensation, false otherwise

public void useDualPoint(bool b)

Configures device to use dual-point calibration.

dp 1


public bool usingDualPoint()

Determines if dual point calibration is being used.

bool usingTemp = pH_Probe::usingDualPoint();
usingTemp = ph.usingDualPoint()


true if using compensation, false otherwise

public float getCalibrateHigh()

Retrieves the dual-point calibration high value.

float calHigh = pH_Probe::getCalibrateHigh();
calHigh = ph.getCalibrateHigh()


the dual-point calibration high value

public float getCalibrateLow()

Retrieves the dual-point calibration low value.

float calLow = pH_Probe::getCalibrateLow();
calLow = ph.getCalibrateLow()


the dual-point calibration low value

public byte getVersion()

Retrieves the firmware version of the device.

byte version = pH_Probe::getVersion();
version = ph.getVersion()


version of firmware

public void reset()

Resets all the stored calibration information.