218 lines
7.3 KiB
C++
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;
|
|
}
|
|
}
|