Introduction
Measure Electrical Conductivity in Siemens, Total Dissolved Solids in PPM, Salinity in PSU and PPT.
Monitor hydroponic nutrient levels, salinity levels in aquariums or the ocean, saltwater pools, soil salinity, water quality etc.
It uses the standard Arduino Wire library to interface with the device. It’s operating principle is based on sending a very short-duration DC pulse from one probe pin and measuring the conductivity on the other pin. The conductivity is then converted to a temperature compensated Siemen. Salinity is also derived from the measure and is in PSU, PPT, and PPM.
Characteristics
- EC range: ~1.0 - ~200mS
- Salinity range: 2 - 42
- Temperature range: -2 - 35C
- Interface: I2C
- Current use: ~10mA peak, low idle current ~1mA
- Voltage range: 2.7 - 5.5V
Connections
I2C Connections
Making the connections to the device is as follows:
EC Salinity Probe | Master device |
---|---|
GND | GND |
SCL | SCL |
SDA | SDA |
VCC | 2.7 - 5V |
Temperature Probe Connections
The temperature probe should be connected as follows:
EC Salinity Probe | Temperature Probe |
---|---|
+ | VCC |
D | Data |
- | GND |
EC Probe Connections
The EC probe has two pins and can be connected either way.
Probe Selection
Any 2-electrode probe can be attached to the device.
Calibration
#include <ECSalinity.h>
EC_Salinity ec;
float calibrationSolution_mS = 2.77;
ec.setK(10.0);
ec.calibrateProbe(calibrationSolution_mS, ec.tempCoefEC);
When the device is powered for the first time, it will be uncalibrated. There are two calibration options: single and dual or double point. Single point determines a percent difference between actual readings and expected readings, then uses it to adjust the readings. Double point uses two points, a high and low, to determine the adjustment to make. The choice of single or double depends on the expected use. A small range might be better measured by single point calibration whereas a large range may be more accurate with double point.
Before any measurements can be made, to include measurements to calibrate the probe, the cell constant (K) must be specified. This number is typically 0.1, 1.0, or 10.0. The exact value may be found on the probe itself (9.988 for example). After K has been set, you can expect to see values being returned. It will not be accurate and must be calibrated.
To begin the single point calibration process, place the thermometer and probe in a calibration solution then call the calibrateProbe
function.
For best results, the probe should be cleaned with distilled water and then placed in the solution for 5-10 minutes before the probe is used. It shouldn’t be placed on the bottom or side of the solution container. Note that any turbidity, air bubbles, large particles, etc will effect readings. An unstable temperature will decrease accuracy as well.
When calibrating the probe, it is important to consider the expected temperature range. EC measurements are very temperature dependent, effecting the results by approximately 2% per degree C. The probe should be calibrated at the median expected temperature.
Likewise, the probe should be calibrated in the median expected EC range. For example, if you are planning to measure the salinity of an aquarium, you might expect readings ±5 from 35PPT (equivalent to 53mS). So a 53mS solution for calibration would be appropriate, whereas a hydroponic calibration might be 2.77mS or lower.
Another consideration is the placement of the probe. When the probe sends out a pulse of electricity, it leaves the probe in 360 degrees. If it is near a metal surface, you will experience fringing effects. The probe should be calibrated in an environment as similar as possible to the location it will be deployed in.
Single Point
float solutionEC = 53.0;
ec.calibrationProbe(solutionEC, ec.tempCoefSalinity);
After K has been set, you can calibrate the probe using a single point. For this method of calibrating, submerge the probe and wait for the readings to stabilize. Then call calibrateProbe
. The calibration information will be stored in ec.referenceLow and is the percent difference from the measured value and the expected value.
Dual Point
You can use dual point calibration for more accurate results between two predesignated points. Two calibration solutions are required, the low and high values you expect to measure between.
float readingLow = 51.0;
float readingHigh = 60.2;
ec.setDualPointCalibration(50.0, 58.0, readingLow, readingHigh);
ec.useDualPoint(true);
- Determine the lowest and highest measurement you expect in mS. For example, to
measure salinity in an aquarium, the lowest level you would expect to measaure might
be 30 PPT and the highest might be 38 PPT. These points are referred to as
referenceLow
andreferenceHigh
- Using the calibrated probe and a calibration solution at
referenceLow
, callmeasureEC
and see what the actual reading is. Do the same for referenceHigh. These readings are referred to asreadingLow
andreadingHigh
. As an example, thereadingLow
might be 27 andreadingHigh
might be 40. - Call
setDualPointCalibration
to save the values to the device, then enable dual point calibration. By default, the device does not use dual point. A call touseDualPoint
must be made to enable it each time the device is powered.
float solutionECLow = 53.0;
float solutionECHigh = 58.0;
ec.calibrateProbeLow(solutionECLow, ec.tempCoefSalinity);
ec.calibrateProbeHigh(solutionECHigh, ec.tempCoefSalinity);
calibrateProbeLow
and calibrateProbeHigh
can be used
to programatically determine the values.
getCalibrateHigh
and getCalibrateLow
can be used
to get the currently set reference values.
ec.useDualPoint(false);
Each call to measureEC
will use the calibration to adjust
the reading. It can be disabled by ec.useDualPoint(false);
Use
float tempC = ec.measureTemp();
Once the probe has been calibrated, a reading can be taken. The device will use
the most recent temperature measurement obtained from measureTemp
.
The probe should be placed in the solution to be measured and measureEC
called to start a measurement. For best results, the probe should be cleaned with distilled
water and left in the solution for 5 - 10 minutes. Be sure no air bubbles or debris
are on the probe points.
After the measurement is taken, the following class variables are updated:
uS
mS
S
PPM_500
PPM_640
PPM_700
salinityPSU
salinityPPT
salinityPPM
tempC
tempF
Temperature Coefficients
float pureWaterCompensation = 0.0455;
ec.measureEC(pureWaterCompensation);
ec.measureEC();
ec.measureSalinity();
If the solution to be measured is saltwater, use measureSalinity()
,
if it is freshwater, use measureEC()
. A custom temperature
coefficient can be used by passing it to measureEC()
.
Temperature Compensation
byte tempConstant = 25;
ec.setTempConstant(tempConstant);
ec.setTempConstant(0xFF);
To set the temperature used for compensation, call
setTempConstant()
and pass the temperature to use. To use the
actual temperature, pass 0xFF.
Accuracy
ec.setAccuracy(21);
The accuracy of the device can be adjusted by modifying setAccuracy
.
By default, 9 measurements are taken. A running median sort is applied and
the middle third of the nine measurements are averaged together to provide the
final result. Any number of measurements can be taken as long as it is evenly
divisible by 3. The least number of measures possible is 3.
Measurement Time
Each individual EC measurement takes 10ms. If the default accuracy is set to 9,
a call to measureEC
will return in about 90ms. A temperature measurement
takes 750ms.
Member Data
uS
float
EC in micro-Siemens
mS
float
EC in milli-Siemens
S
float
EC in Siemens
PPM_500
long
TDS in PPM using 500 as a multiplier (US)
PPM_640
long
TDS in PPM using 640 as a multiplier
PPM_700
long
TDS in PPM using 700 as a multiplier (US)
salinityPSU
float
Salinity in Practical Salinity Units
salinityPPT
float
Salinity in parts-per-thousand
salinityPPM
float
Salinity in parts-per-million
tempC
float
Temperature in Celsius
tempF
float
Temperature in Fahrenheit
tempCoefEC
const float = 0.019
Temperature compensation coefficient for EC/freshwater measurements
tempCoefSalinity
const float = 0.021
Temperature compensation coefficient for salinity measurements
Member Functions
calibrateProbe
#include <ECSalinity.h>
EC_Salinity ec;
ec.calibrateProbe(2.77, ec.tempCoefEC);
ec.calibrateProbe(53.0, ec.tempCoefSalinity);
ec.calibrateProbe(1.0, 0.0455);
void calibrateProbe(float solutionEC, float tempCoef)
Parameter | Description |
---|---|
solutionEC | mS of calibration solution |
tempCoef | temperature coefficient to use for measurement |
Calibrates the connected probe and saves the result in EEPROM.
calibrateProbeHigh
#include <ECSalinity.h>
EC_Salinity ec;
while (Serial.available() == 0)
{
Serial.print("mS: "); Serial.println(ec.measureEC(ec.tempCoefSalinity));
delay(5000);
}
Serial.read();
Serial.println("Calibrating high...");
ec.calibrateProbeHigh(58, ec.tempCoefSalinity);
void calibrateProbeHigh(float solutionEC, float tempCoef)
Parameter | Description |
---|---|
solutionEC | mS of calibration solution |
tempCoef | temperature coefficient to use for measurement |
Calibrates dual-point values for the high reading and saves them in the devices’s EEPROM.
calibrateProbeLow
ec.calibrateProbeLow(2, ec.tempCoefEC);
ec.calibrateProbeLow(53.0, ec.tempCoefSalinity);
ec.calibrateProbeLow(0.1, 0.0455);
void calibrateProbeLow(float solutionEC, float tempCoef)
Parameter | Description |
---|---|
solutionEC | mS of calibration solution |
tempCoef | temperature coefficient to use for measurement |
Calibrates dual-point values for the low reading and saves them in the devices’s EEPROM.
getAccuracy
byte accuracy = ec.getAccuracy();
byte getAccuracy()
Retrieves the accuracy configuration of the device.
Returns: byte
accuracy
getCalibrateHigh
#include <ECSalinity.h>
EC_Salinity ec;
Serial.println("Calibrating high...");
ec.calibrateProbeHigh(58, ec.tempCoefSalinity);
Serial.print("Reference high set at: ");
Serial.println(ec.getCalibrateHigh());
float getCalibrateHigh()
Retrieves the dual-point calibration high reference value.
Returns: float
highCalibration
getCalibrateLow
float lowCalibration = ec.getCalibrateLow();
float getCalibrateLow()
Retrieves the dual-point calibration low reference value.
Returns: float
lowCalibration
getCalibrateLowReading
float lowCalibration = ec.getCalibrateLowReading();
float getCalibrateLowReading()
Retrieves the dual-point calibration low reading value.
Returns: float
lowCalibration
getCalibrateHigh
#include <ECSalinity.h>
EC_Salinity ec;
Serial.println("Calibrating high...");
ec.calibrateProbeHigh(58, ec.tempCoefSalinity);
Serial.print("Reference high set at: ");
Serial.println(ec.getCalibrateHigh());
float getCalibrateHigh()
Retrieves the dual-point calibration high reference value.
Returns: float
highCalibration
getCalibrateHighReading
float getCalibrateHighReading()
Retrieves the dual-point calibration high reading value.
Returns: float
highCalibration
getCalibrateOffset
float offsetCalibration = ec.getCalibrateOffset();
float getCalibrateOffset()
Retrieves the single-point calibration offset value.
Returns: float
offsetCalibration
getK
float K = getK();
float getK()
Retrieves the cell constant from the device.
Returns: float
K
getTempConstant
byte tempConstant = ec.getTempConstant();
byte getTempConstant()
Retrieves the temperature constant used for temperature compensation. A value
of 0xFF
indicates the actual measured temperature is being used.
Returns: byte
tempConstant
getVersion
byte version = ec.getVersion();
if (version != 1) return;
byte getVersion()
Retrieves the version of the hardware/firmware.
Returns: byte
version
measureEC()
#include <ECSalinity.h>
EC_Salinity ec;
float EC = ec.measureEC(ec.tempCoefEC);
float EC = ec.measureEC(ec.tempCoefSalinity);
float EC = ec.measureEC(0.0455);
float measureEC(float tempCoef)
Parameter | Description |
---|---|
tempCoef | temperature coefficient to use for measurement |
Starts an EC measurement.
Updates the following:
- uS
- mS
- S
- PPM_500
- PPM_640
- PPM_700
- salinityPSU
- salinityPPT
- salinityPPM
- tempC
- tempF
Returns: float
EC in mS
measureSalinity()
float PSU = ec.measureSalinity();
float measureSalinity()
Starts an EC salinity measurement using tempCoefSalinity as a temperature coefficient.
Updates the following:
- uS
- mS
- S
- PPM_500
- PPM_640
- PPM_700
- salinityPSU
- salinityPPT
- salinityPPM
- tempC
- tempF
Returns: float
salinity in PSU
measureTemp()
float tempC = ec.measureTemp();
float setAccuracy(byte accuracy)
Starts a temperature measurement.
Updates the following:
- tempC
- tempF
Returns: float
temperature in Celsius
reset()
void reset()
Clears all calibration data from the device.
setAccuracy
ec.setAccuracy(21);
void setAccuracy(byte accuracy)
Parameter | Description |
---|---|
accuracy | accuracy setting |
Changes the number of samples taken per measurement. The device uses a running median average that averages the middle third of the total values.
setDualPointCalibration
ec.setDualPointCalibration(1.0, 4.0, 0.8, 5.0);
void setDualPointCalibration(float refLow, float refHigh, float readLow, float readHigh)
Parameter | Description |
---|---|
refLow | reference low calibration solution in mS |
refHigh | reference high calibration solution in mS |
readLow | reading low calibration solution in mS |
readHigh | reading low calibration solution in mS |
Sets all the values for dual point calibration and saves them in the devices’s EEPROM.
setK
ec.setK(1.5);
void setK(float K)
Parameter | Description |
---|---|
K | the new cell constant |
Updates the device with a new cell constant and saves it in EEPROM.
setTempConstant
ec.setTempConstant(25);
void setTempConstant(byte tempConstant)
Parameter | Description |
---|---|
tempConstant | the new cell constant |
Configures the device to use the provided temperature constant.
By default, the temperature constant is set to 0xFF
which means the actual temperature is to be used.
useDualPoint
ec.useDualPoint(true);
void useDualPoint(bool useDualPoint)
Parameter | Description |
---|---|
useDualPoint | true/false |
Configures the device to use dual point calibration. By default, the device powers on with this value set to false
.
useTemperatureCompensation
ec.useTemperatureCompensation(true);
void useTemperatureCompensation(bool useTempComp)
Parameter | Description |
---|---|
useTempComp | true/false |
Configures device to use temperature compensation. If this is set to false
, the uncompensated Siemen value will be returned by the device.
usingDualPoint
bool bDualPoint = ec.usingDualPoint();
bool usingDualPoint()
Determines if dual point calibration is being used.
Returns: bool
true/false
usingTemperatureCompensation
bool bTempComp = ec.usingTemperatureCompensation();
bool usingTemperatureCompensation()
Determines if temperature compensation is being used.
Returns: bool
true/false