Problemas con pH shield 1.1

Hola,

Estoy teniendo problemas para hacer funcionar un pH shield con sonda. No encuentro bibliotecas para el modelo que compre y que es este:

No tengo experiencia previa con estas placas por lo que os agradecería alguna ayuda ya que estoy bastante perdido.

Google: Ph-Sensor-Module-V1-1

Respuesa: Enlace Ph Sensor Module V1.1

NO me gusta esta tabla de respuesta al PH

Al código de wikipedia yo le agregaria esto en el setup y por enda habria que modificar la conversión a ph.

AnalogReference(INTERNAL);

Solo válido para MEGA/DUE
Ya que la lectura máxima será de 414.12 mV y con esa referencia interna de 1100mV logras mejorar la calidad de la lectura vs una lectura contra una referencia de 5000 mV como siempre se hace.
En el setup agregas esto

void setup(void)
{
  pinMode(LED,OUTPUT);  
  Serial.begin(9600);  
  Serial.println("pH meter experiment!");    //Test the serial monitor
  analogReference(INTERNAL);
}

y si asi lo usaras en el loop modificas esto

voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;

por esto

voltage = avergearray(pHArray, ArrayLenth)*1.1/1023;

Gracias por la info Surbyte.

Ya utilice el sketch de dfrobot pero con fallos, no conseguía una lectura estable de la sonda, mas tarde me di cuenta que no respondia a los tampones pH de 7 y 4, es decir no presentaba variación alguna en el voltaje.

la figura o imagen que viene en Enlace Ph Sensor Module V1.1 no se corresponde con el modelo que tengo yo parece ser el modelo de la version 1.0, no se si esto afectaria al codigo o es que los cambios son minimos ya que la arquitectura es la misma y llevan los mismos componentes.

mañana subire el sketch y los datos enviados al monitor serie con y sin cambios.

Un saludo.

Pues hoy he estado haciendo pruebas con la sonda con este código que he cambiado según me comentaste.

#define SensorPin A2            //pH meter Analog output to Arduino Analog Input 2
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;   
void setup(void)
{
  
  pinMode(LED,OUTPUT);  
  Serial.begin(9600);  
  Serial.println("pH meter experiment!");    //Test the serial monitor
  analogReference(INTERNAL1V1); 
}
void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*1.1/1023;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
  Serial.print("Voltage:");
        Serial.print(voltage,2);
        Serial.print("    pH value: ");
  Serial.println(pHValue,2);
        digitalWrite(LED,digitalRead(LED)^1);
        printTime=millis();
  }
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];

Y esto es lo que me dio como resultado la sonda cuando estaba sumergida en el buffer de pH 7.0

La señal sigue sin ser estable

pH meter experiment!
Voltage:0.54 pH value: 1.91
Voltage:0.68 pH value: 2.39
Voltage:0.66 pH value: 2.33
Voltage:0.61 pH value: 2.14
Voltage:0.65 pH value: 2.27
Voltage:0.68 pH value: 2.38
Voltage:0.66 pH value: 2.31
Voltage:0.62 pH value: 2.16
Voltage:0.64 pH value: 2.22
Voltage:0.70 pH value: 2.46
Voltage:0.65 pH value: 2.26
Voltage:0.60 pH value: 2.11
Voltage:0.66 pH value: 2.32
Voltage:0.67 pH value: 2.33
Voltage:0.69 pH value: 2.42
Voltage:0.62 pH value: 2.19
Voltage:0.62 pH value: 2.18
Voltage:0.69 pH value: 2.42
Voltage:0.68 pH value: 2.37
Voltage:0.67 pH value: 2.35
Voltage:0.63 pH value: 2.19
Voltage:0.64 pH value: 2.24
Voltage:0.68 pH value: 2.38
Voltage:0.66 pH value: 2.31
Voltage:0.65 pH value: 2.27
Voltage:0.63 pH value: 2.20
Voltage:0.64 pH value: 2.25
Voltage:0.71 pH value: 2.48
Voltage:0.66 pH value: 2.32
Voltage:0.65 pH value: 2.27
Voltage:0.63 pH value: 2.20
Voltage:0.63 pH value: 2.22
Voltage:0.69 pH value: 2.42
Voltage:0.69 pH value: 2.41
Voltage:0.69 pH value: 2.41
Voltage:0.62 pH value: 2.19
Voltage:0.71 pH value: 2.47

Queria comprobar que las conexiones estan hechas de manera correcta ya que los pines de salida tenian una nomenclatura algo rara:

"To" "Do" "Po" "G" "G" "V+"

To = esto creo que es la señal de temperatura para la correccion del pH
Do = no estoy seguro si puede ser una salida digital (Digital Output)
G = Neutros
V+= Voltaje

La señal será mas o menos estable de acuerdo al circuito que uses.
Normalmente todos tomamos varias muestras y las promediamos y asi quitamos esa molesta fluctuación.
Algunos usamos el promedio móvil que arranca lento pero luego es sencillamente extraordinario.
Para tu caso sería muy bueno porque no esperas cambios bruscos de ph sino graduales. En estos casos el promedio móvil funciona muy bien.

Buscalo en wikipedia o en google como Arduino movil average o Arduino promedio movil.

Hola,

Estuve hablando con los que me proporcionaron la sonda y me pasaron sus códigos, se solucionan algunos fallos pero surgen nuevos problemas.

La sonda para pH4 me da valores altos de pH calibrando analogicamente abarco un rango de pH de 9.30 a 13.00 y creo que la correspondencia lineal entre mV y pH esta invertida.

/*
# This sample codes is for testing the pH meter V1.0.
 # Editor : YouYou
 # Date   : 2013.10.21
 # Ver    : 0.1
 # Product: pH meter
 # SKU    : SEN0161
*/

#define SensorPin 0            //pH meter Analog output to Arduino Analog Input 0
#define Offset -3.00            //deviation compensate
unsigned long int avgValue;     //Store the average value of the sensor feedback
void setup()
{
  pinMode(13,OUTPUT);  
  Serial.begin(9600);  
  Serial.println("Ready");    //Test the serial monitor
}
void loop()
{
  int buf[10];                //buffer for read analog
  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  { 
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        int temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue+Offset;                      //convert the millivolt into pH value
  Serial.print("    pH:");  
  Serial.print(phValue,2);
  Serial.println(" ");
  digitalWrite(13, HIGH);       
  delay(800);
  digitalWrite(13, LOW); 
}

Hola tengo el mismo ladrillo, en el enlace de ebay donde lo compré
( http://www.ebay.es/itm/Liquid-PH0-14-Value-Detect-Sensor-Module-PH-Electrode-Probe-BNC-for-Arduino-/291638372809?hash=item43e70069c9:g:m7EAAOSwsB9V9m0N)
añaden un archivo;
http://www.uctronics.com/download/U3525.zip

no consigo arrancarlo... no se si el ide tendra que ver...

Rantamplan, parece que tienes poca idea de como es la estructura de un programa en Arduino o te malentiendo y quieres ayudar con ese código pero no sirve para este microcontrolador.

Basicamente un programa de arduino tiene un área de definiciones y librerías
una de setup
y finalmente el loop que se ejecuta indefinidamente.

#include <Librerias.h>
// variables globales.

void setup() {
// cosas que se inicializan 1 sola vez
}
void loop() {
// Programa que se ejecuta indefinidamente
}

El código que has puesto es para otro microcontrolador que nada tiene que ver con Arduino mas que la programación en C. Una un compilador muy reconocido que se llama Keil que nada tiene que ver con Arduino.
Entonces cuando busques información pones en Google: arduino ph shield 1.1 y ahi tienes tus códigos.

Aca tienes un ejemplo que si funcionará PH shield 1.1 code

Gracias, lo de la estructura lo tengo claro, :cold_sweat: creia que keil era la libreria, es lo que tiene la falta de estudios y la ignorancia.
He cargado el codigo,

/*
 # This sample code is used to test the pH meter V1.1.
 # Editor : YouYou
 # Date   : 2014.06.23
 # Ver    : 1.1
 # Product: analog pH meter V1.1
 # SKU    : SEN0161
*/
#define SensorPin A2            //pH meter Analog output to Arduino Analog Input 2
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;    
void setup(void)
{
  pinMode(LED,OUTPUT);  
  Serial.begin(9600);  
  Serial.println("pH meter experiment!");    //Test the serial monitor
}
void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
	Serial.print("Voltage:");
        Serial.print(voltage,2);
        Serial.print("    pH value: ");
	Serial.println(pHValue,2);
        digitalWrite(LED,digitalRead(LED)^1);
        printTime=millis();
  }
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}

la lectura sale invertida, los acidos por encima de 8 y alcalinos no por debajo, como se modifica esto?

Podes comprobar que la salida de la sonda sensora de PH es similar a la tabla?

La sonda para pH4 me da valores altos de pH calibrando analogicamente abarco un rango de pH de 9.30 a 13.00 y creo que la correspondencia lineal entre mV y pH esta invertida.

Bueno parece que hablamos de sondas diferentes de modo que habrá que considerar ajustar las cosas de otro modo.
Hay que hacer una calibración y modificar la recta para obtener offset y pendiente de la recta que SI represente a esa sonda.
Son dos o mas puntos pero supongamos dos.

  1. y2 = m*x2 + b
  2. y1 = mx1 + b
    donde
    b = ordenada al origen u offset
    m = pendiente de la recta que será negativa por estar invertida
    y2,x2 par de puntos en calibración 2
    y1,x1 par de puntos en calibración 1.
    Y es ph
    X es lectura que toma el arduino via ADC.
    Despejan b y m y obtienen la respuesta.
    Si restan 1 de 2 eliminan b
    m = (y2- y1)/(x2-x1)
    reemplazan en una ecuación y tienen b
    b = y1-m
    x1= y1 - (y2- y1)/(x2-x1)x1
    __b = (y1
    x2-y2*x1)/((x2-x1))__

Tu ecuación será: y (en ph) = m*X(en mV del ADC) + b
con m y b obtenidos previamente.
Asi que debes hacer un programa que permita calibrar y otro que permita usar los valores de m y b para obtener la lectura que buscas.

Necesito datos de la sonda!! Ubiquen el modelo y posible tabla de salida en mV

Ante todo gracias, muchas cosas se me escapan...
Wattson Chargeable combination pH electrode E-201-C

Technical specifications

Product name: pH Electrode
Model: E-201-C
Measuring range: (0-14)PH
Temperature: (0-80)°C
Theoretic percent slope: ≥97% (25°C)
Zero point PH value: (7±0.25)PH (25°C)
Inner impedance: ≤250MΩ (25°C)
Response time: ≤1 minute
Alkaline error: ≤15mv (25°C)
http://www.phkedida.com/lab-ph-electrode-e-201s

Captura.JPG

Captura1.JPG

Buffer solution Con ph 7.0 voltage: 2.84 mV y pH value : 9.94
Con ph 4.0 voltage: 3.37 mV y pH value : 11.78
directamente midiendo con el multimetro con ph 7 da 2.819mv
ph 4 da 3.342mv

Son dos o mas puntos pero supongamos dos.

  1. y2 = mx2 + b 7.0 = m2.84 + b
  2. y1 = mx1 + b 4.0 = m3.37 + b
    donde
    b = ordenada al origen u offset
    m = pendiente de la recta que será negativa por estar invertida
    y2,x2 par de puntos en calibración 2
    y1,x1 par de puntos en calibración 1.
    Y es ph
    X es lectura que toma el arduino via ADC.
    Despejan b y m y obtienen la respuesta.
    Si restan 1 de 2 eliminan b
    m = (y2- y1)/(x2-x1) m = (7.0- 4.0)/(2.84-3.37)= -5.6603773585
    reemplazan en una ecuación y tienen b
    b = y1-mx1= y1 - (y2- y1)/(x2-x1)x1
    b = (y1
    x2-y2
    x1)/((x2-x1)) b = (4.02.84-7.03.37)/((2.84-3.37))= 23.0754716981

Tu ecuación será: y (en ph) = m*X(en mV del ADC) + b
con m y b obtenidos previamente.

Bueno... gracias Surbyte , gracias Chelugas y gracias a Toni Ruiz de Electroensaimada.com por el tutorial de el sensor ir.

void setup(){
  Serial.begin(9600);

}

void loop(){
float medida;

medida=PH_Sensor(2);

Serial.print("  Lectura Sonda: ");Serial.print(medida);Serial.println(" pH");

delay(100);
}
float PH_Sensor(int pin_PH){

int ADC;
float Tension,nivel;


ADC=analogRead(pin_PH);//Leemos en el canal pin
Tension=ADC_to_Volt(ADC);//Conversion a Voltios

nivel=-5.6603773585*(Tension)+23.0754716981; // ecuación de surbyte

return nivel;
}


float ADC_to_Volt(int ADC_value){
float Volt=0;

Volt=(ADC*5.0)/1023;


return Volt;
}

se ajusta a ph 4 y a ph 7 en cuanto tenga un calibrador dijital o liquido "buffer" con otro Ph para contrastar la lectura comentare... con mas puntos de referencia se puede aplicar el comando pow por si en vez de recta resulta que es curva
Gracias one more time.

Me alegro que te sirviera... es Análisis matemático I... hace mucho tiempo de eso.

Gracias por el interés surbyte y Rantamplan, si a mi también me quedan las clases algo lejos jeje, las usaba un montón con el espectrofotometro para las rectas de calibración en determinación de metales pesados en las aguas y es una pena que todo lo que no usamos cotidianamente se vaya perdiendo...

Le echare un ojo hoy a la sonda y trasteare un rato a ver si consigo algo.

Gracias de nuevo a todos, hoy he "reaprendido" mucho.

hello

thank you i learn a lot from this conversation.
i wnat to ask Rantamplan, have you set up this circuit ( http://www.ebay.es/itm/Liquid-PH0-14-Value-Detect-Sensor-Module-PH-Electrode-Probe-BNC-for-Arduino-/291638372809?hash=item43e70069c9:g:m7EAAOSwsB9V9m0N)

i need help about the values of some components.

best
hakan

Yes okyanusumhakan than the moment I only calibrate with two points, try to charge the last two codes and compile it, Po pin to analog input, vcc to 5v and grnd--grng, later with the pot on shield accurate it... my English not is so good but... report results

Haciendo un intento de mejorar el codigo, en el monitor sale a izquierda la lectura pasando por el "estabilizador", a la derecha la lectura que viene directa de la ecuación sobre adc-volt.

No consigo hacer una media con decimales, alguna idea? Después veo que al alimentar otros dispositivos (una pcb con relé y dos leds) incluso creo que el led tx del usb al parpadear hace que varie la lectura del ADC/Volt/PH, creo que con AREF se soluciona, algun aporte? Se puede disponer el codigo mas ordenadamente ?

Sobre AREF y medidas de Voltaje : Precise voltage measurement with an Arduino microcontroller

const int numReadings = 10;
int readings[numReadings];      // la lectura de la entrada analógica
int index = 0;                  // el índice de la lectura actual
float average = 0;                // la media
int total = 0;   

void setup(){

  Serial.begin(9600); //Abrir comunicacion con el monitor
 
// inicializa todos los elementos del arreglo con 0:

  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;     
pinMode (2, OUTPUT);  
}

void loop(){

float medida; 

medida=PH_Sensor(2);

 
 // resta la última lectura
  total= total - readings[index];        
  // lectura del sensor
  readings[index] = (medida);
  // suma la lectura actual y el total
  total= total + readings[index];      
  // avanza al siguiente elemento del arreglo
  index = index + 1;                    

  // si se llego al final de arreglo (al último elemento)
  if (index >= numReadings)              
    // se vuelve al primer elemento (índice 0)
    index = 0;                          

  // calcula la media
  average = total / numReadings;        
  // envía el resultado a la PC
   
  delay(1);        // retraso entre lectura y lectura para la estabilidad


//imprime en monitor
Serial.print("  Lectura Sonda: ");Serial.print(medida);Serial.println(" pH");
Serial.print("  estabilizada: ");Serial.print(average);

delay(500);
}
float PH_Sensor(int pin_PH){ //nombre variable

int ADC;// crea nombre para almacenar variables
float Tension,nivel; //nombre variables


ADC=analogRead(pin_PH);//Leemos en el canal pin
Tension=ADC_to_Volt(ADC);//Conversion a Voltios
// conversion a rango ph nivel = pendiente de la 
//recta por voltaje ADC mas ordenada al origen
nivel=-5.6603773585*(Tension)+23.0754716981;

return nivel; // devuelve nivel a ph sensor
}

//conversion a lectura 0-5v
float ADC_to_Volt(int ADC_value){
float Volt=0;

Volt=(ADC*5.0)/1023;


return Volt;
}

bueno Rantamplan, usa este promedio móvil como estabilizador, te vas a sorprender.