NAV Navbar
Logo
cpp python shell

Introduction

The ISE (Ion Specific Electrode) Probe Interface can be used to read any probe that outputs a voltage in the range of -1024 mV to 1024 mV. pH and ORP are supported with specific libraries, but it is very easy to use another mV based probe by extending the library.

Characteristics

Connections

I2C Connections

Connection to the device is as follows:

ISE Probe Interface Master device
GND GND
SCL SCL
SDA SDA
3.3/5v 3.3 - 5V

Temperature Sensor Connections

The temperature probe comes with a 3-wire header; any 3-wire DS18B20 will work. The VCC pin is labeled with a triangle:

ISE Probe Interface Temperature Probe
▲ (VCC)
(Data) (pin 2)
(GND) (pin 3)

A standalone DS18B20 can be directly connected to the board, no resistor is required.

I2C Bus Pull-ups

Each device comes with 4.7k resistor pullups on the I2C bus. They pass through a 3-pad solder paste jumper. The outer pads are connected to the middle by thin traces. To disable the pullups, use a utility knife to cut both traces. To re-enable the pullups, connect all three pads together with solder.

Getting Started

To start developing with the device, you need to install a library.

Raspberry Pi

Before you can run anything, you will need to enable software I2C; the Pi’s hardware implementation has a clock-stretching bug that will prevent it from working with the probe (or any other device that uses clock-stretching).

  1. sudo nano /boot/config.txt and scroll to the bottom
  2. Add dtoverlay=i2c-gpio,i2c_gpio_sda=<pin>,i2c_gpio_scl=<pin> 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.

  3. ctrl + x to exit, y to save, and enter to confirm the filename.

  4. Reboot

The shell Example

An interactive shell interface is provided 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 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.

Calibration

There are two calibration options, single point and dual point. Single point calibration is a simple offset to the measured value. It is best suited for a sensor that displays linear measurements in the range of interest. Dual point calibration is used when the probe results are not linear over the entire range. Two points are selected, the high and low end of expected measurements.

Single Point

ISE_Probe ISE;

ISE.calibrateSingle(20);  // the low measurement being 20 mV
from iseprobe import iseprobe

ISE = iseprobe(3)

ISE.calibrateSingle(20)  # the low measurement being 20 mV
  cal 7.0

Single point calibration is done in the mV unit. To begin a single point calibration, submerge the probe and wait for the readings to stabilize. Then call calibrateSingle and pass the value the probe should be reading in mV. After calling it, the results are saved in the device’s EEPROM and used automatically.

As an example, if an ORP probe is reading 560 mV in a 600 mV solution, call calibrateSingle(600).

Dual Point

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

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

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

ISE.useDualPoint(false);
ISE.useDualPoint(False)
  dp 1

Use

Temperature Compensation

ISE.useTempCompensation(true);
ISE.useTempCompensation(True)
  tc 1
  tc 0

Temperature compensation can be used to adjust for the temperature effect on the probe. The device itself doesn’t contain any firmware that adjusts the readings, that is left to be implemented by the probe-specific libraries. However, this is a saved setting on the device. The pH library checks this value and if true, will take a temperature reading and adjust the measured pH accordingly.

Measurement Time

A mV measurement takes 500 ms. A temperature measurement takes 750ms.

Probe Maintenance

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. 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.

Isolation and Interference

Using any water quality measuring probe with another probe will likely cause interference. There are many factors that determine the amount to include the grounding of the solution, the type of probes, the solution itself, chemical reactions that may take place, etc. The only way to ensure interference doesn’t cause faulty measurements is to isolate the circuit.

Each probe would need to be isolated from each other using either a galvanic isolation circuit, or connected to separated battery powered devices, transmitting information via bluetooth or WiFi, for example.

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 [email protected].

Class Members

public float tempC

Temperature in C

public float tempF

Temperature in F

public long mV

Milli-volts from the probe

Class Functions

float measuremV()

Starts a mV measurement.

ISE_Probe::measuremV();
ISE.measuremV()
mv

Returns

the measured result in mV, -1 on error

float measureTemp()

Starts a temperature measurement.

ISE_Probe::measureTemp();
ISE.measureTemp()
temp

tempC and tempF are updated

A value of -127 means the temperature sensor is not connected.

Returns

temperature in C

void calibrateSingle(float solutionmV)

Calibrates the probe using a single point using a mV value.

ISE_Probe::calibrateSingle(200);
ISE.calibrateSingle(200)
cal 200

The result will be saved in the device’s EEPROM and used automatically. It takes 4.5 seconds to complete.

void calibrateProbeLow(float solutionmV)

Calibrates the dual-point values for the low reading, in mV, and saves them in the devices’s EEPROM. It takes 4.5 seconds to complete.

ISE_Probe::calibrateProbeLow(0);
ISE.calibrateProbeLow(0)
low 0

Parameters

void calibrateProbeHigh(float solutionmV)

Calibrates the dual-point values for the high reading, in mV, and saves them in the devices’s EEPROM. It takes 4.5 seconds to complete.

ISE_Probe::calibrateProbeHigh(200);
ISE.calibrateProbeHigh(200)
high 200

Parameters

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

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

ISE_Probe::setDualPointCalibration(0, 200, 3, 230);
ISE.setDualPointCalibration(0, 200, 3, 230)

Parameters

float getCalibrateOffset()

Returns the single-point offset from the device.

float offset = ISE_Probe::getCalibrateOffset();
offset = ISE.getCalibrateOffset()
cal

Returns

the probe’s offset

void useTemperatureCompensation(bool b)

Configures the device to use temperature compensation.

ISE_Probe::useTemperatureCompensation(true);
ISE.useTemperatureCompensation(True)
tc 1

Parameters

bool usingTemperatureCompensation()

Determines if temperature compensation is being used.

bool usingTemp = ISE_Probe::usingTemperatureCompensation();
usingTemp = ISE.usingTemperatureCompensation()
tc

Returns

true if using compensation, false otherwise

void useAveraging(bool b)

Configures device to use averaging.

ISE_Probe::useAveraging(true);
ISE.useAveraging(True);

Parameters

void useDualPoint(bool b)

Configures device to use dual-point calibration.

ISE_Probe::useDualPoint(true);
ISE.useDualPoint(True);
```shell
dp 1

Parameters

bool usingDualPoint()

Determines if dual point calibration is being used.

bool usingTemp = ISE_Probe::usingDualPoint();
usingTemp = ISE.usingDualPoint()
dp

Returns

true if using compensation, false otherwise

float getCalibrateHighReference()

Returns the dual-point calibration high reference value.

float calHigh = ISE_Probe::getCalibrateHighReference();
calHigh = ISE.getCalibrateHighReference()
high

Returns

the dual-point calibration high reference value

float getCalibrateLowReference()

Returns the dual-point calibration low reference value.

float calLow = ISE_Probe::getCalibrateLowReference();
calLow = ISE.getCalibrateLowReference()
low

Returns

the dual-point calibration low reference value

uint8_t getVersion()

Returns the firmware version of the device.

uint8_t version = ISE_Probe::getVersion();
version = ISE.getVersion()
version

Returns

version of firmware

void reset()

Resets all the stored calibration information.

pH Measurement

The ISE Probe Interface can measure pH with a pH probe attached. Including #include "ISE_pH.h" will give access to all of the previously described API functions, in addition to measurepH(). calibrateSingle(), calibrateProbeLow(), and calibrateProbeHigh() take a pH unit value rather than a mV value if using the pH library.

float measurepH()

Starts a pH measurement.

ISE_pH::measurepH();
pH.measurepH()

Returns

the measured result in pH, or -1 on error

void calibrateSingle(float solutionpH)

Calibrates the probe using a single point using a pH value. It takes 4.5 seconds to complete.

ISE_pH::calibrateSingle(7.0);
pH.calibrateSingle(7.0)
cal 7.0

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

void calibrateProbeLow(float solutionpH)

Calibrates the dual-point values for the low reading, in pH, and saves them in the devices’s EEPROM. It takes 4.5 seconds to complete.

ISE_pH::calibrateProbeLow(4.0);
pH.calibrateProbeLow(4.0)
low 4.0

Parameters

void calibrateProbeHigh(float solutionpH)

Calibrates the dual-point values for the high reading, in pH, and saves them in the devices’s EEPROM. It takes 4.5 seconds to complete.

ISE_pH::calibrateProbeHigh(10.0);
pH.calibrateProbeHigh(10.0)
high 10.0

Parameters

ORP Measurement

The ISE Probe Interface can measure ORP with an ORP probe attached. Including #include "ISE_ORP.h" will give access to all of the previously described API functions, in addition to measureORP(). Additionally, Eh is calculated; two methods are included for Eh, setProbePotential() and getProbePotential().

float measureORP()

Starts an ORP measurement. ISE_ORP::ORP and ISE_ORP::Eh are updated.

ISE_ORP::measureORP();
ORP.measureORP()

Returns

the measured result in mV, or -1 on error

void setProbePotential(uint32_t probePotential)

Saves the connected probe’s potential in EEPROM so that Eh can be calculated. After setting this value, the class member ISE_ORP::Eh is automatically updated with each call to measureORP().

ISE_ORP::setProbePotential(195);
ORP.setProbePotential(195)

uint32_t getProbePotential()

Returns the saved probe potential from EEPROM.

ISE_ORP::getProbePotential();
ORP.getProbePotential()

Returns

the probe potential