element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Vertical Farming
  • Challenges & Projects
  • Design Challenges
  • Vertical Farming
  • More
  • Cancel
Vertical Farming
Blog Automated Green House Blog:10 - Three Dollar EC PPM Meter for MCU
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: m.ratcliffe
  • Date Created: 3 Sep 2015 2:56 AM Date Created
  • Views 8191 views
  • Likes 3 likes
  • Comments 40 comments
  • adapted_greenhouse
  • ppm
  • cheap
  • ec
  • arduino
Related
Recommended

Automated Green House Blog:10 - Three Dollar EC PPM Meter for MCU

m.ratcliffe
m.ratcliffe
3 Sep 2015

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.

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

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:

image

 

Wiring it up:

Note: You want the Solid Prong type plug

Do not Plug the pronged plug into the mains


image

 

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.


image

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:


image


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.

>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 https://wp.josh.com/2014/06/23/no-external-pull-up-needed-for-ds18b20-temp-sensor/ ] or add a pull up for the temperature probe data line [google it]

 

Calibration Code

 

 

/*

  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 <http://www.gnu.org/licenses/>.

 

    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
https://wp.josh.com/2014/06/23/no-external-pull-up-needed-for-ds18b20-temp-sensor/  << Library for using the temp probe without a pullup

 

*/

 

 

//************************** 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);

 

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]

 

EC PPM Measurement Code

 

 

/*

  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 <http://www.gnu.org/licenses/>.

 

    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);

 

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

 

 

Side Note: I haven't got the Figure 8 Junction Block to test, but if it has a decent resistance we will have to add it to the Ra variable to get good readings, I will update this once I know more.

 

  • Sign in to reply

Top Comments

  • m.ratcliffe
    m.ratcliffe over 10 years ago +2
    Well Guys there is some good news on the PH Front, we all know the Ph Probes are Expensive. Ive just been playing about with the plug sensor and some basics/acids solutions, there is something going on…
  • RWReynolds
    RWReynolds over 9 years ago in reply to m.ratcliffe +2
    Are you familiar with the ScIO device? I think it's supposed to be available summer of '15 and is around $150 - $200, a little out of budget I know. But it looks pretty promising. https://www.consumerphysics…
  • m.ratcliffe
    m.ratcliffe over 10 years ago in reply to DAB +1
    Thanks Dab, The Ec Probes usually last a long time, Using DC might make them wear out a little faster but at $1 a probe i'm happy to change them annually along with the main water carbon filter. I'm guessing…
  • deedeeharris
    deedeeharris over 3 years ago in reply to kevingooran

    Hey,

    Did you find the appropriate values for the esp32?

    Thanks.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • tonttu
    tonttu over 4 years ago

    Nice project. Now I'm really curious if the polarization could be minimized with taking two measurements per cycle, but flipping the HIGH and LOW in between, so it would be kind of square wave ac.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • m.ratcliffe
    m.ratcliffe over 5 years ago in reply to kevingooran

    Hi, yes the ADC range/bits will need changing, you may also need to change the Vin part as the esp32 is a 3.3v board not 5.

     

    Output pin resistance can be calculated from this graph using ohms law:


    There are multiple lines because each output pin can be set in different power/current modes. I would stick with one of the modes that has a linear output resistance [such as source3].image

    More info: https://www.esp32.com/viewtopic.php?f=12&t=5840 


    Also note that the ADC of the esp32 is not linear and to get accurate voltage readings it needs a calibration table. The Dev boards also can be a bit messy and have pullup/down resistors on some of the ADC channels, you may need to consult the schematic to find a bare ADC pin, it also has two ADC chips one of which can not be used when wifi is enabled.

    All the best,

    Mike

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • kevingooran
    kevingooran over 5 years ago in reply to m.ratcliffe

    Hi Michael ! if i want use this code in esp32, i should change 1024.0 to 4096.0 , right ? and how about ra & rd value ?.

    i hope you can help me to rewrite this code for esp32, thanks

     

    best regards

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • m.ratcliffe
    m.ratcliffe over 5 years ago in reply to gabri84

    Hi Gabri, Sure share your code/example on E14 and send a link. Im sure myself and others will find it interesting.

    As for using a esp8266 as the mcu for EC. It is a little more challenging as the resistance of the probes is different and the esp8266 have a voltage divider before the ADC that needs to be taken into account.

    Below is an example ode for the esp8266:




    //************* DS18B20 Temperature Sensor *********************//

    #include <OneWire.h>

    #include <DallasTemperature.h>

    //Need To Use Pin D3 Because it has an internal pullup [dont change this pin unless you really have to]

    #define ONE_WIRE_BUS D3  // Data wire For Temp Probe is plugged into pin 10 on the Arduino

    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 DS18B20_Temperature =0;

     

     

    //*************** EC Probe Related ***************//

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

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

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

     

     

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

    int Ra=55; //Resistance of powering Pins

    int Rd=100000; // Bottom half of adc oltage divider built into the esp8266

    int ECPin= A0;

    int ECGround=D7;

    int ECPower =D8;

     

     

    float Vin =3.3;

    float Vout =0; //a ariable for vout

     

     

    float Rc =1; //a variable for probe resistance

    int raw=1; // a variable for ADc result

    float EC = 1; //ariable for actual EC

    float EC25 = 1;  //After Taing into account Temperature

    float ppm=1; //PPM Equiilent

    //Some Variables for Calibration

    //Quick and dirty calibration by serial

    float EC_Calibration_TempCopensated =1;

    float Kn=1;

    float EC_Calibration=0.54;

    float Rc_Calibration=1;

     

     

    //*********** 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=0.71;

     

     

    void setup() {

      // put your setup code here, to run once:

    Setup_EC();

     

     

    }

     

     

    void loop() {

    Read_EC();

    delay(10000); // doing it faster will polarise the probe plates/fluid

     

     

    }

     

     

     

     

     

     

    //*************************** Functions *****************************//

    void Setup_EC(){

    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

    };

     

     

    //************************ Reading EC Probe ***********************//

    void Read_EC(){

    Get_DS18B20_Temperature();

    //************ Getting the ADC Reading ****************//

    digitalWrite(ECPower,HIGH);

     

     

    raw= analogRead(ECPin);

    raw= analogRead(ECPin);

    digitalWrite(ECPower,LOW);

     

    //***************** Converts to volts **************************//

    Vout= (raw)/1024.0;

    //Calculates Prbe Resistance from Vout

    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);

     

     

     

     

    //

    Serial.print("  Fluid EC: ");

    Serial.print(EC25);

    Serial.print(" S  ");  //add units here

    Serial.print("Raw: ");

    Serial.print(raw);

    Serial.print("Ec Prbe: ");

    Serial.print(Rc);

    Serial.print(" Ohms  ");  //add units here

    Serial.print("Cell Constant K");

    Serial.println(Kn);

    }

    //************* Reading the waterproof temperature probe *******************//

    void Get_DS18B20_Temperature(){

    sensors.requestTemperatures();// Send the command to get temperatures

    DS18B20_Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable

    Serial.print(F("DS Temperature:     "));

    Serial.println(DS18B20_Temperature);

     

    };

     

     

     

     

     

     

    void Calibrate(){

    delay(30000);

    Rc_Calibration=0;

    Read_EC();

    Rc_Calibration=Rc_Calibration+Rc;

    delay(5000);

    Read_EC();

    Rc_Calibration=Rc_Calibration+Rc;

    delay(5000);

    Read_EC();

    Rc_Calibration=Rc_Calibration+Rc;

    delay(5000);

    Read_EC();

    Rc_Calibration=Rc_Calibration+Rc;

    delay(5000);

    Read_EC();

    Rc_Calibration=Rc_Calibration+Rc;

     

     

    Rc_Calibration=Rc_Calibration/5;

     

     

    //Quick and dirty calibration by serial

    EC_Calibration_TempCopensated =EC_Calibration*(1+(TemperatureCoef*(DS18B20_Temperature-25.0))) ;

    Kn=((EC_Calibration_TempCopensated*Rc_Calibration)/1000.0);

     

     

     

    };

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube