I'm building a combined temperature- and pH meter and adjuster for a small lab using inexpensive materials. The pH meter is of the eBay quality, and the measurements pulled from an analogue pin.
This is all pretty straightforward, but I really want to do three-point calibrations using buffer solutions with pH 4.01, 6.86 and 9.18 respectively.
My math knowledge doesn’t extend to making linear regression models myself, but I found some code online to get me started, from here: https://www.instructables.com/PH-RegulaterMeter-Arduino/.
It starts by making measurements from the buffer solutions and save those in three different variables, thus:
(The original code is littered with LCD commands, which I erased. It’s also using buffer solutions with pH 4,7 and 10, which I changed to my values).
for (double i=100; i>0; i--) //read values for 10 seconds (the pH measuring function contains a 10 msek delay)
{
readPH(); //read current pH value
pH4.01val = pHvalue; //set equal to variable for this pH
}
I don’t know why the original code reads the electrode 100 times when it only saves the last measurement to the variable. I guess it’s giving the electrode time to adjust.
Anyway, the output is three variables: pH4.01val, pH6.86val and pH9.18val.
These are then used to calculate slope and offset:
slope = 5.17 /(pH9.18val - pH4.01val); //System of equations to make each reading equal pH 4.01 & 9.18 respectively shown below:
// 9.18=(pH9.18val*slope)+offset - 4.01=(pH4.01val*slope)+offset
//This system of equations creates a straight line trend for all pH readings
offset = (abs(10.87 - ((pH4.01val + pH6.86val)*slope)))/2; //S.O.E. using point at pH 6.86 and pH4.01/9.18 slope to ensure a best fit, below:
// 4.01=(pH4.01val*slope)+offset + 6.86=(pH6.86val*slope)+offset
//slope and offset solved to create best fit line approximation
And I understand what’s happening so far, somewhat. It’s the next part of the code that vexes me:
offset2 = slope*2.97; //multiply by old offset value, new slope times old offset
slope = 0.59*slope; //new slope * old slope... "offset2" and new "slope" are used for the following:
//calibrated pH = (old slope*3.5*pHvalue + old offset)*new slope + new offset
// = (old pH reading)*slope + offset
//see 'readPH()' for application of this equation
if ((pH4.01val + pH6.86val) > 10.87) //if total of pH4 and pH7 reading is greater than 11
{
negative = 1; //set negative to hold value of 1 to change algorithm of pHvalue..offset is < 0
}
THIS IS MY ACTUAL QUESTION:
What are those numbers 2.97 and 0.59?! Where did they come from? The comments say something about “old” offset and “new” slope, but those are just numbers and not saved variables?
All this is then used to correct the measurements in this way:
if (negative == 0) //if the offset is positive... see calibration subroutine.. negative is initialized as 0
{
pHvalue = (slope*3.5*pHvalue + offset + offset2); //convert the millivolt into pH value, with positive offset and slope from calibration
}
else
{
pHvalue = (slope*3.5*pHvalue - offset + offset2); //convert the millivolt into pH value, with negative offset and slope from calibration
}
Again, I don’t really get the use of the “offset2” variable. I might just be too dumb, but I would love to use this code if only I understood how it works. Does anyone? Can you help me understand those numbers in the calibration part and the use of the offset2 variable?
The full original code is available for download through the Instructables link above.

