Close

Three Dollar EC - PPM Meter [Arduino]

A project log for Hacking the way to growing food

Using Technology And A Hackers Mindset To Grow Food. Last Updated [16/01/2021]

michael-ratcliffeMichael Ratcliffe 09/04/2015 at 13:56154 Comments

This Blog will Cover How to build a cheap EC meter for your aquaponics/Hydroponics or water quality related projects. We are not going to get into what the ideal value of PPM or EC is, Just cover how to measure and quantify a fluid.

We will be using this for the Urine based aquaponics unit, we need to be able to control the strength of the growing fluid in the system but for the person on a budget a EC meter is just to much money. the Solution a $3 EC Meter for any Arduino.

You can use this to measure drinking water quality to with a small change to the code and changing R1 [see below].

Parts:

-MCU of your choice with ADC

-DS18B20 waterproof temperature sensor

-500 ohm [or 1kohm resistor]

-Type A Two Prong american plug to Figure 8

-Female Socket for Figure 8 connector

So why are we using a plug:

-Cheap

-Available worldwide

-Standard size [makes calibration easy]

Use the solid prong one like below and not the one with holes:

images.jpg

Wiring it up:

Note: You want the Solid Prong type plug

Do not Plug the pronged plug into the mains

Pinout.png

Operating Principal

PPM is calculated from the EC of a fluid, EC is the inverse of the electrical resistance of the fluid. We are estimating the EC or PPM of a fluid by measuring the resistance between two probes [The plug pins] when the plug is submerged in the liquid of interest.

Ec measurement needs to be done using AC or the liquid of interest is polarised and will give bad readings. This has got to be a great example of asking why instead of just accepting a statement as fact, it turns out we can take a very fast DC reading without suffering polarisation. meaning we can make a really cheap EC sensor.

Want to use it and dont care how it works? Skip to the main EC code and using the wiring diagram it will work.

Temperature Compensation

Temperature has an effect on the conductivity of fluids so it is essential that we compensate for this.

It is common to use a liner approximation for small temperature changes[1] to convert them to their equivelant EC at 25*C:

EC25 = EC /( 1 + a (T - 25) )

EC25- Equivelant EC at 25'C

EC - Measured EC

T- Temperature [Decgrees C] of Measurment

a = 0.019 °C [Commonly used for nutrient solutions]

Deciding on Value of R1

//##################################################################################

//----------- Do not Replace R1 with a resistor lower than 300 ohms ------------

//##################################################################################

We can change the Value of R1 in the voltage divider to change the range of EC we want to measure. Below is the Equivalent Voltage divider circuit.

Voltage Divider.png

Ra

Ra the resistance of the digital pins is not stated in the data sheet instead we need to pull it out from a graph.

Going off the graph on page [387] of the atmel 2560 Data Sheet “Figure 32-25. I/O Pin Output Voltage vs. Source Current (VCC = 5V)”

V=IR

Ra= V/I [From Figure] V=0.4 I=1.5e-4 R=25 ohms estimated

Rc


Rc will change with EC [PPM] of the measured fluid. we will calculate the maximum and minimum values we expect to see for the range of fluids we wish to measure taking into account temperature changes and the cell constant K. [We will estimate K to be 3 for the plug probe, estimate from previous tests]

EC = EC25*( 1 + a (T - 25))

R=(1000/(EC*K)) +Ra

Min temp=0 [we arnt going to care about EC if the pond is frozen]

Max Temp = 40 *C [I doubt a pond should be above this]

Minimum EC 25=0.3 EC= 0.3*(1+0.019*(0-25) Min EC= 0.16 S/sm

Maximum EC 25= 3 EC= 0.3*(1+0.019*(40-25) Max EC = 3.9 S/cm

Min Resistance = 1000/(MaxEC*K)+25 = 1000(3.9*2.88) =114 ohms

Max Resitance = 1000/(MinEC*K)+25 = 1000/(0.16*2.88) = 2195 ohms

R1

Now we have enough information to calculate a good value for R1 to get the best resolution over our intended measuring range. We could sum it all up mathematically and differentiate to find the peak, but that hurts my head so I just did a quick excel spreadsheet for the Voltage divider for the EC I expect to see:

Exel.png


As we can see we get the largest difference using a value for R1 of 500 ohm, I only had 1Kohm to hand so I will have to live with a little less range.

So we chose a 500 ohm resistor

EC – Range /Voltage Range * (5/ADC steps)

(3.9-0.16)/3.14 * 5/1024 = 5.8e-3 resolution so that is a resolution of 0.0058

To put this is PPM [Tranchen [Australia] PPMconversion: 0.7] this is a resolution of 4ppm.

Much more than we need for aquaponics or hydroponics.

If you want to measure the quality of drinking water you will need to calculate the expected Ec values and increase R1 accordingly.


Calibration Code

If you want the best readings from your system it is advisable to calibrate your sensor with some known fluid. But If you dont need to if you use the plug probe shown above, it will still work well.

>Add your EC in S/cm into the definitions

>Plug your K value from the terminal window into the main EC code

you will need to use the modified one wire and Dallas library [download from www.michaelratcliffe.com] or add a pull up for the temperature probe data line [google it]

/*
  ElCheapo Arduino EC-PPM measurments Calibration
 
  This Script is used for calibration of the sensor and fine tuning of the Cell Constant K
  Submerge the sensor and temperature probe in the calibration solution and leave for a while so the temperature probe can settle
  Change the value of the calibration solution to suit the solutiton strength
  Stir the probe to make sure the solution is well mixed and upload the code to the arduino
  Open the terminal for an update of the estimated Cell Constant K [should be around 3] and use this new value in the main EC code.
 
 
  28/8/2015  Michael Ratcliffe  Mike@MichaelRatcliffe.com
 
 
          This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
 
    Parts:
    -Arduino - Uno/Mega
    -Standard American two prong plug
    -1 kohm resistor
    -DS18B20 Waterproof Temperature Sensor
 
 
    See www.MichaelRatcliffe.com/Projects for a Pinout and user guide or consult the Zip you got this code from
 
*/
 
 
//************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install Use them or add a pull up resistor to the temp probe
 
 
#include <OneWire.h>
#include <DallasTemperature.h>
 
 
 
 
 
 
//************************* User Defined Variables ********************************************************//
 
 
float CalibrationEC=1.38; //EC value of Calibration solution is s/cm
 
 
 
 
//##################################################################################
//-----------  Do not Replace R1 with a resistor lower than 300 ohms    ------------
//##################################################################################
 
 
int R1= 1000;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=A1;
int ECPower =A4;
 
 
//*************Compensating for temperature ************************************//
//The value below will change depending on what chemical solution we are measuring
//0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
float TemperatureCoef = 0.019; //this changes depending on what chemical we are measuring
 
 
 
 
//************ Temp Probe Related *********************************************//
#define ONE_WIRE_BUS 10          // Data wire For Temp Probe is plugged into pin 10 on the Arduino
const int TempProbePossitive =8;  //Temp Probe power connected to pin 9
const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8
 
 
 
 
//***************************** END Of Recomended User Inputs *****************************************************************//
 
 
OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
 
 
float TemperatureFinish=0;
float TemperatureStart=0;
float EC=0;
int ppm =0;
 
 
float raw= 0;
float Vin= 5;
float Vdrop= 0;
float Rc= 0;
float K=0;
 
 
 
 
int i=0;
float buffer=0;
 
 
//*********************************Setup - runs Once and sets pins etc ******************************************************//
void setup()
{
  Serial.begin(9600);
  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly
 
  delay(100);// gives sensor time to settle
  sensors.begin();
  delay(100);
  //** Adding Digital Pin Resistance to [25 ohm] to the static Resistor *********//
  // Consule Read-Me for Why, or just accept it as true
  R1=(R1+Ra);
 
  Serial.println("ElCheapo Arduino EC-PPM measurments Calibration");
  Serial.println("By: Michael Ratcliffe  Mike@MichaelRatcliffe.com");
  Serial.println("Free software: you can redistribute it and/or modify it under GNU ");
  Serial.println("");
  Serial.println("Make sure Probe and Temp Sensor are in Solution and solution is well mixed");
  Serial.println("");
  Serial.println("Starting Calibration: Estimated Time 60 Seconds:");
 
 
 
};
//******************************************* End of Setup **********************************************************************//
 
 
 
 
//************************************* Main Loop - Runs Forever ***************************************************************//
//Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
void loop()
{
 
 
  i=1;
  buffer=0;
sensors.requestTemperatures();// Send the command to get temperatures
TemperatureStart=sensors.getTempCByIndex(0); //Stores Value in Variable
 
 
//************Estimates Resistance of Liquid ****************//
while(i<=10){
 
 
 
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low
digitalWrite(ECPower,LOW);
buffer=buffer+raw;
i++;
delay(5000);
};
raw=(buffer/10);
 
 
 
 
sensors.requestTemperatures();// Send the command to get temperatures
TemperatureFinish=sensors.getTempCByIndex(0); //Stores Value in Variable
 
 
//*************Compensating For Temperaure********************//
EC =CalibrationEC*(1+(TemperatureCoef*(TemperatureFinish-25.0))) ;
 
//***************** Calculates R relating to Calibration fluid **************************//
Vdrop= (((Vin)*(raw))/1024.0);
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra;
K= 1000/(Rc*EC);
 
 
 
 
Serial.print("Calibration Fluid EC: ");
Serial.print(CalibrationEC);
Serial.print(" S  ");  //add units here
Serial.print("Cell Constant K");
Serial.print(K);
 
 
if (TemperatureStart==TemperatureFinish){
  Serial.println("  Results are Trustworthy");
  Serial.println("  Safe To Use Above Cell Constant in Main EC code");
 
}
else{
  Serial.println("  Error -Wait For Temperature To settle");
 
}
 
 
}
//************************************** End Of Main Loop **********************************************************************//

EC PPM Measurement Code

>If you are using PPM and not EC make sure you note what conversion factor you are using [it isnt universal]

>Dont call the read function more than once every 5 seconds or you will get bad readings and a damaged probe

I tested this code in a solution for 48 hours reading at 5 second intervals without any polarisation or probe damage, the longer you leave between readings the longer your probe will last. 5 seconds is the minimum wait between readings not the maximum.

you will need to use the modified one wire and Dallas library [download from www.michaelratcliffe.com] or add a pull up for the temperature probe data line [google it]

/*
  ElCheapo Arduino EC-PPM measurments
 
  This scrip uses a common USA two prong plug and a 47Kohm Resistor to measure the EC/PPM of a Aquaponics/Hydroponics Sytem.
  You could modift this code to Measure other liquids if you change the resitor and values at the top of the code.
 
  This Program will give you a temperature based feed controller. See Read me in download file for more info.
 
  28/8/2015  Michael Ratcliffe  Mike@MichaelRatcliffe.com
 
 
          This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
 
    Parts:
    -Arduino - Uno/Mega
    -Standard American two prong plug
    -1 kohm resistor
    -DS18B20 Waterproof Temperature Sensor
 
    Limitations:
    -
    -
 
    See www.MichaelRatcliffe.com/Projects for a Pinout and user guide or consult the Zip you got this code from
 
*/
 
 
//************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe
 
 
#include <OneWire.h>
#include <DallasTemperature.h>
 
 
 
 
 
 
//************************* User Defined Variables ********************************************************//
 
 
//##################################################################################
//-----------  Do not Replace R1 with a resistor lower than 300 ohms    ------------
//##################################################################################
 
 
int R1= 1000;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=A1;
int ECPower =A4;
 
 
//*********** Converting to ppm [Learn to use EC it is much better**************//
// Hana      [USA]        PPMconverion:  0.5
// Eutech    [EU]          PPMconversion:  0.64
//Tranchen  [Australia]  PPMconversion:  0.7
// Why didnt anyone standardise this?
 
 
float PPMconversion=0.7;
 
 
//*************Compensating for temperature ************************************//
//The value below will change depending on what chemical solution we are measuring
//0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
float TemperatureCoef = 0.019; //this changes depending on what chemical we are measuring
 
 
 
 
//********************** Cell Constant For Ec Measurements *********************//
//Mine was around 2.9 with plugs being a standard size they should all be around the same
//But If you get bad readings you can use the calibration script and fluid to get a better estimate for K
float K=2.88;
 
 
 
 
//************ Temp Probe Related *********************************************//
#define ONE_WIRE_BUS 10          // Data wire For Temp Probe is plugged into pin 10 on the Arduino
const int TempProbePossitive =8;  //Temp Probe power connected to pin 9
const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8
 
 
 
 
//***************************** END Of Recomended User Inputs *****************************************************************//
 
 
OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
 
 
float Temperature=10;
float EC=0;
float EC25 =0;
int ppm =0;
 
 
float raw= 0;
float Vin= 5;
float Vdrop= 0;
float Rc= 0;
float buffer=0;
 
 
 
 
//*********************************Setup - runs Once and sets pins etc ******************************************************//
void setup()
{
  Serial.begin(9600);
  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly
 
  delay(100);// gives sensor time to settle
  sensors.begin();
  delay(100);
  //** Adding Digital Pin Resistance to [25 ohm] to the static Resistor *********//
  // Consule Read-Me for Why, or just accept it as true
  R1=(R1+Ra);// Taking into acount Powering Pin Resitance
 
  Serial.println("ElCheapo Arduino EC-PPM measurments");
  Serial.println("By: Michael Ratcliffe  Mike@MichaelRatcliffe.com");
  Serial.println("Free software: you can redistribute it and/or modify it under GNU ");
  Serial.println("");
  Serial.println("Make sure Probe and Temp Sensor are in Solution and solution is well mixed");
  Serial.println("");
  Serial.println("Measurments at 5's Second intervals [Dont read Ec morre than once every 5 seconds]:");
 
 
};
//******************************************* End of Setup **********************************************************************//
 
 
 
 
//************************************* Main Loop - Runs Forever ***************************************************************//
//Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
void loop()
{
 
 
 
 
GetEC();          //Calls Code to Go into GetEC() Loop [Below Main Loop] dont call this more that 1/5 hhz [once every five seconds] or you will polarise the water
PrintReadings();  // Cals Print routine [below main loop]
 
 
delay(5000);
 
 
}
//************************************** End Of Main Loop **********************************************************************//
 
 
 
 
//************ This Loop Is called From Main Loop************************//
void GetEC(){
 
 
//*********Reading Temperature Of Solution *******************//
sensors.requestTemperatures();// Send the command to get temperatures
Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
 
 
 
 
//************Estimates Resistance of Liquid ****************//
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
digitalWrite(ECPower,LOW);
 
 
 
 
//***************** Converts to EC **************************//
Vdrop= (Vin*raw)/1024.0;
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra; //acounting for Digital Pin Resitance
EC = 1000/(Rc*K);
 
 
//*************Compensating For Temperaure********************//
EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
ppm=(EC25)*(PPMconversion*1000);
 
 
;}
//************************** End OF EC Function ***************************//
 
 
 
 
//***This Loop Is called From Main Loop- Prints to serial usefull info ***//
void PrintReadings(){
Serial.print("Rc: ");
Serial.print(Rc);
Serial.print(" EC: ");
Serial.print(EC25);
Serial.print(" Simens  ");
Serial.print(ppm);
Serial.print(" ppm  ");
Serial.print(Temperature);
Serial.println(" *C ");
 
 
/*
//********** Usued for Debugging ************
Serial.print("Vdrop: ");
Serial.println(Vdrop);
Serial.print("Rc: ");
Serial.println(Rc);
Serial.print(EC);
Serial.println("Siemens");
//********** end of Debugging Prints *********
*/
};

Got any questions let me know.

The next tutorial will be on coding a self learning nutrient doser.

References:

[1]

John J. Barron & Colin Ashton "The Effect of Temperature on Conductivity Measurement" Technical Services Department, Reagecon Diagnostics Ltd

http://www.reagecon.com/pdf/technicalpapers/Effect_of_Temperature_TSP-07_Issue3.pdf

Discussions

Nuno Silva wrote 05/09/2017 at 12:58 point

Hi Michael,

I am trying to use your hardware and software to test portable water.

In my case I am calibrating the system for 0,01288 S/cm and I would like to ask you what do you think the R1 should be for this project.

If I follow your methodology Vdrop and Vout Range I should use a 30K ohms resistor.

This is the way?

Thanks

Nuno

  Are you sure? yes | no

Michael Ratcliffe wrote 08/07/2017 at 21:41 point

I havent tested at such a low EC, you might need to use a larger probe surface area to get it to work. 

But hey give it a shot and see if a 30k works?

  Are you sure? yes | no

daniele bordignon wrote 03/17/2017 at 09:12 point

Hi Michael. Great post, i'm going to build one of these. I was guessing.. The sensor can stay into water 24/24 7/7?
Is it durable (after 3 or 6 months, one year..)?

  Are you sure? yes | no

ctsai2 wrote 03/16/2017 at 13:35 point

Hi Michael,

Can I use this code on DUE instead?

  Are you sure? yes | no

Michael Ratcliffe wrote 08/07/2017 at 21:42 point

Sorry for the late reply, 

I havent tested on a DUO, it may have different v drop for digital pins [can work it out from data sheet]. this would be possible, but if it has extra circutry on the analog pins to reduce noise etc it wont work.

  Are you sure? yes | no

ctsai2 wrote 02/07/2017 at 17:35 point

Dear Michael,

Thanks for sharing this thread. 
I need to make a salinity/EC meter for 35ppt/50000EC. Can I use your setup? And what is the reason R1 should be greater than 300ohm?

  Are you sure? yes | no

Michael Ratcliffe wrote 02/08/2017 at 10:09 point

An EC of 50? That is going to be challenging, I cannot confirm 100%. 

But the bet way may be to reduce the probe area [cut them shorter?] to keep the current reqirments down. 

R1: this limits the current drawn by the probe, the arduino digital pin can only supply 20ma. 

  Are you sure? yes | no

ctsai2 wrote 02/15/2017 at 18:57 point

Yes, EC of 50 mS/cm. Right now I have it set up the same as yours. Have not shorten the probes yet. calculated using 1000ohms resistor. Is there anything else I should be concern and change? Because I don't want to burnt any pin. And yes, the conductivity is very high, it's seawater that I am measuring.

Thank you.

  Are you sure? yes | no

ctsai2 wrote 03/15/2017 at 18:41 point

Michael, 

I cut the probe short, change the Calibration value, but my best R1 for resistor is below 300ohms. Since the seawater resistance is so low compare to fresh/drinking water, can I use R1<300 ohm?
Or is this reversed, that I can only use R1 > than like 500 ohms? 

Instead of using analog i/o pins, the ECpower is connect directly to the 5V on the board, since we will have constant flowing water so not worrying about polarized the fluid. Does that also up my current drawn to 500mA?

Trying hard to make this work. Following your direction I already build one to measure 400-1000ppm and it works. Now moving onto measuring 32,000ppm to 40,000ppm

Thanks for any of your help

  Are you sure? yes | no

geert2 wrote 02/05/2017 at 13:20 point

Dear Michael, 

More respect every day. One remark and a cry for help. 

The Electric conductivity is an indicator for ammonia. Meaning that if you have a dead fish in the system, or algae that start dying, , you will notice the EC going thourgh the roof. This means the EC probe is one of the most telling indicators if something is going very wrong. 

I started to work on the system with a NODECMU Kit, and got quite far. 

However the readings are defenitely not right (see below). 

This could be because of the way the analog port reacts in a NODEMCU, or for any other reeason I don't understand, such as using digital pins for delivering the current. 

I am definitely out of my depth. Could you please help me? 

For water: 

Rc: 32808.05 EC: 0.01 Simens  6 ppm  25.50 *C 
raw993.00
Vdrop: 3.20
Rc: 32808.05
0.01Siemens

Salt water: 
Rc: 2752.90 EC: 0.12 Simens  79 ppm  25.50 *C 
raw748.00
Vdrop: 2.41
Rc: 2752.90
0.13Siemens

My code: 

//************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe
 

#include <Onewire.h>
#include  <Dallastemperature.h>

 
 
 
 
 
 
//************************* User Defined Variables ********************************************************//
 
 
//##################################################################################
//-----------  Do not Replace R1 with a resistor lower than 300 ohms    ------------
//##################################################################################
 
 
int R1= 1000;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=D7;
int ECPower =D8; // originally A4 is used by air pressure measurement 
 
 
//*********** Converting to ppm [Learn to use EC it is much better**************//
// Hana      [USA]        PPMconverion:  0.5
// Eutech    [EU]          PPMconversion:  0.64
//Tranchen  [Australia]  PPMconversion:  0.7
// Why didnt anyone standardise this?
 
 
float PPMconversion=0.64;
 
 
//*************Compensating for temperature ************************************//
//The value below will change depending on what chemical solution we are measuring
//0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
float TemperatureCoef = 0.019; //this changes depending on what chemical we are measuring
 
 
 
 
//********************** Cell Constant For Ec Measurements *********************//
//Mine was around 2.9 with plugs being a standard size they should all be around the same
//But If you get bad readings you can use the calibration script and fluid to get a better estimate for K
float K=2.88;
 
 
 
 
//************ Temp Probe Related *********************************************//
#define ONE_WIRE_BUS D2          // Data wire For Temp Probe is plugged into pin 10 on the Arduino // with me on 2 
//const int TempProbePossitive =8;  //Temp Probe power connected to pin 9  // I don' have that? 
//const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8  //should I do that? 
// 
 
 
 
//***************************** END Of Recomended User Inputs *****************************************************************//
 
OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
// 
 
float Temperature=10;
float EC=0;
float EC25 =0;
int ppm =0;
 
 
float raw= 0;
float Vin= 3.3;  // is only 3.3 v with esp was 5
float Vdrop= 0;
float Rc= 0;
float buffer=0;
 
 
 
 
//*********************************Setup - runs Once and sets pins etc ******************************************************//
void setup()
{
  Serial.begin(9600);
//  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
//  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
//  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
//  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly
 
  delay(100);// gives sensor time to settle
//  sensors.begin();
  delay(100);
  //** Adding Digital Pin Resistance to [25 ohm] to the static Resistor *********//
  // Consule Read-Me for Why, or just accept it as true
  R1=(R1+Ra);// Taking into acount Powering Pin Resitance
 
  Serial.println("ElCheapo Arduino EC-PPM measurments");
  Serial.println("By: Michael Ratcliffe  Mike@MichaelRatcliffe.com");
  Serial.println("Free software: you can redistribute it and/or modify it under GNU ");
  Serial.println("");
  Serial.println("Make sure Probe and Temp Sensor are in Solution and solution is well mixed");
  Serial.println("");
  Serial.println("Measurments at 5's Second intervals [Dont read Ec morre than once every 5 seconds]:");
 
 
};
//******************************************* End of Setup **********************************************************************//
 
 
 
 
//************************************* Main Loop - Runs Forever ***************************************************************//
//Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
void loop()
{
 
 
 
 
GetEC();          //Calls Code to Go into GetEC() Loop [Below Main Loop] dont call this more that 1/5 hhz [once every five seconds] or you will polarise the water
PrintReadings();  // Cals Print routine [below main loop]
 
 
delay(10000);// original is 5000 
 
 
}
//************************************** End Of Main Loop **********************************************************************//
 
 
 
 
//************ This Loop Is called From Main Loop************************//
void GetEC(){
 
 
//*********Reading Temperature Of Solution *******************//
sensors.requestTemperatures();// Send the command to get temperatures
Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
 
 
 
 
//************Estimates Resistance of Liquid ****************//
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
digitalWrite(ECPower,LOW);
 
 
 
 
//***************** Converts to EC **************************//
Vdrop= (Vin*raw)/1024.0;
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra; //acounting for Digital Pin Resitance
EC = 1000/(Rc*K);
 
 
//*************Compensating For Temperaure********************//
EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
//EC25 = EC;
ppm=(EC25)*(PPMconversion*1000);
 
 
;}
//************************** End OF EC Function ***************************//
 
 
 
 
//***This Loop Is called From Main Loop- Prints to serial usefull info ***//
void PrintReadings(){
Serial.print("Rc: ");
Serial.print(Rc);
Serial.print(" EC: ");
Serial.print(EC25);
Serial.print(" Simens  ");
Serial.print(ppm);
Serial.print(" ppm  ");
Serial.print(Temperature);
Serial.println(" *C ");
 
 




//********** Usued for Debugging ************
Serial.print("raw");
Serial.println(raw);
Serial.print("Vdrop: ");
Serial.println(Vdrop);
Serial.print("Rc: ");
Serial.println(Rc);
Serial.print(EC);
Serial.println("Siemens");
//********** end of Debugging Prints *********




};

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:28 point

Replied to the second post :) 

  Are you sure? yes | no

geert2 wrote 02/05/2017 at 13:20 point

Dear Michael, 

More respect every day. One remark and a cry for help. 

The Electric conductivity is an indicator for ammonia. Meaning that if you have a dead fish in the system, or algae that start dying, , you will notice the EC going thourgh the roof. This means the EC probe is one of the most telling indicators if something is going very wrong. 

I started to work on the system with a NODECMU Kit, and got quite far. 

However the readings are defenitely not right (see below). 

This could be because of the way the analog port reacts in a NODEMCU, or for any other reeason I don't understand, such as using digital pins for delivering the current. 

I am definitely out of my depth. Could you please help me? 

For water: 

Rc: 32808.05 EC: 0.01 Simens  6 ppm  25.50 *C 
raw993.00
Vdrop: 3.20
Rc: 32808.05
0.01Siemens

Salt water: 
Rc: 2752.90 EC: 0.12 Simens  79 ppm  25.50 *C 
raw748.00
Vdrop: 2.41
Rc: 2752.90
0.13Siemens

My code: 

//************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe
 

#include <Onewire.h>
#include  <Dallastemperature.h>

 
 
 
 
 
 
//************************* User Defined Variables ********************************************************//
 
 
//##################################################################################
//-----------  Do not Replace R1 with a resistor lower than 300 ohms    ------------
//##################################################################################
 
 
int R1= 1000;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=D7;
int ECPower =D8; // originally A4 is used by air pressure measurement 
 
 
//*********** Converting to ppm [Learn to use EC it is much better**************//
// Hana      [USA]        PPMconverion:  0.5
// Eutech    [EU]          PPMconversion:  0.64
//Tranchen  [Australia]  PPMconversion:  0.7
// Why didnt anyone standardise this?
 
 
float PPMconversion=0.64;
 
 
//*************Compensating for temperature ************************************//
//The value below will change depending on what chemical solution we are measuring
//0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
float TemperatureCoef = 0.019; //this changes depending on what chemical we are measuring
 
 
 
 
//********************** Cell Constant For Ec Measurements *********************//
//Mine was around 2.9 with plugs being a standard size they should all be around the same
//But If you get bad readings you can use the calibration script and fluid to get a better estimate for K
float K=2.88;
 
 
 
 
//************ Temp Probe Related *********************************************//
#define ONE_WIRE_BUS D2          // Data wire For Temp Probe is plugged into pin 10 on the Arduino // with me on 2 
//const int TempProbePossitive =8;  //Temp Probe power connected to pin 9  // I don' have that? 
//const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8  //should I do that? 
// 
 
 
 
//***************************** END Of Recomended User Inputs *****************************************************************//
 
OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
// 
 
float Temperature=10;
float EC=0;
float EC25 =0;
int ppm =0;
 
 
float raw= 0;
float Vin= 3.3;  // is only 3.3 v with esp was 5
float Vdrop= 0;
float Rc= 0;
float buffer=0;
 
 
 
 
//*********************************Setup - runs Once and sets pins etc ******************************************************//
void setup()
{
  Serial.begin(9600);
//  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
//  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
//  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
//  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly
 
  delay(100);// gives sensor time to settle
//  sensors.begin();
  delay(100);
  //** Adding Digital Pin Resistance to [25 ohm] to the static Resistor *********//
  // Consule Read-Me for Why, or just accept it as true
  R1=(R1+Ra);// Taking into acount Powering Pin Resitance
 
  Serial.println("ElCheapo Arduino EC-PPM measurments");
  Serial.println("By: Michael Ratcliffe  Mike@MichaelRatcliffe.com");
  Serial.println("Free software: you can redistribute it and/or modify it under GNU ");
  Serial.println("");
  Serial.println("Make sure Probe and Temp Sensor are in Solution and solution is well mixed");
  Serial.println("");
  Serial.println("Measurments at 5's Second intervals [Dont read Ec morre than once every 5 seconds]:");
 
 
};
//******************************************* End of Setup **********************************************************************//
 
 
 
 
//************************************* Main Loop - Runs Forever ***************************************************************//
//Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
void loop()
{
 
 
 
 
GetEC();          //Calls Code to Go into GetEC() Loop [Below Main Loop] dont call this more that 1/5 hhz [once every five seconds] or you will polarise the water
PrintReadings();  // Cals Print routine [below main loop]
 
 
delay(10000);// original is 5000 
 
 
}
//************************************** End Of Main Loop **********************************************************************//
 
 
 
 
//************ This Loop Is called From Main Loop************************//
void GetEC(){
 
 
//*********Reading Temperature Of Solution *******************//
sensors.requestTemperatures();// Send the command to get temperatures
Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
 
 
 
 
//************Estimates Resistance of Liquid ****************//
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
digitalWrite(ECPower,LOW);
 
 
 
 
//***************** Converts to EC **************************//
Vdrop= (Vin*raw)/1024.0;
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra; //acounting for Digital Pin Resitance
EC = 1000/(Rc*K);
 
 
//*************Compensating For Temperaure********************//
EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
//EC25 = EC;
ppm=(EC25)*(PPMconversion*1000);
 
 
;}
//************************** End OF EC Function ***************************//
 
 
 
 
//***This Loop Is called From Main Loop- Prints to serial usefull info ***//
void PrintReadings(){
Serial.print("Rc: ");
Serial.print(Rc);
Serial.print(" EC: ");
Serial.print(EC25);
Serial.print(" Simens  ");
Serial.print(ppm);
Serial.print(" ppm  ");
Serial.print(Temperature);
Serial.println(" *C ");
 
 




//********** Usued for Debugging ************
Serial.print("raw");
Serial.println(raw);
Serial.print("Vdrop: ");
Serial.println(Vdrop);
Serial.print("Rc: ");
Serial.println(Rc);
Serial.print(EC);
Serial.println("Siemens");
//********** end of Debugging Prints *********




};

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:01 point

Hey could you trim your post? [clip the code out?] I struggle to reply to long comments with one screen :) 

The NodeMcu has a second voltage divider [its a 1.1v analog input in real life], a bit more maths and It can work quite well [see second reply for a code snippet that works on my nodemcu]. Please do use the pins I suggest, the nodemcu has a lot of funky pull-up and down reistors on the other pins] also D7  has a pull up that makes it work with the temperature sensor without a external one]

I can email you over something ive been working on for the nodemcu [wifi, user interface and about a years worth of storage in the spiffs for datalog]  and files for a 3D printed fish feeder or hydroponics doser if you would find them useful.

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:01 point

float R1= 1200; //The resitor in the EC probe

float Ra=55; //Resistance of powering Pins
float Rd=100000; // Bottom half of adc oltage divider
int ECPin= A0;
int ECGround=D6;
int ECPower =D5;

float Vin =3.3; 
float Vout =0; //a variable for vout
//***************** Converts to volts **************************//
Vout= (raw)/1023.0;
//Calculates Prbe Resistance from Vout, 3.2 is a value relating to the voltage divider dont mistake it for a Vin
Rc=(  ((3.2*Vout)/(  ((Vin-(3.2*Vout))/(R1+Ra))-(Vout/Rd)))   -Ra);
EC = (1000.0*K)/Rc; 
//*************Compensating For Temperaure and convert to ppm********************//
EC25  =  EC/ (1+ TemperatureCoef*(DS18B20_Temperature-25.0));
ppm=(EC25)*(PPMconversion*1000.0);

  Are you sure? yes | no

davegreengo wrote 05/05/2018 at 06:10 point

Hi Michael, love your aqua/hydro control sensor setup here, I would be very interested in this NodeMCU code you have? I'm looking at setting this up on my Node over the next few days and would love to see your code.

Thanks a bunch, you've already saved me £££ and made gave me the possibility of getting my readings plotted over time once this is setup.

  Are you sure? yes | no

geert2 wrote 02/06/2017 at 06:38 point

I sent you more information by E-mail. Thanks for your support. 

The code below: 

1. so you say: take out D7 and D8 (use it for your relay) and connect to D6 and D5 (help, my soldering is not good). 

2. I understand you add a voltage divider with 3 times a 100K resistor (to buy), 

the line coming from D5 has first the 1.2 K  (why not 1k like everywhere else?) than 2 times a 100 K in serie,   

here comes the line to AO. between A0 and D6 you have the last 100K.

Why not only D5 and connect to Ground? 

My other sensors I don't have this voltage up/down thing, as it is too complicated for me as a newbee, and only with EC there is a real problem having permanent current. However, as I am looking to connect to solar power, savings might be good, knowing only pumps and heating really consume electricity. 

Geert

  Are you sure? yes | no

davegreengo wrote 05/05/2018 at 18:00 point

Hi,

Did you ever get this working on your NodeMCU, I would be interested in seeing your code if so.

Thanks,

Dave

  Are you sure? yes | no

Pranav P wrote 02/05/2017 at 06:09 point

Loved the project, using this for my aeroponics project. New to arduino. Where can I find these OneWire.h and DallasTemperature.h lib files? You mentioned that they were custom, but I cant find the link to download them. 

  Are you sure? yes | no

Pranav P wrote 02/05/2017 at 06:11 point

Saw the link right before the code, but it just leads back to your site. 

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:18 point

  Are you sure? yes | no

geert2 wrote 01/25/2017 at 14:49 point

Wonderful hack, thank you very much. 

To Luc: probably your water temp probe does not work and gives -127 C, making the outcome calibrated to 25 C quite wrong, 

I installed it on my aquaponics with an arduino and ESP8266. https://thingspeak.com/channels/147606. Now it runs on Yun, more stable, but I could not get the temp probe to work yet (probably broken). I took the temp compensation out. 

I plan to try a similar system on WEMOS D1R2 or other ESP-based kit. It would work on 3.3V. How to approach this? Would your calcuations stay valid? This would be a cheaper approach. 

Geert 

  Are you sure? yes | no

kg6tfg wrote 08/04/2020 at 07:57 point

hello Geert i know its been a while, just wonder if still have the of the for nodemcu/thingspeak, do you mind to post it here or i am happy if you can email it to me,

thanks

manoy

  Are you sure? yes | no

francocazzolli wrote 01/15/2017 at 00:13 point

Hi, I'm about to start the build on the hydro ppm meter to automate my current garden. Can anyone help with code for an addition of an analog output ( say 4-20ma) to allow the use of the output into a plc? I have not really done anything with Arduino before so my programming skills are minimal ;)

Ta

Franco

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:25 point

Im not quite sure what you mean. Does your PLC accept PWM as a input? 

  Are you sure? yes | no

Luc Kirsten-Roger wrote 12/14/2016 at 19:15 point

Hello ! Thank you for your code. I have tried running it on a NodeMCU and I'm getting a negative K when I run the calibration code. Do you have any idea on what might cause that ?

The only thing that I have change is that :
int R1= 480;
int Ra=25; //Resistance of powering Pins
int ECPin= 12;
int ECPower = 15;
I used one of the ground pin from the NodeMCU.
Thank you !

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:17 point

See above reply, I now have it working on a nodemcu, just needed tweeking to take care of the different pin resistances and built in voltage divider

  Are you sure? yes | no

edjay1980 wrote 11/12/2016 at 18:30 point

Hi Michael, great project! This was my take on it:

STEP 1: Estimate my K (basically I think about this K as my constant to take into account my own personal setting of the cable I chose w/ its respective lenght, the arduino I have, etc.)

Unfortunately K changes as a function of PPM:

PPM => K

140 => 5.20 (this is my tap water)

500 => 4.90

750 => 3.88

1000 => 3.50

1500 => 3.00

2000 => 2.98

So I chose a value around the PPM that I will be measuring which also happened to be the average of K = 3.91

(I can have K initially set at 3.91 and then a feedback loop that changes K according to what PPM I initially get, for now I left it at 3.91)


STEP 2: Measure ppm w/ K average. Expecting the most accurate measurement around 750 ppm

PPm (actual) => PPM (measured)

140 => 190

500 => 615

750 => 763

1000 => 945

1500 => 1097

2000 => 1410

STEP 3: fit an equation to account for error. Ended up fitting a linear, quadratic and logarithmic equation in Wolfram alpha.  The best fit was the quadratic.

y_actual = 0.000714574*measurement^2+0.441125*measurement+7.4625

ppm_corrected = 0.000714574*ppm_measured*ppm_measured     +     0.441125 * ppm_measured    +     7.4625;

PPM (actual) => PPM (corrected)

140 => 117
500 => 549
750 => 760
1000 => 1062
1500 => 1351
2000 => 2050


Made solutions using water and table salt

Eg. to make a 500 ppm solution, I used 12 Liters and 1 teaspoon of salt

Now I'm looking into how long my setup will maintain its calibration. I have measured my 6 samples every day for a week and it is still accurate. I have notice, however, that when I stir the solution before measuring, the measurement is less accurate. More accurate when I don't initially stir up the solution.

  Are you sure? yes | no

Michael Ratcliffe wrote 02/06/2017 at 00:23 point

Hey, 

I believe [an educated guess at best]  we are having a partial polarisation occur when measuring and adjusting the K value to get good readings. when you stir the solution your reducing the polarisation effect. 

Nice that you noticed it.

  Are you sure? yes | no

Organic & Healthy:-) wrote 10/15/2016 at 20:16 point

Michael, many thanks for this, looking forward to implementing it in a new aeroponic controller that we are designing with the Raspberry Pi and Arduino.  Will keep you updated and thanks again!

  Are you sure? yes | no

Michael Ratcliffe wrote 10/15/2016 at 21:39 point

Glad it was of use :) , keep an eye on the project for a new probe design. [a month or so away] 

  Are you sure? yes | no

Tomáš Klapka wrote 10/07/2016 at 16:25 point

 Amazing project and thanks for sharing. I've finaly found use for American Type A extension to Figure 8 which I got with a battery charger :)

I wanted to note that I read ph in the same water too and I've found that after setting ec pins it increases ph measurements up to around 11 and 12 ph. I guess it is because ph sensor generates and measures small current and pins in OUTPUT mode are messing with it. So I've changed the code a little bit...

In the setup part I set pins to INPUT:

void setup_ec()
{
  pinMode(PIN_EC, INPUT);
  pinMode(PIN_EC_VCC, INPUT);
  pinMode(PIN_EC_GROUND, INPUT);
  delay(100);
}

and every time i want to read EC, I configure VCC and GROUND pins, read value, and then again reset pins back to INPUT:

void read_ec_raw()
{
  // initialize pins
  pinMode(PIN_EC_VCC, OUTPUT);
  pinMode(PIN_EC_GROUND, OUTPUT);
  delay(100);
  digitalWrite(PIN_EC_GROUND, LOW);
  digitalWrite(PIN_EC_VCC, HIGH);
 
  // read value
  raw = analogRead(PIN_EC);
  raw = analogRead(PIN_EC);// This is not a mistake, First reading will be low (charged capacitor)
 
  // deconfigure pins
  digitalWrite(PIN_EC_VCC, LOW);
  pinMode(PIN_EC_VCC, INPUT);
  pinMode(PIN_EC_GROUND, INPUT);
  delay(100);
}

This way both ph and ec readings seem to be correct :)

  Are you sure? yes | no

Michael Ratcliffe wrote 10/07/2016 at 17:09 point

Thanks for confirming the pimode fix solved the issue :) 

  Are you sure? yes | no

feini22163 wrote 03/21/2017 at 05:12 point

Can u explain what you mean? How can you get pH value?

  Are you sure? yes | no

Ditia Fajrin Febrian wrote 10/03/2016 at 08:34 point

Hi Michael,

Nice project!

I have a question here,

1. if i use mini probe with 4mm lenght and only 2mm gap, will it work? Do I need to make some adjustment? or a calibration will be enough?

2.in what unit the ec measured? S? mili S? or micro S?

Waiting for your help.

Thank you very much!

  Are you sure? yes | no

Michael Ratcliffe wrote 10/05/2016 at 10:20 point

Hey, sorry about the late reply :)  do you have a link to the probe you plan onn using?

1. Any probe should work, ll you need is two pieces of conductive material in the water with a small gap between them. you will need to choose a resitor to suit your estimated cell constant [The cell constant, K, is equal to the distance in cm between the probe's electrodes divided by the surface area of the electrodes in cm2] 

*2mm of a gap might have a lot of "fringing", ie the gap is too small and it distorts the cell constant.

2. I cant recall :D Its been a long time, you will be able to wor it out by comparing the ppm readout to the EC? 

Drop me a message i you need any more help.

  Are you sure? yes | no

Ditia Fajrin Febrian wrote 12/09/2016 at 03:51 point

Hi Michael,

It's been a long day, sorry I just asking for help then gone for so long. 

Here are the link to the probe i plan to use, really small,

https://www.aliexpress.com/item/New-G1-4-0-8MPA-Water-quality-probe-TDS-conductivity-test-water-quality-testing-probe/32630094172.html

When I run the calibration code, the K value is at 0,75.

I test to read a 1 mS/cm solution and the result are smaller it is around 0,8 mS/cm. Is it fine?

Thank you

  Are you sure? yes | no

Michael Ratcliffe wrote 12/09/2016 at 14:02 point

You are using temperature compensation? I dont see a temp sensor on the probe..

  Are you sure? yes | no

Ditia Fajrin Febrian wrote 12/12/2016 at 08:55 point

Yes, I do exactly as instructed, i am using DS18B20 waterproof type.

  Are you sure? yes | no

Michael Ratcliffe wrote 12/12/2016 at 12:28 point

time to find a fault then :) I would imagine its one of the following:

1>Temperature compensation value [coefficient] of your test fluid and calibration fluid are different?  what are you measuring and hat calibration fluid?

2>The probe has a bit of internal Resistance,, can test this with a ohm meter between electrical connector and probe pin.. should be very low resistance.

3>Choice of resistor you Soldered in parallel with probe is either on the wrong side [should be on Vin side] or the value is not the best choice for your range of ec?

  Are you sure? yes | no

Michael Ratcliffe wrote 12/12/2016 at 12:29 point

time to find a fault then :) I would imagine its one of the following:

1>Temperature compensation value [coefficient] of your test fluid and calibration fluid are different?  what are you measuring and hat calibration fluid?

2>The probe has a bit of internal Resistance,, can test this with a ohm meter between electrical connector and probe pin.. should be very low resistance.

3>Choice of resistor you Soldered in parallel with probe is either on the wrong side [should be on Vin side] or the value is not the best choice for your range of ec?

  Are you sure? yes | no

truthhung0726 wrote 09/02/2016 at 13:08 point

Hello, Michael,

Your solution is so good for TDS, how about measuring salinity? I tried to use this solution to detect salinity of warer, the result is far from the salinity meter. How can you modify this solution for the salinity. Could you give me some information? Thanx,  

  Are you sure? yes | no

Michael Ratcliffe wrote 09/02/2016 at 15:41 point

Hey thanks for the feedback :)

To measure Salinity:

>Find a temperature compensation value for sea water [or work it out]

>Run thru the maths a little with an estimate for the range of EC you want to measure. You may find that the resistance between probes is very low and you cant go below 300ohms current limiting resitor to match. You may have to decrease probe area of the plug [heat shrink should work] untill you get K value that will work for your fluid.

  Are you sure? yes | no

Ozel wrote 08/29/2016 at 06:32 point

Hi Michael

I am usung your project in my hydroponic system for couple of months, and it is great, thanks for sharing. My problem is elektrolysis between US plug electrodes. I am measuring Ec each 10sec, but because of DC I think, particules are being collected one electrode, and it makes wrong Ec measurement. 

İs there any way to avoid it?

Thanks a lo

  Are you sure? yes | no

Michael Ratcliffe wrote 08/29/2016 at 12:07 point

Hey, Some plugs are stainless steel, others are plated. 

Are both prongs degrading, or just one? 

  Are you sure? yes | no

Ozel wrote 08/29/2016 at 12:24 point

Both of them has changed their color to brown, but only one is degraded. 

  Are you sure? yes | no

Michael Ratcliffe wrote 08/29/2016 at 12:28 point

If you clean them does the coating come away from the plug?

You cold change the measurment time from ten seconds to 60 seconds? 10 seconds is probably a lot more data than you need. Also setting the ground as an input when not measuring will increase proble life. :)

  Are you sure? yes | no

Ozel wrote 09/01/2016 at 08:13 point

I did it, thanks a lot Michael

  Are you sure? yes | no

sombrablack wrote 08/13/2016 at 18:17 point

In sorry to keep bothering but i dont see the voltage divider in the arduino picture would it still work if instead of building the circuit in the  Arduino picture i use the equivalente voltage divider schematic?

  Are you sure? yes | no

Michael Ratcliffe wrote 08/14/2016 at 14:56 point

Can you re word the question? I dont quite follow

  Are you sure? yes | no

e.ercanbalbay wrote 08/04/2016 at 19:50 point

Hi,

Thank you for basic circuit. I have installed ec probe and start to test it with sd card as data logger. For tap water i see ec value is dropping in 24 hours. first reading is  0,4 ec lastest one(24h later) 0,32 :( I didnt use temperature sensor and temperature compensation , could it affect the readings and value drop ? ı have used 1 k resistor. measured in 5 seconds interval.

Graph;

  Are you sure? yes | no

Michael Ratcliffe wrote 08/05/2016 at 10:12 point

Temperature compensation is needed for EC, this effect could be from a temperature change [although I would expect it to be a U shape over 24 hours].  How small is your test container, the less volume the more likely to polarise.

Looks like a good code, mind sharing it?

  Are you sure? yes | no

Organic & Healthy:-) wrote 10/15/2016 at 20:13 point

What you have here appears to be normal activity regarding tap water, the chlorine and fluoride will evaporate over a 24 hr period.  Most aquarium stores recommend not using tap water before waiting over a 24 hour period or due to this very issue. 

This really documents how well Michael's hack works as it clearly shows the chemicals evaporating over time.  If you had RO water with 0PPM to start it should be flat-lined.

  Are you sure? yes | no

sombrablack wrote 08/01/2016 at 23:42 point

Im sorry but if i were to use an alternating voltage source how doesthe Math change. I mean to calculate The EC?

  Are you sure? yes | no

Michael Ratcliffe wrote 08/02/2016 at 12:25 point

Depends what circuitry you are using to do this. 

  Are you sure? yes | no

sombrablack wrote 08/02/2016 at 16:11 point

I'm thinking in a pwm of 95Hz from the MCU or an NE555 at 95Hz to get continuous reading

  Are you sure? yes | no

Michael Ratcliffe wrote 08/02/2016 at 22:07 point

You will need to read up on polarisation and frequency [I recall a lower limit]. but tbh unless your using this for process control, a reading every 5 seconds should be enough.

  Are you sure? yes | no

sombrablack wrote 08/02/2016 at 23:36 point

thanks im testing a new MCU but it only works with digital gates and counters and I can't program it using code but rather making some boolean gates, its new so its weird but I already made it to read and send the pulse in intervals of 5 seconds. 

  Are you sure? yes | no

oschneider wrote 07/16/2016 at 08:32 point

Michael, did you run your program for several days? I made an ec probe according to your specification and let your program run several hours and suddenly I can not read from serial anymore. This is the case: http://forum.arduino.cc/index.php?topic=412806.0

Now I will print some more debug information in the sketch in order to figure out  if the program is working properly. I don't think it is the Raspberry which receives the sensor data via serial USB. Or maybe my Mega is broken ...

  Are you sure? yes | no

Michael Ratcliffe wrote 07/17/2016 at 12:13 point

Hey Buddy, Ive let the code run for months at a time [dosing my system] and a few people around the world are using it for long term data logging.

Maybe there is something being sent back in your serial loop that is eating slowly at the memory? The lib below will let you keep a track of memory ussage.

http://playground.arduino.cc/Code/AvailableMemory 

  Are you sure? yes | no

oschneider wrote 07/17/2016 at 18:57 point

Thx, Michael for your feedback. I already printed out the free memory in your loop but there was not any increase. I am using now another communication pattern. I am asking the Arduino to send data and then the Arduino reacts. This is working. I am receiving the sensor data on a Raspberry Pi with pyserial and I think there was going wrong something on this side. 

  Are you sure? yes | no

Michael Ratcliffe wrote 07/17/2016 at 20:00 point

Glad you solved it :)

  Are you sure? yes | no