A Updated PH Probe, Now gives A Readout For Probe Life and a time alarm for when to Calibrate.

 

DFRobot were nice enough to send me one of their pH pro MCU probes [Longer lasting] but this tutorial and code will work for any analog pH MCU meter [ebay special etc] these are coming down in price rapidly but I recommend calibrating often.

 

The Analog pH breakout boards often have a little pot for adjusting during calibration, this is a pain in the ass at calibration time. This new code uses a different method and is all code based.

 

 

 

 

Pinout

[Turn Pot on PH meter fully  anticlockwise, we are now using a better Calibration method]

 

GUI

The LCD has a few useful Screens

l

 

 

How It works:

 

pH Measurement and Calibration

pH probes output a small voltage change [from-170mv to 170mv, for ph 4-10], the breakout board is essentially a op amp with an offset. So it now outputs a 0-5v signal.

These boards are made with a potentiometer to change the gain of the amplifier to calibrate, good idea but very awkward, we instead will be giving it a set gain and calibrating in the code.

So what are the steps if you have a different board:

>Turn Pot fully clockwise

>Short BNC connector together and read mv [from serial] This is your Ideal pH reading, the DF robot is 1.96v

>Connect probe and read mv [from serial] when in pH4 and pH7, The probe change will be 170mv, you now have a way to work out the gain of the amp.

 

pH = 7 -(Ph_Calibration_mv - measured_mv)*gain   // Simple?

 

Doing it this way we can read pH and calibrate without messing with that pot ever again, by taking three readings  1:Ideal pH 7 mv  , 2:Actual pH7 mv ,  3: pH4mv

 

The LCD GUI will guide you thru a Calibration process:

 

k

 

Probe Life

The LCD screen with Probe life should have all readings above 50% to be considered a probe in good health, if ones lower I recommend cleaning it or ordering a replacement [It will fail soon].

 

There are three indicators of probe life when we calibrate.

http://reagecon.com/pdf/technicalpapers/Electrode_CM_v5_TSP-02_Issue_4.pdf

In the Code these are showed as:

H1: pH7 offset [pH7 should output the ideal voltage of 1.96, as they age they get an offset

H2 Slope,  change in mv between pH4 calibration and pH7 

H3:Drift , Healthy probes should have reached a s.s value after 60 seconds, this one checks for a difference between a reading at 60 seconds and 120

 

A more Technical Explanation of the health checks:

//there are three ways we can measure a proble life during calibration:

//1:Asymmetry potential (Eo), the Millivoltes at pH7 [mV reading in pH 7.00 buffer ± 25 mV]

//2:Slope, mv per Ph change [mV reading in pH 7.00 buffer - mV reading in pH 4.00 buffer 160 – 180 mV]

//3:Drift mV reading in pH 4.00 buffer (1 min) – mV reading in pH 4.00 buffer (2 min) ± 1.5 mV  [we are checking for stable readings]

 

 

I have tested this code with good probes, failed probes and aged b probes and it works very well at identifying them.

Got a probe with a low Health indicator one or three? check out the blog on reviving a probe:

Blog:13.9 - PH Probe Revival: Ultrasonic Cleaning

 

 

The Code

This reads the ph probes shield [its an analog value] averages ten readings to reduce any noise and converts the ADC reading into a ph value. outputting the reading to serial.

 

The code works and it works great, I did however group into one variable the gain and slope, this means the health check values are only valid for analog probes, there will be an updated I2C version soon.

 

Header 1

/*

   Script to print PH to serial

 

 

 

   * Turn Pot fully counter clockwise[All the way it should take multiple turns], we arnt ussing it anymore for calibration

 

 

   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

   -df Robot Ph Probe Kit [SKU:SEN0169] This is a great PH sensor compared to the ones ive had in the past

 

 

  

    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"

#include "LiquidCrystal.h" //Standard LCD Lbrary

#include "EEPROM.h" //Standard EEPROM Library

 

 

//*********************** User defined variables ****************************//

//The Number of Days before the LCD will tell you its time to Calibrate

int Cal_Period_Warining=30;

//pH meter Analog output to Arduino Analog Input 0

int PHPin =A15;  

//I got this from shorting the nbc's cnetre pin to outer pin [simulated the perfect probe] open serial and its the mv reading that you want to put here

float Healthy1_mv=1.96;    

 

 

 

 

 

 

//************ Temp Probe Related *********************************************//

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

const int TempProbePossitive =22;  //Temp Probe power connected to pin 9

const int TempProbeNegative=24;    //Temp Probe Negative connected to pin 8

float Temperature=0.0;

float MinT=100;

float MaxT=0;

 

 

 

 

//********************** End Of Recomended User Variables ******************//

 

 

 

 

//************** Some values for working out the ph*****************//

 

 

float mvReading=0;

float Vs=5;

float phValue=0;

int i=0;

long reading=0;

unsigned long sum=0;

float average=0;

//used for min/max logs

float MinPH=10;

float MaxPH=0;

 

 

//************** Variables used to determin probe health **********//

//there are three ways we can measure a proble life during calibration:

//1:Asymmetry potential (Eo), the Millivoltes at pH7 [mV reading in pH 7.00 buffer ± 25 mV]

//2:Slope, mv per Ph change [mV reading in pH 7.00 buffer - mV reading in pH 4.00 buffer 160 – 180 mV]

//3:Drift mV reading in pH 4.00 buffer (1 min) – mV reading in pH 4.00 buffer (2 min) ± 1.5 mV  [we are checking for stable readings]

int ProbeLife1=0;

float mvReading_7=0;

 

 

//Some major brands will have this set at 35mv, we have a gain of around 8 in our op amp

float Health1_range =0.28;

float Healthy1_mv2=1.96;

 

 

 

 

//I got these from a healthy probe and extrapolating the slope deviation

int ProbeLife2=0;

float Slope=0;

float mvReading_4=0;

float Healthy2_Slope=2.15;

float Healthy2_range=0.25;

 

 

int ProbeLife3=0;

float Drift=0;

float mvReading_4_Delayed=0;

float Healthy3_Drift=0;

float Healthy3_range=0.02;

 

 

//some Variables for Probe Calibration Time

int Last_Day=0;

int Days_Since_Calibration=0;

int CalibrationWarning=0;

 

 

float offset=0;

 

 

// select the pins used on the LCD panel

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

 

 

// define some values used by the panel and buttons

int lcd_key     = 0;

int adc_key_in  = 0;

int button =0;

#define btnRIGHT  1

#define btnUP     2

#define btnDOWN   3

#define btnLEFT   4

#define btnSELECT 5

#define btnNONE   6

 

 

int Screen =1;

//Max number of screens on lcd

const int Last_Screen_no =6;

//used to debounce input button

int buttonLast=0;

 

 

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.

 

 

//************************** Just Some basic Definitions used for the Up Time LOgger ************//

long Day=0;

int Hour =0;

int Minute=0;

int Second=0;

int HighMillis=0;

int Rollover=0;

 

 

//Used For Calibration timing

unsigned long StartCalibration1=0;

 

 

//***************** Specifying where to sotre the calibration value [non volatile memory **//

int value=0; //we use this to check if memory has been writen or not

int addresCalibrationPH4=0;

int addresCalibrationPH7=50;

int addresProbleLife1=100;

int addresProbleLife2=150;

int addresProbleLife3=200;

int addresseCalibrationDays=250;

 

 

//************************************** Setup Loop Runs Once ****************//

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

  read_Temp();// getting rid of the first bad reading

  Read_Eprom();

  Slope_calc();

  Splash_Screen();

 

if(Days_Since_Calibration>=Cal_Period_Warining) CalibrationWarning=1;

 

//Adjusting some values for use later in map function

Healthy1_mv2=Healthy1_mv*1000;

Health1_range =Health1_range*1000;

 

 

Healthy2_Slope=Healthy2_Slope*1000;

Healthy2_range=Healthy2_range*1000;

 

 

Healthy3_Drift=Healthy3_Drift*1000;

Healthy3_range=Healthy3_range*1000;

 

 

}

//******************************** End Of Setup **********************************//

 

 

//******************** Main Loops runs Forver ************************************//

void loop()

{

 

 

//All these functions are put below the main loop, keeps the loop logic easy to see

read_LCD_buttons();

read_Temp();

Log_Min_MaxTemp();

ReadPH();

Log_Min_MaxPH();

uptime();

//Used to see hoe many days ago the probe was calibrated

Day_Change();

CalibratePH();

PrintReadings();

delay(100);

};

 

 

//************************** End Of Main Loop ***********************************//

 

 

 

 

//*************************Print Some useful startup info **************************//

void startupinfo(){

Serial.println("pH Probe Script for arduino");

Serial.println("Released under GNU by Michael Ratcliffe");

Serial.println("www.MichaelRatcliffe.com");

Serial.println("Element14 'Adapted_Greenhouse'");

Serial.println("Using DFRobot PH Probe Pro ");

Serial.println("How to Use:");

Serial.println("1:Place Probe into pH7 calibration fluid, open serial ");

Serial.println("2:Take Recomened cell constand and change it in the top of code");

Serial.println("3:Rinse Probe and place in pH4 calibration fluid");

Serial.println("4:Adjust potentiometer on pH meter shield until ph reading in serial is 4");

Serial.println("    ");

Serial.println("Thats it your calibrated and your readings are accurate!");

 

}

 

 

//***************************** Function to read temperature ********************************//

void read_Temp(){

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

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

 

 

 

 

}

 

 

 

 

 

 

//*************************Take Ten Readings And Average ****************************//

void ReadPH(){

  i=0;

  sum=0;

  while(i<=20){

  reading=analogRead(PHPin);

  sum=sum+reading;

    delay(10);

    i++;

  }

average=sum/i;

 

 

//Converting to mV reading and then to pH

mvReading=average*Vs/1024;

//phValue=mvReading*K_PH;  

phValue=(7-((mvReading_7-mvReading)*Slope));

 

 

}

 

 

 

 

 

 

 

 

 

 

//****************************** Reading LCd Buttons ****************************//

void read_LCD_buttons(){

  adc_key_in = analogRead(0);      // read the value from the sensor

// my buttons when read are centered at these valies: 0, 144, 329, 504, 741

// we add approx 50 to those values and check to see if we are close

if (adc_key_in > 1000)  button =0;

 

 

else if (adc_key_in < 50)   button =1;

else if (adc_key_in < 250)  button =2;

else  if (adc_key_in < 450)  button =3;

else if (adc_key_in < 650)  button =4;

else if (adc_key_in < 850)  button =5;

 

 

 

 

//Second bit stops us changing screen multiple times per input

if(button==2&&buttonLast!=button){

Screen++;

 

 

}

else if (button==3&&buttonLast!=button){

Screen--;

};

 

 

if (Screen>=Last_Screen_no) Screen=Last_Screen_no;

if(Screen<=1) Screen=1;

 

 

buttonLast=button;

};

 

 

 

 

 

 

//************************ Uptime Code - Makes a count of the total up time since last start ****************//

 

 

void uptime(){

//** Making Note of an expected rollover *****// 

if(Day>=30){

HighMillis=1;

 

 

}

//** Making note of actual rollover **//

if(millis()<=100000&&HighMillis==1){

Rollover++;

HighMillis=0;

}

//Calculating the uptime

long secsUp = millis()/1000;

 

 

Second = secsUp%60;

 

 

Minute = (secsUp/60)%60;

 

 

Hour = (secsUp/(60*60))%24;

 

 

Day = (Rollover*50)+(secsUp/(60*60*24));  //First portion takes care of a rollover [around 50 days]

 

 

 

 

 

 

                     

};

 

 

 

 

//************************** Printing somthing useful to LCd on start up **************************//

void Splash_Screen(){

 

 

lcd.begin(16, 2);              // start the library

lcd.setCursor(0,0);

delay(1000);

lcd.print("PH meter       ");

lcd.setCursor(0,1);

delay(1000);

lcd.print("Mike Ratcliffe");

lcd.setCursor(0,1);

delay(1000);

lcd.setCursor(0,1);

lcd.print("Free Software   ");

delay(1000);

lcd.setCursor(0,1);

lcd.print("Mike Ratcliffe");

delay(1000);

lcd.setCursor(0,1);

lcd.print("Free Software   ");

delay(1000);

  lcd.setCursor(0,0);

lcd.print("To Navigate         ");

  lcd.setCursor(0,1);

lcd.print("Use Up-Down     ");

delay(3000);

  lcd.setCursor(0,0);

lcd.print("To Calibrate      ");

  lcd.setCursor(0,1);

lcd.print("Hold Select       ");

delay(3000);

 

 

 

 

};

 

 

//******************** calculating the PhMeter Parameters ***************************************//

void Slope_calc(){

 

 

offset=Healthy1_mv-mvReading_7;

Slope=3/(Healthy1_mv-mvReading_4-offset);

 

}

 

 

//*************************** Checking what we stored in non volatile memory last time ************//

void Read_Eprom(){

 

 

//************** Restart Protection Stuff ********************//

  //the 254 bit checks that the adress has something stored to read [we dont want noise do we?]

   value = EEPROM.read(addresCalibrationPH7);

   mvReading_7=value*Vs/256;

   delay(10);

 

value = EEPROM.read(addresCalibrationPH4);

   mvReading_4=value*Vs/256;

   delay(10);

//Checking for Probe Life 1 Indicator

value = EEPROM.read(addresProbleLife1);

   ProbeLife1=value;

   delay(10);

//Probe:ife 2 saved

   value = EEPROM.read(addresProbleLife2);

   ProbeLife2=value;

   delay(10);

//Probe:ife 3 saved

   value = EEPROM.read(addresProbleLife3);

   ProbeLife3=value;

   delay(10);

 

 

  //Checking memory slot for probe calibration time

  Days_Since_Calibration = EEPROM.read(addresseCalibrationDays);

 

 

 

 

};

 

 

//******************************* Checks if Select button is held down and enters Calibration routine if it is ************************************//

void CalibratePH(){

 

 

 

//we check if we are on ph screen and the select button is held

if(Screen!=4) return;

if(button!=5) return;

else delay(1000);

read_LCD_buttons();

if(button!=5) return;

 

 

//we need to stop in this loop while the user calibrates

while(1){

read_LCD_buttons();

lcd.setCursor(0,0);

lcd.print("Ph Probe in pH7   ");

lcd.setCursor(0,1);

lcd.print("Press Right            ");

//user pressed right?

if(button==1) break;

delay(100);

       };

StartCalibration1=millis();

 

 

//We are giving the probe 1 minute to settle

while(millis()<StartCalibration1+60000){

lcd.setCursor(0,0);

lcd.print("Calibrating              ");

lcd.setCursor(0,1);

lcd.print("                      ");

lcd.setCursor(0,1);

lcd.print(StartCalibration1+60000-millis());

lcd.setCursor(7,1);

lcd.print(":mSeconds");

delay(1000);

};

ReadPH();

delay(100);

ReadPH();

               

   //*******Saving the new value to EEprom**********//  

   mvReading_7=mvReading;

 

 

 

 

 

 

while (1) { // wee need to keep this function running until user opts out with return function

                            

  read_LCD_buttons();

  if(button==3) return; //exits the loop without saving becauser user asked so

                            

if(millis()%4000>=2000){

   

     lcd.setCursor(0,0);

     lcd.print("Calibrated         ");

       lcd.setCursor(0,1);

      lcd.print("Select To Save       ");                            

 

 

                              }

else{

                             

                   

      lcd.setCursor(0,1);

      lcd.print("Down to Exit           ");

                              };

                            

   if (button==5) break;

}                              

//read the ph probe

 

 

   //Saving the value steight from ADC, removes conversion errors                              

   value= average/4;

   EEPROM.write(addresCalibrationPH7,value);

   //Resetting the days sinc calibration

   Days_Since_Calibration=0;

   CalibrationWarning=0;

   Slope_calc();

   ProbeLife_Check_1();

   EEPROM.write(addresseCalibrationDays,Days_Since_Calibration);

 

 

   //Displaying the new offset

   lcd.setCursor(0,0);

   lcd.print("Saved Calibration        ");

                                                          

   lcd.setCursor(0,1);

   lcd.print("Offset                        ");

   lcd.setCursor(3,1);

   lcd.print(offset);

   delay(2000);

   //move onto pH4 Calibration

 

                               

 

 

   lcd.setCursor(0,0);

   lcd.print("Rinse and           ");

                                                          

   lcd.setCursor(0,1);

   lcd.print("Placein pH4                      ");

 

   delay(4000);

 

   while(1){

   lcd.setCursor(0,0);

   lcd.print("Press Right          ");

                                                          

   lcd.setCursor(0,1);

   lcd.print("If Probe in 4                       ");

   //move onto next stage if select is held

   read_LCD_buttons();

   if (button==1) break;

   }

StartCalibration1=millis();

 

 

//We are giving the probe 1 minute to settle

while(millis()<StartCalibration1+60000){

lcd.setCursor(0,0);

lcd.print("Calibrating              ");

lcd.setCursor(0,1);

lcd.print("                      ");

lcd.setCursor(0,1);

lcd.print(StartCalibration1+60000-millis());

lcd.setCursor(7,1);

lcd.print(":mSeconds");

delay(1000);

};

ReadPH();

delay(100);

ReadPH();

 

 

mvReading_4=mvReading;

 

 

 

 

   //We are giving the probe 1 minute to settle

   StartCalibration1=millis();

  while(millis()<=StartCalibration1+60000){

  lcd.setCursor(0,0);

  lcd.print("Health Check              ");

  lcd.setCursor(0,1);

  lcd.print("                      ");

  lcd.setCursor(0,1);

  lcd.print(StartCalibration1+60000-millis());

lcd.setCursor(7,1);

lcd.print(":mSeconds");

  delay(1000);

};

ReadPH();

delay(100);

   ReadPH();

   mvReading_4_Delayed=mvReading;

   //Saving ADc readout, to remove conversion errors

   value= average/4;

EEPROM.write(addresCalibrationPH4,value);

   Slope_calc();

   ProbeLife_Check_2();

   ProbeLife_Check_3();

 

   //Put back to main screen and exit calibration

   lcd.setCursor(0,0);

   lcd.print("Saved Calibration        ");

 

   delay(1000);

  //Informing the use about the probe life

while(1){

read_LCD_buttons();

 

 

 

 

if(ProbeLife2>=50 && ProbeLife2>=50 &&ProbeLife3>=50){

lcd.setCursor(0,0);

lcd.print("Probe Condition  ");

lcd.setCursor(0,1);

lcd.print("Good            "); }

 

 

if(ProbeLife2<50 || ProbeLife2<50 || ProbeLife3<50){

lcd.setCursor(0,0);

lcd.print("Probe Condition   ");

lcd.setCursor(0,1);

lcd.print("Faulty           "); }

 

 

if(millis()%6000 <=3000){

lcd.setCursor(0,0);

lcd.print("Press Right          ");

                                                          

lcd.setCursor(0,1);

lcd.print("To exit               ");

};

 

 

//user pressed right?

if(button==1) break;

delay(100);

       };

   Screen=1;

   return;                                                       

 

 

};

 

 

//******************************* LOGS Min/MAX Values*******************************//

                          void Log_Min_MaxTemp(){

                          

                         

                            if(Temperature>=MaxT) MaxT=Temperature;

                            if(Temperature<=MinT) MinT=Temperature;

                                              

                                                

                          };

 

 

//******************************* LOGS Min/MAX Values*******************************//

                          void Log_Min_MaxPH(){

                          

                         

                            if(phValue>=MaxPH) MaxPH=phValue;

                            if(phValue<=MinPH) MinPH=phValue;

                                              

                                                

                          };

 

 

 

 

 

 

void PrintReadings(){

              

                Serial.print("pH: "); 

                Serial.print(phValue);

                Serial.print(Temperature);

                Serial.println(" *C  ");

                Serial.print("mv: "); 

                Serial.print(mvReading);

                Serial.print("   mvPh7: ");

                Serial.print(mvReading_7);

                 Serial.print("   mvPh4: ");

                Serial.println(mvReading_4);

                Serial.print("H1: "); 

                Serial.print(ProbeLife1);

                Serial.print("   H2: ");

                Serial.print(ProbeLife2);

                 Serial.print("H3: "); 

                Serial.println(ProbeLife3);

             

                Serial.print("Slope ");

                Serial.print(Slope);

           

             

                        

                                      //** First Screen Shows Temp and EC **//

                                      if(Screen==1){

                                      lcd.setCursor(0,0);

                                      lcd.print("Arduino pH   ");

                                      lcd.setCursor(0,1);

                                      lcd.print("pH:               ");

                                      lcd.setCursor(3,1);

                                      lcd.print(phValue);

                                      lcd.setCursor(9,1);

                                      lcd.print(Temperature);

                                      lcd.print("'C");

                                      }

                                     

                                     

                                       //**Third Screen Shows Min and Max **//

                                       else if(Screen==2){

                                      lcd.setCursor(0,0);

                                      lcd.print("Min:              ");

                                       lcd.setCursor(4,0);

                                       lcd.print(MinPH);

                                       lcd.setCursor(9,0);

                                      lcd.print(MinT);

                                      lcd.print("'C");

                                      lcd.setCursor(0,1);

                                      lcd.print("Max:               ");

                                      lcd.setCursor(4,1);

                                      lcd.print(MaxPH);

                                      lcd.setCursor(9,1);

                                      lcd.print(MaxT);

                                      lcd.print("'C");

                                      }

                                     

                                     

                                      else if(Screen==6){

                                   

                                      lcd.setCursor(0,0);

                                      lcd.print("Uptime Counter:              ");

                                    

                                      lcd.setCursor(0,1);

                                      lcd.print("                                     ");//Clearing LCD

                                      lcd.setCursor(0,1);

                                      lcd.print(Day);

                                      lcd.setCursor(3,1);

                                      lcd.print("Day");

                                      lcd.setCursor(8,1);

                                      lcd.print(Hour);

                                      lcd.setCursor(10,1);

                                      lcd.print(":");

                                      lcd.setCursor(11,1);

                                      lcd.print(Minute);

                                      lcd.setCursor(13,1);

                                      lcd.print(":");

                                      lcd.setCursor(14,1);

                                      lcd.print(Second);

                                    

                                    

                                       }

                       

                                      else if(Screen==4){

                                      

                                      lcd.setCursor(0,0);

                                      lcd.print("Calibrate pH          ");

                                    

                                    

                                      lcd.setCursor(0,1);

                                      lcd.print("Hold Select            ");

                                   

                                      }

                                      else if(Screen==3){

                                      

                                      lcd.setCursor(0,0);

                                      lcd.print("Probe Health %          ");

                                    

                                    

                                      lcd.setCursor(0,1);

                                      lcd.print("H1:                     ");

                                      lcd.setCursor(3,1);

                                      lcd.print(ProbeLife1);

                                      lcd.setCursor(9,1);

                                      lcd.print("H2:");

                                      lcd.setCursor(12,1);

                                      lcd.print(ProbeLife2);

                                      if(millis()%6000<3000){

                                      lcd.setCursor(0,1);

                                      lcd.print("H3:                "); 

                                      lcd.setCursor(3,1);

                                      lcd.print(ProbeLife3);

                                      }

                                      }

                                    

                                      else if(Screen==5){

                                      

                                      lcd.setCursor(0,0);

                                      lcd.print("Days Since Cal         ");

 

 

                                      lcd.setCursor(0,1);

                                      lcd.print("                       ");

                                      lcd.setCursor(0,1);

                                      lcd.print(Days_Since_Calibration);

                                    

                                      }

                                    

   if((millis()%10000<=2000) && (CalibrationWarning==1)){

 

 

                                      lcd.setCursor(0,0);

                                      lcd.print("Calibrate the          ");

                                      lcd.setCursor(0,1);

                                      lcd.print("Probe                   ");

                                                                

                           };         

 

};

 

 

//************************************* Used For Probe time Since Last Calibration *************************************//

//This wont keep counting if unit has been powered off, so it is only really useful for use when in permanant use

void Day_Change(){

if(Day!=Last_Day){

    Last_Day=Day;

    Days_Since_Calibration++;

    EEPROM.write(addresseCalibrationDays,Days_Since_Calibration);

    if(Days_Since_Calibration>=Cal_Period_Warining) CalibrationWarning=1;

};

 

};

 

 

 

 

//********************** The Section Below will give you a read out of probe Life ****************************************//

//there are three ways we can measure a proble life during calibration:

//1:Asymmetry potential (Eo), the Millivoltes at pH7 [mV reading in pH 7.00 buffer ± 25 mV]

//2:Slope, mv per Ph change [mV reading in pH 7.00 buffer - mV reading in pH 4.00 buffer 160 – 180 mV]

//3:Drift mV reading in pH 4.00 buffer (1 min) – mV reading in pH 4.00 buffer (2 min) ± 1.5 mV  [we are checking for stable readings]

 

 

void ProbeLife_Check_1(){

//Structure, get pH7 mv reading and map life vs mv reading , variables Good value, band for bad reading

//We already just got the mvReading int he calibration function

//map(value, fromLow, fromHigh, toLow, toHigh);

 

 

value=mvReading_7*1000;

if (value>=Healthy1_mv2) ProbeLife1=map(value, Healthy1_mv2, (Healthy1_mv2+Health1_range), 100, 0);

if (value<Healthy1_mv2) ProbeLife1=map(value, Healthy1_mv2, (Healthy1_mv2-Health1_range), 100, 0);

if (ProbeLife1<=1) ProbeLife1=0;

EEPROM.write(addresProbleLife1,ProbeLife1);

};

 

 

void ProbeLife_Check_2(){

//structure compare ph7 mv to ph4 mv , variables  Good value  Band for bad reading

 

 

value=Slope*1000;

if (value>=Healthy2_Slope) ProbeLife2=map(value, Healthy2_Slope,(Healthy2_Slope+ Healthy2_range), 100, 0);

if (value<Healthy2_Slope) ProbeLife2=map(value, Healthy2_Slope,(Healthy2_Slope-Healthy2_range), 100, 0);

if (ProbeLife2<=1) ProbeLife2=0;

EEPROM.write(addresProbleLife2,ProbeLife2);

};

 

 

 

 

void ProbeLife_Check_3(){

//structure, leave probe in ph 4 for 1 minute and then take another average at 2 mins map from 0 drift to 5mv for probe life

Drift=(mvReading_4-mvReading_4_Delayed);

value=Drift*1000;

if (value>=Healthy3_Drift) ProbeLife3=map(value, Healthy3_Drift,(Healthy3_Drift+ Healthy3_range), 100, 0);

if (value<Healthy3_Drift) ProbeLife3=map(value, Healthy3_Drift,(Healthy3_Drift- Healthy3_range), 100, 0);

if (ProbeLife3<=1) ProbeLife3=0;

EEPROM.write(addresProbleLife3,ProbeLife3);

};