/**************************************************** 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 La adaptación fue mejorada durante la Residencia de la ReGOSH realizada en UNCUYO, Mendoza. *****************************************************/ #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 = 2032.44; //buffer pH=4.00 a 25^C this->_neutralVoltage = 1500.00; //buffer pH=7.00 a 25^C this->_voltage = 1500.00; } DFRobot_PH::~DFRobot_PH() { } void DFRobot_PH::begin() { EEPROM_read(PHVALUEADDR, this->_neutralVoltage); //carga el voltaje correspondiente al pH neutro en el EEPROM (pH = 7.00) //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 = 1500.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.00) //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 = 2032.44; //nuevo EEPROM EEPROM_write(PHVALUEADDR+4, this->_acidVoltage); } } float DFRobot_PH::readPH(float voltage, float temperature) { float slope = (7.00-4.00)/((this->_neutralVoltage-1500.0)/3.0 - (this->_acidVoltage-1500.0)/3.0); // calibracio'n de dos puntos:_neutralVoltage,7.00 y _acidVoltage,4.00 float intercept = 7.00 - slope*(this->_neutralVoltage-1500.0)/3.0; 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; String sCmd = String(cmd); sCmd.toUpperCase(); phCalibration(cmdParse(sCmd.c_str())); // 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 Serial.print(voltage); Serial.println("mV "); } } 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, "ENTRARPH") != NULL){ modeIndex = 1; }else if(strstr(cmd, "SALIRCAL") != NULL){ modeIndex = 3; }else if(strstr(cmd, "PHCAL") != NULL){ modeIndex = 2; } return modeIndex; } byte DFRobot_PH::cmdParse() { byte modeIndex = 0; if(strstr(this->_cmdReceivedBuffer, "ENTRARPH") != NULL){ modeIndex = 1; }else if(strstr(this->_cmdReceivedBuffer, "SALIRCAL") != 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("")); } break; case 1: enterCalibrationFlag = 1; phCalibrationFinish = 0; Serial.println(); Serial.println ("Entró al modo calibración"); Serial.println("Introduzca buffer 4.00"); Serial.println("Dejar estabilizar"); Serial.println("Presione pHCAL"); Serial.println(); break; case 2: if(enterCalibrationFlag){ if((this->_voltage>1022)&&(this->_voltage<1678)){ // buffer solution:7.00{ Serial.println(); Serial.print(F("Buffer: 7.00")); this->_neutralVoltage = this->_voltage; Serial.println(F("Presione GUARDAR")); Serial.println(); phCalibrationFinish = 1; }else if((this->_voltage>1854)&&(this->_voltage<2500)){ //buffer solution:4.01 Serial.println(); Serial.println(F("Buffer: 4.00")); this->_acidVoltage = this->_voltage; Serial.println(F("Pase al buffer 7.00")); Serial.println("Dejar estabilizar"); Serial.println("Presione pHCAL"); Serial.println(); phCalibrationFinish = 1; }else{ Serial.println(); Serial.print(F(">>Error, pruebe nuevamente.<<<")); Serial.println(); // not buffer solution or faulty operation phCalibrationFinish = 0; } } break; case 3: if(enterCalibrationFlag){ Serial.println(); if(phCalibrationFinish){ if((this->_voltage>1022)&&(this->_voltage<1678)){ EEPROM_write(PHVALUEADDR, this->_neutralVoltage); }else if((this->_voltage>1854)&&(this->_voltage<2500)){ EEPROM_write(PHVALUEADDR+4, this->_acidVoltage); } Serial.print(F(">>>Calibración exitosa")); }else{ Serial.print(F(">>>Falló la calibración")); } Serial.println(); Serial.println(); phCalibrationFinish = 0; enterCalibrationFlag = 0; } break; } }