// 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; }