ArduinoGeneral

Analog TDS sensor & PH sensor V2

userHead mati_4004 2019-09-05 06:28:25 4533 Views3 Replies
Hello,

I have these two sensors installed to my arduino mega, but PH goes crazy after i measure the TDS sensor

This is the layout im using (left part) https://drive.google.com/file/d/1BehWn0 ... UixdN/view

I use 4 transistors to isolate positive and ground wires from the TDS sensor when im using the PH and the other way as well. Problem is, after i read the TDS it seems something happens in the water and the PH probe gets crazy..... the analog reading from the PH probe should be arround 250-350 and it goes to 50-90.

I tried everything, don't know what more i can do.... have you used TDS and PH probes at the same time?



Code: Select all
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>


///////////TDS//////////
#define TdsSensorPin A14
#define VREF 5.0      // analog reference voltage(Volt) of the ADC
#define SCOUNT  5           // sum of sample point
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0, copyIndex = 0;
float averageVoltage = 0, tdsValue = 0;

//////////PH////////////
#define SensorPin A13            //pH meter Analog output to Arduino Analog Input 0
#define TDSoffset 0
#define Offset 3            //deviation compensate
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
#define ph2 6.3
#define ph1 7.5
#define v2 1.46
#define v1 1.60
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;
bool AutoPH = false;
 int j = 0;
int analogBuffer2[SCOUNT];    // store the analog value in the array, read from ADC
int analogBufferTemp2[SCOUNT];
int analogBufferIndex2 = 0, copyIndex2 = 0;
float averageVoltage2 = 0;
/////////TDS&PH ON OFF/////////
#define measureInterval 30000
#define TDSPin 51           //TDS meter for on/off
#define PhPin 49            //pH meter for on/off

///////////Temperatura  //////////
OneWire ourWire1(42);  // Sensor temperatura
DallasTemperature sensors1(&ourWire1); //Se declara una variable u objeto para nuestro sensor1

/////////LCD//////////////////
// 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;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int 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) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;
  return btnNONE;  // when all others fail, return this...
}



void setup(void)
{
  sensors1.begin(); // Temperatura

  pinMode(TdsSensorPin, INPUT);
  pinMode(PhPin, OUTPUT); //PH off and on
  pinMode(TDSPin, OUTPUT); //TDS off and on
  digitalWrite(PhPin, 1);
  digitalWrite(TDSPin, 0);
  Serial.begin(9600);
  Serial.println("pH meter experiment!");    //Test the serial monitor
  lcd.begin(16, 2);              // start the library
}
void loop(void)
{
 
  static unsigned long samplingTime, samplingTime2, measureTime  = millis();
  static unsigned long printTime = millis();
  static float pHValue, voltage, TDSValue, voltage2;

  sensors1.requestTemperatures();   //Se envía el comando para leer la temperatura
  float temp1 = sensors1.getTempCByIndex(0); //Se obtiene la temperatura en ºC del sensor 1

        if(millis()- measureTime > measureInterval )
    {
        if(j == 0)
        {
          j = 1;
          digitalWrite(TDSPin,0);
          delay(1000);
          digitalWrite(PhPin,1);
          delay(5000);
          measureTime=millis();
        } 

    }
     if(millis()- measureTime > measureInterval)
        { 
         if(j == 1)
         {
          j = 0;
          digitalWrite(PhPin,0);
          delay(1000);
          digitalWrite(TDSPin,1);
          measureTime=millis();
        }
       
    }
  
    if(millis()-samplingTime > samplingInterval && digitalRead(PhPin) == 1)
    {
        pHArray[pHArrayIndex++]=analogRead(SensorPin);
        if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
        voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
        pHValue = (ph2-ph1)/(v2-v1)*(voltage-v2)+ph2;
        samplingTime=millis(); 
  
    }
   static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 5000 && digitalRead(TDSPin) == 1 )  //every 40 milliseconds,read the analog value from the ADC
  {
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
    analogBufferIndex++;
    if (analogBufferIndex == SCOUNT)
      analogBufferIndex = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U)
  {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficient = 1.0 + 0.02 * (temp1 - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value
    Serial.print("voltage:");
    Serial.print(compensationVolatge, 2);
    Serial.print(" TDS Value:");
    Serial.print(tdsValue, 0);
    Serial.print("ppm ");
  }





  if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    Serial.print("VPH   ");
    Serial.print(voltage, 4);
        Serial.print(" Analogico   ");
    Serial.print(analogRead(A13));
    Serial.print(" PH Value:");
    Serial.println(pHValue, 0);
    lcd.setCursor(10, 0);
    lcd.print("T:"); // print a simple message
    lcd.setCursor(12, 0);           // move to the begining of the second line
    lcd.print(analogRead(A13));  // read the buttons
    lcd.setCursor(0, 0);
    lcd.print("PH:"); // print a simple message
    lcd.setCursor(3, 0);           // move to the begining of the second line
    lcd.print(pHValue);  // read the buttons
    lcd.setCursor(0, 1);
    lcd.print("TDS:"); // print a simple message
    lcd.setCursor(4, 1);           // move to the begining of the second line
    lcd.print(tdsValue);  // read the buttons
    printTime = millis();
  }

  // lcd.setCursor(0,1);            // move to the begining of the second line
  // if(AutoPH=false)lcd.print("OFF");
  // if(AutoPH=true)lcd.print("ON");
  lcd_key = read_LCD_buttons();  // read the buttons

  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
    case btnRIGHT:
      {

        break;
      }
    case btnLEFT:
      {

        break;
      }
    case btnUP:
      {

        break;
      }
    case btnDOWN:
      {

        break;
      }
    case btnSELECT:
      {
        AutoPH = !AutoPH;
        break;
      }
    case btnNONE:
      {
        break;
      }
  }

}
double avergearray(int* arr, int number) {
  int i;
  int max, min;
  double avg;
  long amount = 0;
  if (number <= 0) {
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if (number < 5) { //less than 5, calculated directly statistics
    for (i = 0; i < number; i++) {
      amount += arr[i];
    }
    avg = amount / number;
    return avg;
  } else {
    if (arr[0] < arr[1]) {
      min = arr[0]; max = arr[1];
    }
    else {
      min = arr[1]; max = arr[0];
    }
    for (i = 2; i < number; i++) {
      if (arr[i] < min) {
        amount += min;      //arr<min
        min = arr[i];
      } else {
        if (arr[i] > max) {
          amount += max;  //arr>max
          max = arr[i];
        } else {
          amount += arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount / (number - 2);
  }//if
  return avg;
}
int getMedianNum(int bArray[], int iFilterLen)
{
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++)
  {
    for (i = 0; i < iFilterLen - j - 1; i++)
    {
      if (bTab[i] > bTab[i + 1])
      {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}
2019-09-12 18:47:21 The tds meter(SEN0244), as well as the EC meter(DFR0300 or DFR0300-H) will send the electronic signal into the liquid when they are working, so if the tds meter and the EC meter powered by the same power supply, that is, common ground, the TDS probe will influence the chemical reaction of the pH probe, leading to pH probe works unstably.
You need to avoid the same power supply, if you want use them meanwhile. The analog isolator is a good solution. Please check it on this link: https://www.dfrobot.com/product-1621.ht ... ption=true
One analog isolator is enough, to isolate the TDS meter.
userHeadPic Youyou
2019-09-05 07:08:56 So i figured out that it does not matter if a turn on the TDS sensor, the problem is when i do an analogRead, it seems that reading changes the water, and therefore, the PH reading.... and it takes a while (+10min) to get a good reading again

Any suggestion?
userHeadPic mati_4004