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
- mV Measurement range: -1024 mV to 1024 mV
- mV Accuracy: ± 1 mV
- Temperature range: -2 to 35 C
- Temperature Precision: 0.05 C
- Interface: I2C
- Current use: ~10mA peak, low idle current ~1mA
- Supply voltage range: 3.3 to 5.5V
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.
Arduino IDE: go to the library manager (Sketch / Include Library / Manage Libraries…) and search for ISE Probe.
PlatformIO: install the library using the library manager (PlatformIO / PlatformIO Home / Libraries), search for ISE Probe.
Particle.io: search for ISE_Probe_Interface in the Libraries section of the IDE.
MicroPython: clone the GitHub repo. In the python/MicroPython directory, you will find the files for various boards and their accompanying README files with instructions.
Raspberry Pi: clone the GitHub repo. In the python/RaspberryPi directory, you will find the files for various boards and their accompanying README files with instructions. Be sure to read the section below for instructions.
Rust: Download/install/documentation for the crate
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).
sudo nano /boot/config.txt
and scroll to the bottomAdd
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.ctrl + x
to exit,y
to save, andenter
to confirm the filename.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
- 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
andreferenceHigh
- Put the probe in a calibration solution at
referenceLow
and wait for readings to stabilize, callcalibrateProbeLow(0)
. Do the same for referenceHigh by callingcalibrateProbeHigh(140)
. - 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 questions@ufire.co.
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
solutionmV
the mV of the calibration solution
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
solutionmV
the mV of the calibration solution
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
refLow
the reference low pointrefHigh
the reference high pointreadLow
the measured low pointreadHigh
the measured high point
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
b
true for false
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
b
true or false
void useDualPoint(bool b)
Configures device to use dual-point calibration.
ISE_Probe::useDualPoint(true);
ISE.useDualPoint(True);
```shell
dp 1
Parameters
b
true or false
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
solutionpH
the mV of the calibration solution
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
solutionpH
the mV of the calibration solution
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