¿como filtrar la señal analogica de la sonda de ph?

Buenos días, y felices fiestas
ante todo mi nivel de programación deja mucho que desear.
Estoy intentando hacer un programa para controlar un acuario, (bueno si no muero antes).
de momento estoy con la sonda de ph y su modulo PH-4502C
https://images.app.goo.gl/GESHxHqgsAqy5yfs5

pero el problema es que las lecturas de los búferes me la realiza bien y tiene muy pocas fluctuaciones, pero al introducirlo en el acuario, se desmadran las lecturas valores incluso negativos. Os pongo una muestra del sondeo.

13:38:45.615 -> Medida: 525.40 PH: 6.2
13:38:45.650 -> PH_int: 20
13:38:46.718 -> Medida: 521.95 PH: 8.6
13:38:46.753 -> PH_int: 22
13:38:47.826 -> Medida: 525.45 PH: 14.4
13:38:47.860 -> PH_int: 112
13:38:48.930 -> Medida: 506.35 PH: 7.3
13:38:48.965 -> PH_int: 21
13:38:50.041 -> Medida: 523.35 PH: 7.3
13:38:50.041 -> PH_int: 21
13:38:51.145 -> Medida: 540.80 PH: 3.4
13:38:51.145 -> PH_int: 10
13:38:52.220 -> Medida: 506.45 PH: 8.6
13:38:52.254 -> PH_int: 22
13:38:53.323 -> Medida: 484.50 PH: 16.4
13:38:53.359 -> PH_int: 121
13:38:54.428 -> Medida: 485.05 PH: 6.7
13:38:54.464 -> PH_int: 20
13:38:55.536 -> Medida: 520.15 PH: 5.4
13:38:55.570 -> PH_int: 12
13:38:56.637 -> Medida: 543.10 PH: 2.1
13:38:56.672 -> PH_int: 2
13:38:57.743 -> Medida: 508.10 PH: 7.7
13:38:57.779 -> PH_int: 21
13:38:58.848 -> Medida: 514.75 PH: 8.1
13:38:58.883 -> PH_int: 22
13:38:59.951 -> Medida: 533.45 PH: 9.9
13:38:59.986 -> PH_int: 100

No estoy seguro que sea un problema de ruidos electricos, en la urna tengo un calentador eheim mas el filtro externo eheim y una lampara de led china.

he probado de hacer las lecturas con todos los compoenentes desconectados de la corriente pero sigo teneiendo fluctuaciones muy elevadas.

os pongo el codigo pero es lo que os comento las fluctuaciones cuando hago el auto calibrado y uso los buffers no tengo apenas variaciones.

os pongo el codigo en el siguiente porque la pagina no me deja incluirlo en el anterior

///////////////////////////////
// Control Acuario SONDA PH  //
///////////////////////////////
/* Modelo prueba de PH con autoCalibracion
 *  grabación de los valores de calibración en la EEprom de arduino.
 *  posiblemente utilice una SDcard para liberar la EEPROM 
 */
 ///LIBRERIAS
#include <EEPROM.h>
 
//VARIABLES PARA LAS SONDAS
double ValorPH4;       // 622.30 valor mediante el programa    617.60 es teoricamente el valor para ph4
double ValorPH7;       // 517.45 valor mediante el programa    512 es teoricamente el valor para ph7  
int PinSondaPh = A1;   //entrada señal del modulo PH-4502C 
float medidaSondaPH;   //#measure# donde se guarda la lectura de la SondaPH
float promedioSondaPH; // #prom# guarda el promedio de la la lectura de la SondaPH
float PH;              // #Po# calculamos el valor del PH

//VARIABLES CONTROL FLUJO
int a = 0, b=0,c=0;
int a1,a2;
int b1,b2;
boolean Calibracion_PH_Ok;
int estado_pin_Pulsador_SI;
int estado_pin_Pulsador_NO;
int estadoPulsador_OK;
int ControlCicloCalibradoPH4;
int ControlCicloCalibradoPH7;
int controL_while_calibrarSI_NO=0;

//asignacion pines a botones
const int pin_Pulsador_SI = 10;
const int pin_Pulsador_NO = 11;
const int pinPulsador_OK =12;



//##################################################################
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
  pinMode(pinPulsador_OK,INPUT);
  pinMode(pin_Pulsador_SI,INPUT);
  pinMode(pin_Pulsador_NO,INPUT);
  pinMode(PinSondaPh,INPUT);
Serial.print( "pin_Pulsador_SI  ");
Serial.println( digitalRead(pin_Pulsador_SI));
Serial.print( "pin_Pulsador_NO  ");
Serial.println( digitalRead(pin_Pulsador_NO));
Serial.print( "pinPulsador_OK  ");
Serial.println( digitalRead(pinPulsador_OK));


}



//##################################################################
////////////////////////////////////
//       Funcion LOOP      /////////
///      INICIO FUNCION   //////////
////////////////////////////////////////////////////////////////////
void loop() {
  
if(a==0){
  Serial.println("estoy en el loop");   //Para saber por donde anda el programa
  delay (1000);
  a= a+1;
  }
  if(EEPROM.get(20, Calibracion_PH_Ok)==0){
    while(EEPROM.get(20, Calibracion_PH_Ok)==0){ 
      if(a1==0){
      Serial.println(EEPROM.get(20, Calibracion_PH_Ok));
       Serial.println("Hay que calibrar la sonda PH, pulsa Calibrar");
       Serial.println("Pulsa OK");
       delay (1000);
       a1= a1+1;
       }
    estadoPulsador_OK = digitalRead(pinPulsador_OK);
    while (estadoPulsador_OK ==1)
  {//Iniciacion(); 
  }
}
  }
if (controL_while_calibrarSI_NO==0){
   while (EEPROM.get(20, Calibracion_PH_Ok)== 1 && (controL_while_calibrarSI_NO)==0){
     if(a1==0){
      Serial.print ("EEPROM.get(20, Calibracion_PH_Ok)   ");
      Serial.println (EEPROM.get(20, Calibracion_PH_Ok));
      Serial.print("EEPROM.get(0, ValorPH4)   ");
      Serial.println(EEPROM.get(0, ValorPH4));
      Serial.print("EEPROM.get(10, ValorPH7)   ");
      Serial.println(EEPROM.get(10, ValorPH7));
       Serial.println("¿Quieres calibrar la sonda PH, pulsa SI o NO?");
        estado_pin_Pulsador_SI=0;
       delay (1000);
              a1= a1+1;
       }
        while( digitalRead(pin_Pulsador_SI)){
             SI_quiero_calibrar_PH();
             controL_while_calibrarSI_NO=1;
             break;
           }
        while( digitalRead(pin_Pulsador_NO)&&(controL_while_calibrarSI_NO)==0){
            NO_quiero_calibrar_PH();
            Serial.println("estamos en no_quiero_calibrar_PH del loop");
            Serial.print ("Calibracion_PH_Ok  ");
            Serial.println (Calibracion_PH_Ok);
            controL_while_calibrarSI_NO=1;
           break;
          }
     // break;
      }
}
/* lectura_del_Ph();
while( estado_pin_Pulsador_NO ==1)
 {
  if (b2>=1){
 // Iniciacion(); 
  b2=b2+1;
  }
 }*/


LoopNormal:
//siguientes acciones
if(Calibracion_PH_Ok==1){
lectura_del_Ph(); 
}
}


//##################################################################
/////////////////////////////////////
//     SI_quiero_calibrar_PH ///
///      INICIO FUNCION     /////////
/////////////////////////////////////////////////////////////////////////////////////////
void SI_quiero_calibrar_PH(){
  ValorPH4=0;
  ValorPH7=0;
  EEPROM.put(0, ValorPH4);
  EEPROM.put(10, ValorPH7);
  
 Serial.println("estamos en SI_quiero_calibrar_PH");
 Serial.println("ValorPH4");
 Serial.println(EEPROM.get(0, ValorPH4));
  Serial.println("ValorPH7");
 Serial.println(EEPROM.get(10, ValorPH7));
 Iniciacion();
 Serial.println("hemos vuelto de inciacion a SI_quiero_calibrar_PH");
 loop();
}



//##################################################################
/////////////////////////////////////
//     NO_quiero_calibrar_PH ///
///      INICIO FUNCION     /////////
/////////////////////////////////////////////////////////////////////////////////////////
void NO_quiero_calibrar_PH()
{
   Serial.println("estamos en NO_quiero_calibrar_PH");

}



//##################################################################
/////////////////////////////////////
//     Funcion calculo PH   /////////
///      INICIO FUNCION     /////////
/////////////////////////////////////////////////////////////////////////////////////////
void lectura_del_Ph(){                                                                 
      float medidaSondaPH = 0;                                                          
      float promedioSondaPH = 0;                                                       
          for(int i=0;i<20;i++)                                               
            {                                                                 
             medidaSondaPH = analogRead(PinSondaPh);
             promedioSondaPH =promedioSondaPH + medidaSondaPH;
              delay(50);
              }
        promedioSondaPH = promedioSondaPH / 20;
        Serial.print("Medida: ");
        Serial.print(promedioSondaPH );
        float PH = 7 + ((medidaSondaPH - ValorPH7 ) * 3 / (ValorPH7 - ValorPH4 ));
        int PH_int = PH;
        Serial.print("\tPH: ");
        Serial.print(PH, 1);
        Serial.println("");
        Serial.print("\tPH_int: ");
        Serial.print(PH_int, 3);
        Serial.println("");
        delay(100);
     }


//##################################################################
//////////////////////////////////////////
///    Funcion Calibracion Auto  /////////
///        INICIO FUNCION        /////////
/////////////////////////////////////////////////////////////////////
float LecturaSondaPh_calibracion(){
  
   float medidaSondaPH = 0;
     float promedioSondaPH = 0;
    float PH;
       for(int i=0;i<20;i++){  
        medidaSondaPH = analogRead(PinSondaPh);
        promedioSondaPH = promedioSondaPH + medidaSondaPH;
        delay(50);
       }

  promedioSondaPH = promedioSondaPH/20;
  Serial.print("Medida: ");
  Serial.println(promedioSondaPH);
double voltage = 5 / 1023.0 * promedioSondaPH; //Digital to Analog conversion
  Serial.print("\tVoltage: ");
  Serial.println(voltage, 2);
return promedioSondaPH;
}



//##################################################################
///////////////////////////////////////////////
///    Funcion Calibracion Valor PH7  /////////
///           INICIO FUNCION          /////////
/////////////////////////////////////////////////////////////////////
void CalibrarValorPH7() {   //calibramos el valor de ph7
  ValorPH7 = LecturaSondaPh_calibracion();  //se ha de poner otro salto para hacer una lectura entrada analogica y cálculos
  EEPROM.put(10, ValorPH7);      // almacena en direccion cero el punto flotante
  Serial.print("ValorPH7 en EEPROMM    ");
  Serial.println(EEPROM.put(10, ValorPH7));// obtiene valor de punto flotante
  Serial.print("valor de PH7=  ");
  Serial.println(ValorPH7);
  estadoPulsador_OK =0;
  Serial.print ("calibracionValorPH7, valor del pulsador =   ");
  Serial.println (estadoPulsador_OK);
}
//##################################################################
///////////////////////////////////////////////
//     Funcion Calibracion Valor PH4  /////////
///             INICIO FUNCION        /////////
/////////////////////////////////////////////////////////////////////
float CalibrarValorPH4() {     //calibramos el valor de ph4
  ValorPH4 = LecturaSondaPh_calibracion();  //se ha de poner otro salto para hacer una lectura entrada analogica y cálculos
  EEPROM.put(0, ValorPH4);      // almacena en direccion cero el punto flotante
  Serial.print("ValorPH4 en EEPROMM    ");
  Serial.println(EEPROM.put(0, ValorPH4));// obtiene valor de punto flotante
  Serial.print("valor de PH4=  ");
  Serial.println(ValorPH4);
  return ValorPH4;
  estadoPulsador_OK =0;
  Serial.print ("calibracionValorPH4, valor del pulsador =   ");
  Serial.println (estadoPulsador_OK);
  Serial.println("Calibracion ValorPH4, completada pulsa de nuevo el pulsador");
}



//##################################################################  
///////////////////////////////////////////////
//     Funcion INICIALIZACION         /////////
///             INICIO FUNCION        /////////
/////////////////////////////////////////////////////////////////////

void Iniciacion(){ // comenzamos mirando si las variables son diferentes a cero
   estadoPulsador_OK=0;
   estado_pin_Pulsador_SI=0;
   b1=0;
   if(b1==0){
  Serial.println("Iniciacion");
     b1 = b1+1;
         delay(10);
         
         estadoPulsador_OK= digitalRead(pinPulsador_OK);
         
        Serial.println("Iniciacion pasamos de la cabecera");
          b1 = b1+1;
         }
         while((digitalRead(pinPulsador_OK))==0);{
         Serial.println("Iniciacion pasamos de la cabecera");
         Serial.println("introduce la sonda en ph4, espera 2 minutos y pulsa OK");
         }
   while((ValorPH4 )==0 && (digitalRead(pinPulsador_OK))==1){
      if(b==0){
         Serial.println();
         Serial.println();
         Serial.println("introduce la sonda en ph4, espera 2 minutos y activa el pulsador");
         Serial.print("el pulsador esta  ");
         Serial.println(estadoPulsador_OK);
         estadoPulsador_OK=0;
        ControlCicloCalibradoPH4 = 0; 
         b = b+1;
       }
       delay(1000);
       estadoPulsador_OK=0;
       estadoPulsador_OK=digitalRead(pinPulsador_OK);
          while((digitalRead(pinPulsador_OK))==0);{
         estadoPulsador_OK=digitalRead(pinPulsador_OK);
          while((ValorPH4)==0 && (digitalRead(pinPulsador_OK))==1){
             Serial.println("empiezo la calibración ph4, un momento");
             estadoPulsador_OK=0;
             delay(1000);
             CalibrarValorPH4();
             Serial.println("he vuelto de calibrar PH4");   
             Serial.println("VALOR DE PH7"); 
             Serial.println(ValorPH7);
             ControlCicloCalibradoPH4 = 1; }      
         if(c==0){
          estadoPulsador_OK=0;
          Serial.println();
          Serial.println();
          Serial.println("introduce la sonda en ph7, espera 2 minutos y activa el pulsador");
          Serial.print("el pulsador esta  ");
          Serial.println(estadoPulsador_OK);         
          c= c+1;
         }
         delay(1000);
         estadoPulsador_OK=0;
         estadoPulsador_OK=digitalRead(pinPulsador_OK);
         
         while((digitalRead(pinPulsador_OK))==0);
          Serial.println("VALOR DE PH7"); 
             Serial.println(ValorPH7);
      while((ValorPH7)==0 || (estadoPulsador_OK)==1){
        Serial.println("empiezo la calibración ph7, un momento");
        estadoPulsador_OK=0;
        delay(1000);
        CalibrarValorPH7();
        Calibracion_PH_Ok=1;
        EEPROM.put(20, Calibracion_PH_Ok);      // almacena en direccion cero el punto flotante
       Serial.print("Calibracion_PH_Ok en EEPROMM    ");
        Serial.println(EEPROM.put(20, Calibracion_PH_Ok));// obtiene valor de punto flotante
        
        Serial.print("Calibracion_PH_Ok    ");
        Serial.println(Calibracion_PH_Ok);
        Serial.println("la calibración se ha completado");
    estadoPulsador_OK=0;
        }
   
   }//Serial.println("se ha terminado Empiezo la calibracion ph4");
 }//Serial.println("se ha terminado introduce la sonda en  ph4");
Serial.println("se ha terminado Empiezo la calibracion ph4");
while(digitalRead(pinPulsador_OK)==0);
loop;
}//Serial.println("se ha terminado Empiezo la calibracion ph4");

este es el final de momento

Bueno, perdonar os pongo la parte donde hago la lectura de la sonda de ph. me he entusiasmado y os he plantado todo el codigo, como si para mi fuera facil deducir el codigo de gente que lleva mucho tiempo en ello.
Como para que vosotros tengaís que entender, ese pupurri que hago, sin orden y seguramente con poca logica.

//##################################################################
/////////////////////////////////////
//     Funcion calculo PH   /////////
///      INICIO FUNCION     /////////
/////////////////////////////////////////////////////////////////////////////////////////
void lectura_del_Ph(){                                                                 
      float medidaSondaPH = 0;                                                          
      float promedioSondaPH = 0;                                                       
          for(int i=0;i<50;i++)                                               
            {                                                                 
             medidaSondaPH = analogRead(PinSondaPh);
             promedioSondaPH =promedioSondaPH + medidaSondaPH;
              delay(50);
              }
        promedioSondaPH = promedioSondaPH / 50;
        Serial.print("Medida: ");
        Serial.print(promedioSondaPH );
        float PH = 7 + ((medidaSondaPH - ValorPH7 ) * 3 / (ValorPH7 - ValorPH4 ));
        int PH_int = PH;
        Serial.print("\tPH: ");
        Serial.print(PH, 1);
        Serial.println("");
        Serial.print("\tPH_int: ");
        Serial.print(PH_int, 3);
        Serial.println("");
        delay(100);
     }

he segido probando cosas y parece que si, aparte del ruido que puedo atrapar con la señal analogica, hay algo en el codigo que lo acentua, y no se encontrarlo.

Me parece que el problema está acá

float PH = 7 + ((medidaSondaPH - ValorPH7 ) * 3 / (ValorPH7 - ValorPH4 ));

Calculas el promedio de 50 lecturas pero finalmente para calcular el pH usas solo la última (porque es la que queda almacenada en la variable medidaSondaPH).

Creo que debería ser así

float PH = 7 + ((promedioSondaPH - ValorPH7 ) * 3 / (ValorPH7 - ValorPH4 ));

Por otro lado, está perfecto que muestres todo el código, nos permite ver todo el panorama.

Gracias Gatul, ahora mismo me siento como tu avatar, jaja.
ahora mismo lo pruebo.
Si os reireis, pero me tire casi un dia probando el programa y no conseguia leer nada, hasta que hommer se aparecio y me dijo no la tienes en A0 si no en A1, :fearful: por dios.
bueno una solucionada, haber si con tu ayuda soluciono esta otra.

Gatul, si algo se ha mejorado. Sigo teniendo fluctuaciones, son mucho menos disparatadas, pero necesito algo mas de precisión.
quiero hacer un control de co2 para el acuario, y la fluctuacion en el ph es lo que me indicara si tengo o no que aditar co2 en el acuario, mientras mas acido, menos co2. y tengo que moverme entre 6,8 parar el co2 y 7,5 inyectar co2.

Medida: 528.98  PH: 7.18PH_int: 21
Medida: 538.52  PH: 6.82PH_int: 20
Medida: 548.87  PH: 6.44PH_int: 20
Medida: 540.40  PH: 6.76PH_int: 20
Medida: 526.01  PH: 7.29PH_int: 21
Medida: 518.98  PH: 7.54PH_int: 21
Medida: 530.22  PH: 7.13PH_int: 21
Medida: 522.42  PH: 7.42PH_int: 21
Medida: 513.75  PH: 7.74PH_int: 21
Medida: 536.31  PH: 6.91PH_int: 20
Medida: 525.11  PH: 7.32PH_int: 21
Medida: 535.32  PH: 6.94PH_int: 20
Medida: 537.75  PH: 6.85PH_int: 20
Medida: 516.99  PH: 7.62PH_int: 21
Medida: 539.56  PH: 6.79PH_int: 20
Medida: 523.55  PH: 7.38PH_int: 21
Medida: 552.15  PH: 6.32PH_int: 20
Medida: 507.44  PH: 7.97PH_int: 21
Medida: 530.15  PH: 7.13PH_int: 21
Medida: 543.72  PH: 6.63PH_int: 20
Medida: 528.13  PH: 7.21PH_int: 21
Medida: 517.64  PH: 7.59PH_int: 21
Medida: 536.29  PH: 6.91PH_int: 20

no se si volver a promediar la variable PH. No lo tengo nada claro.

Por lo que estuve leyendo la sonda E201 para pH 7 tiene una variación de +/- 0.5, o sea que puedes ver un pH entre 6.5 a 7.5 cuando en realidad es 7, lo cual está dentro de tu rango de trabajo. Veo complicado establecer los puntos en que actuas cuando el error del sensor ya cae en esos límites. O sea, ¿cómo determinar cuándo cortar el CO2 si no sabes si cuando ves 6.8 realmente es 6.8 ó 7.0 ó 7.3?
Creo que vas a tener que usar un conjunto placa/sensor de mayor calidad y menor error.

Por otro lado veo que usas 2 puntos de calibración, pH 4 y pH 7, cuando lo normal para 2 puntos es 4 y 10. En la de 3 puntos se agrega pH 7 (siempre de acuerdo a lo que he leído).
El problema es que no es buena idea calcular la pendiente de la recta de calibración teniendo como uno de los límites el punto sobre el que tienes que trabajar, se supone que el punto de trabajo tiene que estar en el centro de la recta, más o menos. Y esto aplica para cualquier "cosa" que tenga una recta (o curva) de calibración.

¿Probaste la calibración del offset de la placa? ¿Tienes 2.5V (medido con tester/polimetro/multímetro) a la salida de la placa al poner la entrada BNC en corto? ¿Obtienes 512 al leer el pin analógico en ese momento?

Por último, me llama la atención que para pH 7.xx ph_int arroje 21 y para pH 6.xx sea 20 cuando debería ser 7 y 6 respectivamente según el código que nos mostraste. :o

me explico un poco mas para que puedas entender el tema del Co2.


tengo que tener una relacion entre el ph y los carbonatos calcicos Kh.
como ves la tabla esta entre 6.4 a 7,4 de ph que yo procuro estar en torno a 7 y en la vertical yo suelo estar entre 4 y 6 kh.
como puedes apreciar la escala de Co2 es proporcional al kh pero inversamente proporcional al ph.
si tengo un kh de 4 y un ph de 7 tengo 11,8 mg/l de Co2 "dentro del rango aceptable"
pero si kh 4 y ph 6,8 tengo 18,7 mg/l de Co2 "teniendo un exceso de co2"
el kh es un buffer dentro del acuario, digamos que estaviliza el ph, pero el ph es "atacado" por el co2 si tengo un exceso de co2 me acidifica el agua, poniendo en riesgo los peces y plantas.

Si he comprobado los 2,5v en el modulo ph_4502C y si 512 en el monitor serial.
lo de usar esos valores es porque no tengo otro en este momento. Pero mirare de buscar uno de valor 10 o 9 que los he visto, gracias por esa información, mirare de calibrar usando de 4 a (10 o 9) el que encuentre.
de todas maneras, muchas gracias por la ayuda, por lo menos no esta tan disparadas las lecturas.
lo de ph_int, no lo uso, esta parte es un generico de una lectura de ph, como otros tantos que he visto, me gusto mas este por el tema de los "ajustes de calibraciones", por eso aparte uso esos 2 buffers el de 4 y el de 7.
Pero como bien dices, puede que el usar un ph7 para hacer mediciones en ese valor, no sea lo mas adecuado.

Moderador:
Hola, bienvenido al foro Arduino.
En la sección proyectos tienes estos dos hilos que debiste haber leído antes de postear

Como tu consulta es para otra sección lo muevo a Software.
No te preocupes, es solo una cuestión de orden.
Normas del foro

Toda lectura de una sonda que involucra un AO (amplificador operacional) siempre tiene estas cosas que provocan grandes doleres de cabeza.
Empieza verificando la tensión con la que alimentas la placa de medición de PH.
Coloca el tester (espero lo tengas) y mira si hay ripple (medición de CA entre los bornes VCC y GND). No importa si estas usando los 5V del Arduino. A veces la misma tensión del arduino no es buena para un sensor.
Ejemplo de esto es que si tu mides una bateria arduino lo hace perfectamente, pero la misma tensión de una fuente ya tiene problemas para leerlo.

Supongo que no tendrás mas instrumental asi que limitémosnos a un tester (multímetro). Verifica entonces si hay ripple o rizado.
Te recomiendo uses un capacitor de 0.1uF y otro de 10 o 22uF en paralelo con la alimentación de la placa pcb que lee la sonda de PH. Veamos si eso ayuda.

Ahora colaboremos con el promedio.
A mi me gusta el promedio móvil y uso siempre el filtro de promedio móvil de Luis Llamas para tal tarea y es muy efectiva.
El promedio móvil a diferencia del fijo que tu usas es mas rápido y permite tener mas muestras si uno asi lo desea.
Por qué es mas rápido porque supongamos quieras 100 muestras, bueno eso lo hace la primer vez, y luego solo agrega la muestra nueva y descarta la mas vieja y promedia las 100 restantes. Eso para cada ciclo en que la interrogas.

Veamos si eso te da una mejor lectura o mas estable. Usando ambos enfoques debería mejorar sensiblemente.

Excelente explicación @antude.
Entiendo lo que es el pH y, aunque no tengo pecera, imagino lo que lo afecta a los peces, por eso te decía que trabajar en un rango tan chico con una sonda con tanto error te puede complicar la vida, encima para algo tan delicado.

Aparte de lo que te sugiere @surbyte se me ocurre que podrías, en lugar del promedio (o media) de todas las lecturas, usar la mediana.
El tema es que para eso tienes que almacenar las lecturas en un array y luego ordenarlo para finalmente, en este caso que el número de mediciones es par, usar los 2 valores centrales del array para sacar el promedio de ambos, y en base a éste calcular el pH.
Eso te filtraría sustancialmente el ruido y prácticamente eliminaría el error de la sonda.

Gracias, surbyte siempre tan atento, miro la informacion que me propones y compruebo las mediciones.
Gracias, gatul, ya veo que la calidad de la sonda no es lo mas adecuado para lo que pretendo, de todas maneras mirare lo que me comentas e intentare implementarlo.
una solucion seria subir el ph a 7.2 para tener algo mas de margen, pero primero intentare aplicar las aprotaciones que me habeis comentado, para ver cuanto me puedo acercar al ajuste.
ya os comento.

gatul:
Por otro lado veo que usas 2 puntos de calibración, pH 4 y pH 7, cuando lo normal para 2 puntos es 4 y 10. En la de 3 puntos se agrega pH 7 (siempre de acuerdo a lo que he leído).
El problema es que no es buena idea calcular la pendiente de la recta de calibración teniendo como uno de los límites el punto sobre el que tienes que trabajar, se supone que el punto de trabajo tiene que estar en el centro de la recta, más o menos. Y esto aplica para cualquier "cosa" que tenga una recta (o curva) de calibración.

Este también es un punto para prestarle atención. Como bien dice @gatul no puedes calibrar con 7 y medir 7.
No tiene lógica.
El punto alto de la recta debe estar por encima del valor medio. Asi que ahi has cometido un erro posiblemente. Revisa eso.
Yo recuerdo que las botellas de Atlas Scientific por citar alguien que hace estas placas (seguramente copiadas x los chinos de ellos) son de 4 y 10.

Mira el link pero esto es lo que ponen en las especificaciones

• 1 EZO™ pH Circuit
• 1 Double junction silver / silver chloride Lab Grade pH Probe
• 6x 20ml calibration solution pouches (2x pH 4, 2x pH 7 and 2x pH 10)
• 1x 60ml (2oz) pH storage solution bottle
• 1 Electrically Isolated EZO™ Carrier Board
Carrier Board dimensions: 56.2mm x 32mm (2.2″ x 1.2″)
Weight: 25 grams