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!