// efter Mikael Björnson, Arduinobubblan, 2022-08-31
float slope = 0.0; // slope variable for the pH adjustment, set to zero at start
float offset; // offset variable for the pH adjustment
int pHpin = 8;
// storing the values once for multiple use
const float cal_pH[3] = {4.01, 6.86, 9.18};
void setup()
{
pinMode(pHpin,INPUT);
}
void loop()
{
// if the calibration button is pressed or slope is zero, start calibration function
if ((slope == 0.0) || (calibration_button_pressed))
{
pHcalibration();
}
//every 2 seconds, poll the sensor
read_pH();
}
float read_pH()
{
return slope * read_raw() + offset;
}
float read_raw()
{
float avg[10];
for (int i=0; i<10; i++) // take 10 readings from the sensor during 100 ms. Store them in an array.
{
avg[i] = analogRead(pHpin);
delay(10);
}
for (int i=0; i<9; i++) //sorting the readings from low to high
{
for (int j=i+1; j<10; j++)
{
if (avg[i] > avg[j])
{
float temp = avg[i];
avg[i] = avg[j];
avg[j] = temp;
}
}
}
float avgVal = 0;
for (int i=2; i<8; i++) // get the total of the 6 middle values.
{
avgVal += avg[i];
}
return avgVal / 6; // we don't even need to divide by 6 if we do it the same way during calibration and measurement
}
void pHcalibration()
{
//press button when calibration setup is complete for pH cal_pH[0]
float cal1 = read_raw();
//press button when calibration setup is complete for pH cal_pH[1]
float cal2 = read_raw();
//press button when calibration setup is complete for pH cal_pH[2]
float cal3 = read_raw();
// linear least-square fit
float sumVal = cal1 + cal2 + cal3;
float sumCal = cal_pH[0] + cal_pH[1] + cal_pH[2];
float sumValSquare = pow(cal1,2) + pow(cal2,2) + pow(cal3,2);
float sumProd = cal1*cal_pH[0] + cal2*cal_pH[1] + cal3*cal_pH[2];
float slope = (3*sumProd - sumVal * sumCal) / (3*sumValSquare - pow(sumVal,2));
float offset = (sumCal - slope * sumVal) / 3;
}
Comments