Average rainfall 2001-2016, global tropics

Map: Average rainfall 2001-2016, global tropics

module: pH meter - DFRobot

Introduction

This is the first of three pH meters that I tested for Arduino. The pH meter in this article is the (same as the) DFRobot, Gravity: Analog pH Sensor / Meter Kit For Arduino. But I got my copy from Amazon.se. The control board (breakout board) is constructed for 5 volt power (Vin = 5). The pH meter in the next post can be calibrated also for Vin = 3.3.

DFRobot, Gravity: Analog pH Sensor / Meter Kit For Arduino

Online manuals

I found instructions and code for this exact model posted by Electronic clinic on their own web page both on Youtube and also as a Youtube instruction.

Wiring

The wiring is very easy as the pH-meter comes with a prepared contact with only three wires, power, ground and an analog signal (see figure above).

Sketch

The simple sketch below is supplied by Electronic clinic:

#define SensorPin A2          // the pH meter Analog output is connected with the Arduino’s Analog
unsigned long int avgValue;  //Store the average value of the sensor feedback
float b;
int buf[10],temp;

void setup()
{
  Serial.begin(9600);  
  Serial.println("Ready");    //Test the serial monitor
}
void loop()
{
  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  {
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt

  Serial.print("    raw pH:");  
  Serial.print(phValue,2);
  phValue=3.5*phValue;                      //convert the millivolt into pH value

  Serial.print("    calibrated pH:");  
  Serial.print(phValue,2);
  Serial.println(" ");

}

Seeed stduio offers a more advanced code for a similar ph_meter. This code also contains a calibration Offset parameter, and the manual also states how to set the linear equation slope.

/*
  # This sample code is used to test the pH meter V1.1.
  # Editor : YouYou
  # Date   : 2014.06.23
  # Ver    : 1.1
  # Product: analog pH meter
  # SKU    : SEN0161
*/
#define SensorPin A2            //pH meter Analog output to Arduino Analog Input 0
#define Offset 41.02740741      //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
#define uart  Serial
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;
void setup(void)
{
  pinMode(LED, OUTPUT);
  uart.begin(9600);
  uart.println("pH meter experiment!");    //Test the uart monitor
}
void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue, voltage;
  if (millis() - samplingTime > samplingInterval)
  {
    pHArray[pHArrayIndex++] = analogRead(SensorPin);
    if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
    voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
    pHValue = -19.18518519 * voltage + Offset;
    samplingTime = millis();
  }
  if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    uart.print("Voltage:");
    uart.print(voltage, 2);
    uart.print("    pH value: ");
    uart.println(pHValue, 2);
    digitalWrite(LED, digitalRead(LED) ^ 1);
    printTime = millis();
  }
}
double avergearray(int* arr, int number) {
  int i;
  int max, min;
  double avg;
  long amount = 0;
  if (number <= 0) {
    uart.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;
}

Calibration

The core translation from the analog signal to initial pH is similar for all analog pH meters used with Arduino. In the first step the analog signal is translated to voltage:

voltage = signal * Vin / 1024

The DFRobot pH-meter used in this article require 5 volt as Vin, and the conversion to voltage registered by the analog port thus becomes:

voltage = signal * 5.0 / 1024

Most pH-meters also have linear responses between pH and analog voltage output (registered by the Arduino analog port), and the actual pH value is thus calculated as a linear conversion:

pH-value = votage*ScaleFac + Offset

The two sketches above use greatly different values for ScaleFac and Offset:

Sketch ScaleFac Offset
Electronic clinic 3.5 0
DFRobot -19.18518519 41.02740741

Setting ScaleFac and Offset requires solving a linear equation and retrieving the slope (ScaleFac) and intercept (Offset) in two steps:

ScaleFac = (PH2-PH1)/(V2-V1)

Offset = [(PH2+PH1)-ScaleFac*(V1+V2)]/2

This of course requires testing the pH meter against two liquids with a priori known pH.

Resources

DFRobot, Gravity: Analog pH Sensor / Meter Kit For Arduino.

Electronic clinic text manual.

Electronic clinic youtube manual.