NAV Navbar
Logo

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

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);
  1. 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 and referenceHigh
  2. Using the calibrated probe and a calibration solution at referenceLow, call measureEC and see what the actual reading is. Do the same for referenceHigh. These readings are referred to as readingLow and readingHigh. As an example, the readingLow might be 27 and readingHigh might be 40.
  3. 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 to useDualPoint 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:

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