Update Aplicación android/pHimetro.aia, Aplicación android/pHimetro.apk, Código arduino/DFRobot_PH.cpp, Código arduino/DFRobot_PH.h, Código arduino/pHimetro.ino files
parent
67b6061ae0
commit
4156aa24db
@ -0,0 +1,225 @@
|
||||
/****************************************************
|
||||
pHmtero - CoSensores (Sensores Comunitarios)
|
||||
*****************************************************
|
||||
Adaptación del codigo de DFRobot Gravity: Analog pH Sensor / Meter Kit V2, SKU:SEN0161-V2
|
||||
https://wiki.dfrobot.com/Gravity__Analog_pH_Sensor_Meter_Kit_V2_SKU_SEN0161-V2
|
||||
https://github.com/DFRobot/DFRobot_PH
|
||||
*****************************************************/
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "DFRobot_PH.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
|
||||
#define EEPROM_read(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}
|
||||
|
||||
#define PHVALUEADDR 0x00 //parametros iniciales de calibracio'n guardados en el EEPROM
|
||||
|
||||
|
||||
DFRobot_PH::DFRobot_PH()
|
||||
{
|
||||
this->_temperature = 25.0;
|
||||
this->_phValue = 7;
|
||||
this->_acidVoltage = 3830.0; //buffer pH=4.01 a 25^C
|
||||
this->_neutralVoltage = 3305.0; //buffer pH=6.86 a 25^C
|
||||
this->_voltage = 1500.0;
|
||||
}
|
||||
|
||||
DFRobot_PH::~DFRobot_PH()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DFRobot_PH::begin()
|
||||
{
|
||||
EEPROM_read(PHVALUEADDR, this->_neutralVoltage); //carga el voltaje correspondiente al pH neutro en el EEPROM (pH = 6.86)
|
||||
//Serial.print("_neutralVoltage:");
|
||||
//Serial.println(this->_neutralVoltage);
|
||||
if(EEPROM.read(PHVALUEADDR)==0xFF && EEPROM.read(PHVALUEADDR+1)==0xFF && EEPROM.read(PHVALUEADDR+2)==0xFF && EEPROM.read(PHVALUEADDR+3)==0xFF){
|
||||
this->_neutralVoltage = 3305.0; //nuevo EEPROM
|
||||
EEPROM_write(PHVALUEADDR, this->_neutralVoltage);
|
||||
}
|
||||
EEPROM_read(PHVALUEADDR+4, this->_acidVoltage);//carga el voltaje correspondiente al pH acido en el EEPROM (pH = 4.01)
|
||||
//Serial.print("_acidVoltage:");
|
||||
//Serial.println(this->_acidVoltage);
|
||||
if(EEPROM.read(PHVALUEADDR+4)==0xFF && EEPROM.read(PHVALUEADDR+5)==0xFF && EEPROM.read(PHVALUEADDR+6)==0xFF && EEPROM.read(PHVALUEADDR+7)==0xFF){
|
||||
this->_acidVoltage = 3830.0; //nuevo EEPROM
|
||||
EEPROM_write(PHVALUEADDR+4, this->_acidVoltage);
|
||||
}
|
||||
}
|
||||
|
||||
float DFRobot_PH::readPH(float voltage, float temperature)
|
||||
{
|
||||
float slope = (6.86-4.01)/((this->_neutralVoltage-1500.0)/3.0 - (this->_acidVoltage-1500.0)/3.0); // calibracio'n de dos puntos:_neutralVoltage,6.86 y _acidVoltage,4.01
|
||||
float intercept = 6.86 - slope*(this->_neutralVoltage-1500.0)/3.0;
|
||||
|
||||
Serial.print(voltage,0);
|
||||
Serial.print("mV ");
|
||||
Serial.print("A:");
|
||||
Serial.print(slope,4);
|
||||
Serial.print(" B:");
|
||||
Serial.println(intercept);
|
||||
Serial.println();
|
||||
|
||||
|
||||
this->_phValue = slope*(voltage-1500.0)/3.0+intercept; //pH = A*voltaje + B
|
||||
return _phValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DFRobot_PH::calibration(float voltage, float temperature,char* cmd)
|
||||
{
|
||||
this->_voltage = voltage;
|
||||
this->_temperature = temperature;
|
||||
strupr(cmd);
|
||||
phCalibration(cmdParse(cmd)); // si recibe el CMD por el monitor serial entra al modo calibracio'n
|
||||
|
||||
}
|
||||
|
||||
void DFRobot_PH::calibration(float voltage, float temperature)
|
||||
{
|
||||
this->_voltage = voltage;
|
||||
this->_temperature = temperature;
|
||||
if(cmdSerialDataAvailable() > 0){
|
||||
phCalibration(cmdParse()); // si recibe el CMD por el monitor serial entra al modo calibracio'n
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean DFRobot_PH::cmdSerialDataAvailable()
|
||||
{
|
||||
char cmdReceivedChar;
|
||||
static unsigned long cmdReceivedTimeOut = millis();
|
||||
while(Serial.available()>0){
|
||||
if(millis() - cmdReceivedTimeOut > 500U){
|
||||
this->_cmdReceivedBufferIndex = 0;
|
||||
memset(this->_cmdReceivedBuffer,0,(ReceivedBufferLength));
|
||||
}
|
||||
cmdReceivedTimeOut = millis();
|
||||
cmdReceivedChar = Serial.read();
|
||||
if (cmdReceivedChar == '\n' || this->_cmdReceivedBufferIndex==ReceivedBufferLength-1){
|
||||
this->_cmdReceivedBufferIndex = 0;
|
||||
strupr(this->_cmdReceivedBuffer);
|
||||
return true;
|
||||
|
||||
}else{
|
||||
this->_cmdReceivedBuffer[this->_cmdReceivedBufferIndex] = cmdReceivedChar;
|
||||
this->_cmdReceivedBufferIndex++;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
byte DFRobot_PH::cmdParse(const char* cmd)
|
||||
{
|
||||
byte modeIndex = 0;
|
||||
if(strstr(cmd, "CALIBRAR") != NULL){
|
||||
modeIndex = 1;
|
||||
}else if(strstr(cmd, "SALIR") != NULL){
|
||||
modeIndex = 3;
|
||||
}else if(strstr(cmd, "PHCAL") != NULL){
|
||||
modeIndex = 2;
|
||||
}
|
||||
return modeIndex;
|
||||
}
|
||||
|
||||
byte DFRobot_PH::cmdParse()
|
||||
{
|
||||
byte modeIndex = 0;
|
||||
if(strstr(this->_cmdReceivedBuffer, "CALIBRAR") != NULL){
|
||||
modeIndex = 1;
|
||||
}else if(strstr(this->_cmdReceivedBuffer, "SALIR") != NULL){
|
||||
modeIndex = 3;
|
||||
}else if(strstr(this->_cmdReceivedBuffer, "PHCAL") != NULL){
|
||||
modeIndex = 2;
|
||||
}
|
||||
return modeIndex;
|
||||
}
|
||||
|
||||
void DFRobot_PH::phCalibration(byte mode)
|
||||
{
|
||||
char *receivedBufferPtr;
|
||||
static boolean phCalibrationFinish = 0;
|
||||
static boolean enterCalibrationFlag = 0;
|
||||
|
||||
switch(mode){
|
||||
|
||||
case 0:
|
||||
if(enterCalibrationFlag){
|
||||
Serial.println(F(">>>error<<<"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
enterCalibrationFlag = 1;
|
||||
phCalibrationFinish = 0;
|
||||
Serial.println();
|
||||
//Serial.println(F(">>>calibrando<<<"));
|
||||
Serial.println(F("buffer 4.01 o 6.86"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(enterCalibrationFlag){
|
||||
if((this->_voltage>3000)&&(this->_voltage<3500)){ // buffer solution:6.86{
|
||||
Serial.println();
|
||||
Serial.print(F("buffer 6.86"));
|
||||
this->_neutralVoltage = this->_voltage;
|
||||
//Serial.println(F(",SALIR para guardar y salir<<<"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
phCalibrationFinish = 1;
|
||||
}else if((this->_voltage>3501)&&(this->_voltage<4000)){ //buffer solution:4.01
|
||||
Serial.println();
|
||||
Serial.print(F("buffer 4.01"));
|
||||
this->_acidVoltage = this->_voltage;
|
||||
//Serial.println(F(",SALIR para guardar y salir<<<"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
phCalibrationFinish = 1;
|
||||
}else{
|
||||
Serial.println();
|
||||
Serial.print(F(">>>error<<<"));
|
||||
Serial.println(); // not buffer solution or faulty operation
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
phCalibrationFinish = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(enterCalibrationFlag){
|
||||
Serial.println();
|
||||
if(phCalibrationFinish){
|
||||
if((this->_voltage>3000)&&(this->_voltage<3500)){
|
||||
EEPROM_write(PHVALUEADDR, this->_neutralVoltage);
|
||||
}else if((this->_voltage>3501)&&(this->_voltage<4000)){
|
||||
EEPROM_write(PHVALUEADDR+4, this->_acidVoltage);
|
||||
}
|
||||
Serial.print(F(">>>calibrado"));
|
||||
}else{
|
||||
Serial.print(F(">>>fallo"));
|
||||
}
|
||||
Serial.println(F(",salir<<<"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
phCalibrationFinish = 0;
|
||||
enterCalibrationFlag = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/****************************************************
|
||||
pHmtero - CoSensores (Sensores Comunitarios)
|
||||
*****************************************************
|
||||
Adaptación del codigo de DFRobot Gravity: Analog pH Sensor / Meter Kit V2, SKU:SEN0161-V2
|
||||
https://wiki.dfrobot.com/Gravity__Analog_pH_Sensor_Meter_Kit_V2_SKU_SEN0161-V2
|
||||
https://github.com/DFRobot/DFRobot_PH
|
||||
*****************************************************/
|
||||
|
||||
#ifndef _DFROBOT_PH_H_
|
||||
#define _DFROBOT_PH_H_
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#define ReceivedBufferLength 10 //largo del buffer del CMD serial
|
||||
|
||||
class DFRobot_PH
|
||||
{
|
||||
public:
|
||||
DFRobot_PH();
|
||||
~DFRobot_PH();
|
||||
void calibration(float voltage, float temperature,char* cmd); //calibracio'n por CMD serial
|
||||
void calibration(float voltage, float temperature);
|
||||
float readPH(float voltage, float temperature); // voltaje a valor de pH
|
||||
void begin(); //inicializacio'n
|
||||
|
||||
private:
|
||||
float _phValue;
|
||||
float _acidVoltage;
|
||||
float _neutralVoltage;
|
||||
float _voltage;
|
||||
float _temperature;
|
||||
|
||||
char _cmdReceivedBuffer[ReceivedBufferLength]; //guardado en el CMD serial
|
||||
byte _cmdReceivedBufferIndex;
|
||||
|
||||
private:
|
||||
boolean cmdSerialDataAvailable();
|
||||
void phCalibration(byte mode); // proceso de calibracio'n, guarda parametros en el EEPROM
|
||||
byte cmdParse(const char* cmd);
|
||||
byte cmdParse();
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,124 @@
|
||||
|
||||
/****************************************************
|
||||
|
||||
pHmtero - CoSensores (Sensores Comunitarios)
|
||||
|
||||
https://gitlab.com/cosensores
|
||||
https://www.facebook.com/cosensores/
|
||||
https://www.instagram.com/cosensores/
|
||||
|
||||
Somos miembros de Universidades Nacionales trabajando junto a comunidades organizadas
|
||||
en el desarrollo de métodos para evaluar la presencia de contaminantes
|
||||
de manera sencilla en el territorio, acompañando acciones y procesos reivindicativos.
|
||||
|
||||
*****************************************************
|
||||
Adaptación del codigo de DFRobot Gravity: Analog pH Sensor / Meter Kit V2, SKU:SEN0161-V2
|
||||
https://wiki.dfrobot.com/Gravity__Analog_pH_Sensor_Meter_Kit_V2_SKU_SEN0161-V2
|
||||
https://github.com/DFRobot/DFRobot_PH
|
||||
|
||||
1. El codigo fue evaluado en Arduino Uno - IDE 1.0.5
|
||||
2. Para calibrar:
|
||||
CALIBRAR -> ingresa al modo calibracio'n
|
||||
PHCAL -> calibracio'n de dos puntos en buffer pH=4.01 y pH=6.86
|
||||
SALIR -> guarda los parametros y sale del modo de calibracio'n
|
||||
|
||||
****************************************************
|
||||
Librerias control sensor temperatura: ds18b20
|
||||
https://github.com/PaulStoffregen/OneWire
|
||||
https://github.com/milesburton/Arduino-Temperature-Control-Library
|
||||
|
||||
****************************************************/
|
||||
|
||||
//temperatura
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
OneWire ourWire(2); //conectar sensor temperatura a pin digital 2
|
||||
DallasTemperature sensors(&ourWire); //declara una variable u objeto para nuestro sensor
|
||||
|
||||
//pH
|
||||
#define SCOUNT 30 // sum of sample point
|
||||
int analogBuffer[SCOUNT]; //store the sample voltage
|
||||
int analogBufferIndex = 0;
|
||||
|
||||
#include "DFRobot_PH.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define PH_PIN A0
|
||||
float voltage,phValue,temperature = 25;
|
||||
DFRobot_PH ph;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
ph.begin();
|
||||
|
||||
//temperatura
|
||||
sensors.begin(); //Se inicia el sensor
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
//temperatura
|
||||
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
|
||||
float temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
|
||||
|
||||
//pH
|
||||
|
||||
static unsigned long timepoint = millis();
|
||||
if(millis()-timepoint>30U){ //intervalo de tiempo 30seg
|
||||
timepoint = millis();
|
||||
temperature = temp; //comentar para no levantar temperatura
|
||||
analogBuffer[analogBufferIndex] = analogRead(PH_PIN)/1024.0*5000; //lee el voltaje y lo guarda en el buffer cada 40ms
|
||||
analogBufferIndex++;
|
||||
if(analogBufferIndex == SCOUNT)
|
||||
analogBufferIndex = 0;
|
||||
voltage = getMedianNum(analogBuffer,SCOUNT); // obtiene un valor estable aplicando como filtro un valor medio
|
||||
//voltage = analogRead(PH_PIN)/1024.0*5000; // lee voltaje directo
|
||||
phValue = ph.readPH(voltage,temperature); // convierte voltaje a pH
|
||||
|
||||
//imprime
|
||||
|
||||
Serial.print(" >>> ");
|
||||
Serial.print(temperature,1);
|
||||
Serial.println(" ^C <<<");
|
||||
Serial.print(" >>> pH: ");
|
||||
Serial.print(phValue,2);
|
||||
Serial.println(" <<<");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
ph.calibration(voltage,temperature); //proceso de calibracio'n por CMD serial
|
||||
}
|
||||
|
||||
|
||||
int getMedianNum(int bArray[], int iFilterLen)
|
||||
{
|
||||
int bTab[iFilterLen];
|
||||
for (byte i = 0; i<iFilterLen; i++)
|
||||
{
|
||||
bTab[i] = bArray[i];
|
||||
}
|
||||
int i, j, bTemp;
|
||||
for (j = 0; j < iFilterLen - 1; j++)
|
||||
{
|
||||
for (i = 0; i < iFilterLen - j - 1; i++)
|
||||
{
|
||||
if (bTab[i] > bTab[i + 1])
|
||||
{
|
||||
bTemp = bTab[i];
|
||||
bTab[i] = bTab[i + 1];
|
||||
bTab[i + 1] = bTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((iFilterLen & 1) > 0)
|
||||
bTemp = bTab[(iFilterLen - 1) / 2];
|
||||
else
|
||||
bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
|
||||
return bTemp;
|
||||
}
|
||||
|
Loading…
Reference in New Issue