ph-metro/Código arduino/DFRobot_PH.cpp

218 lines
7.3 KiB
C++

/****************************************************
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 <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 = 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;
}
}