PH sensorCalibration Issue - Same Voltage for pH 4.0 and pH 7.0

Hi everyone,

I’m working on a project with a pH sensor and an Arduino. During calibration, the voltages measured for the pH 7.0 and pH 4.0 buffer solutions are the same (e.g., around 2.48V). Because of this, I can’t calculate the correct slope and offset.
This is the code I’m using :
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Initialiser l'écran LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adresse I2C : 0x27, 16 colonnes, 2 lignes

#define SensorPin A0 // Broche analogique connectée au capteur de pH

float slope = -5.70; // Valeur initiale de la pente (sera ajustée lors de la calibration)
float offset = 21.34 + 0.7; // Valeur initiale de l'offset (sera ajustée lors de la calibration)

unsigned long int avgValue; // Stocke la valeur moyenne du capteur
int buf[10], temp;

void setup() {
pinMode(SensorPin, INPUT);

// Initialiser l'écran LCD I2C
lcd.init();
lcd.backlight(); // Activer le rétroéclairage
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome To");
lcd.setCursor(0, 1);
lcd.print(" pH Meter");
delay(2000);
lcd.clear();

Serial.begin(9600); // Activer le moniteur série pour la calibration

// Effectuer la calibration
calibrate();
}

void loop() {
// Lire 10 échantillons pour lisser la valeur
for (int i = 0; i < 10; i++) {
buf[i] = analogRead(SensorPin);
Serial.print("Raw Value: ");
Serial.println(buf[i]);
delay(10);
}

// Trier les valeurs pour éliminer les valeurs aberrantes
for (int i = 0; i < 9; i++) {
for (int j = i + 1; j < 10; j++) {
if (buf[i] > buf[j]) {
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}

// Calculer la moyenne des 6 valeurs centrales
avgValue = 0;
for (int i = 2; i < 8; i++) avgValue += buf[i];
float voltage = (float)avgValue * 5.0 / 1024 / 6; // Convertir en tension (0-5V)
Serial.print("Voltage: ");
Serial.println(voltage);

// Calculer le pH à partir de la formule calibrée
float phValue = (slope * voltage) + offset;
Serial.print("Calculated pH: ");
Serial.println(phValue);

// Afficher la valeur du pH sur l'écran LCD
lcd.setCursor(0, 0);
lcd.print(" pH Value: ");
lcd.print(phValue, 2); // Afficher avec 2 décimales
lcd.print(" ");

// Afficher la description qualitative du pH
lcd.setCursor(0, 1);
if (phValue < 4) lcd.print(" Very Acidic ");
else if (phValue >= 4 && phValue < 5) lcd.print(" Acidic ");
else if (phValue >= 5 && phValue < 7) lcd.print(" Acidic-ish ");
else if (phValue >= 7 && phValue < 8) lcd.print(" Neutral ");
else if (phValue >= 8 && phValue < 10) lcd.print("Alkaline-ish ");
else if (phValue >= 10 && phValue < 11) lcd.print(" Alkaline ");
else if (phValue >= 11) lcd.print("Very alkaline");

delay(1000); // Mettre à jour toutes les secondes
}

// Fonction de calibration dynamique
void calibrate() {
Serial.println("Place the sensor in pH 7.0 buffer solution and press any key...");
while (!Serial.available()) {} // Attendre que l'utilisateur appuie sur une touche
Serial.read(); // Vider le tampon série

// Mesurer la tension pour pH 7.0
float voltage_pH7 = readVoltage();
Serial.print("Voltage at pH 7.0: ");
Serial.println(voltage_pH7);

Serial.println("Place the sensor in pH 4.0 buffer solution and press any key...");
while (!Serial.available()) {}
Serial.read();

// Mesurer la tension pour pH 4.0
float voltage_pH4 = readVoltage();
Serial.print("Voltage at pH 4.0: ");
Serial.println(voltage_pH4);

// Calculer la pente et l'offset
slope = (7.0 - 4.0) / (voltage_pH7 - voltage_pH4);
offset = 7.0 - (slope * voltage_pH7);

Serial.print("Calibration complete! Slope: ");
Serial.print(slope);
Serial.print(", Offset: ");
Serial.println(offset);
}

// Fonction pour lire la tension stabilisée
float readVoltage() {
unsigned long int avgValue = 0;
int buf[10], temp;

// Lire 10 échantillons pour lisser la valeur
for (int i = 0; i < 10; i++) {
buf[i] = analogRead(SensorPin);
delay(10);
}

// Trier les valeurs pour éliminer les valeurs aberrantes
for (int i = 0; i < 9; i++) {
for (int j = i + 1; j < 10; j++) {
if (buf[i] > buf[j]) {
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}

// Calculer la moyenne des 6 valeurs centrales
for (int i = 2; i < 8; i++) avgValue += buf[i];
return (float)avgValue * 5.0 / 1024 / 6; // Convertir en tension (0-5V)
}

I’ve already checked:

  • The connections (everything seems fine).
  • The buffer solutions (they’re fresh and high-quality).
  • The sensor is fully submerged and rinsed with distilled water between measurements.

Does anyone have an idea what might be causing this? Could it be a problem with the code, the sensor, or something else?

Thanks for your help!

Please edit your post to add code tags and to the follow the forum rules. Post links to all the components, especially the pH sensor and calibration solutions, and post a wiring diagram.

See the "How to get the best out of this forum" post for guidelines (linked at the head of every forum category).

First, read this post and learn how to properly post your code with Code Tags:

Second:

If you're using a bare pH sensor connected directly to an Arduino analog input, I doubt you'll ever get it to work satisfactorily. Those sensors have extremely high output impedance and require a special amplifier with high input impedance. Very carefully electrical design and circuit layout are required to get them to work well.

Thank you very much for your reply. I truly appreciate your help. I will make sure to follow this instruction next time. This is my first time, so I sincerely thank you

In the IDE, click on Edit, then Copy for Forum, that will copy your code for pasting on this forum. Then come back here and do a simple paste. That will paste you code in a new window with scroll bars.