diff --git a/Aplicación Android/pHimetro.aia b/Aplicación android/pHimetro.aia similarity index 100% rename from Aplicación Android/pHimetro.aia rename to Aplicación android/pHimetro.aia diff --git a/Aplicación Android/pHimetro.apk b/Aplicación android/pHimetro.apk similarity index 100% rename from Aplicación Android/pHimetro.apk rename to Aplicación android/pHimetro.apk diff --git a/Código arduino/DFRobot_PH.cpp b/Código arduino/DFRobot_PH.cpp new file mode 100644 index 0000000..181e165 --- /dev/null +++ b/Código arduino/DFRobot_PH.cpp @@ -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 + +#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; + } +} diff --git a/Código arduino/DFRobot_PH.h b/Código arduino/DFRobot_PH.h new file mode 100644 index 0000000..9f066fe --- /dev/null +++ b/Código arduino/DFRobot_PH.h @@ -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 diff --git a/Código arduino/pHimetro.ino b/Código arduino/pHimetro.ino new file mode 100644 index 0000000..babd398 --- /dev/null +++ b/Código arduino/pHimetro.ino @@ -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 +#include +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 + +#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 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; +} +