Really hope my title makes some sort of sense.
I am using the gravitytds library on my project, it has a function to allow calibration, storing and reading from the EEPROM but I am unsure on the rules and best practice when trying to run various modifications with the function names, eg in my case I am using 3 sensors rather than the 1.
I have learnt I was able to use the following code to set up multiple TDS sensors, and get individual read outs, however where I am getting stuck, kind of the final hurdle.
I need some help making sense of the library to understand how I would interface and call the ability to calibrate sensors 2 and 3 independently.
my code:
#include <EEPROM.h>
#include "GravityTDS.h"
//Define PinOut
#define TDS_SUP_Pin A0
#define tds_PREDI_Pin A1
#define TDS_OUT_Pin A2
GravityTDS gravityTds_SUP;
GravityTDS gravitytds_PREDI;
GravityTDS gravityTds_OUT;
float temperature = 25;
float tdsValue_SUP = 0;
float tdsValue_PREDI = 0;
float tdsValue_OUT = 0;
float kValue_SUP = 0;
float kValue_PREDI = 0;
float kValue_OUT = 0;
char w_tdsValue_SUP[8];
char w_tdsValue_PREDI[8];
char w_tdsValue_OUT[8];
char SUP_kValue[4];
char PREDI_kValue[4];
char OUT_kValue[4];
int prevtdsValue_SUP;
int prevtdsValue_PREDI;
int prevtdsValue_OUT;
void GravityTDS_setup(){
gravityTds_SUP.setPin(TDS_SUP_Pin);
gravityTds_SUP.setAref(5.0); //reference voltage on ADC, default 5.0V on Arduino UNO
gravityTds_SUP.setAdcRange(1024); //1024 for 10bit ADC;4096 for 12bit ADC
gravityTds_SUP.setKvalueAddress(4); //set the EEPROM address to store the k value,default address:0x08
gravityTds_SUP.begin(); //initialization
gravitytds_PREDI.setPin(tds_PREDI_Pin);
gravitytds_PREDI.setAref(5.0); //reference voltage on ADC, default 5.0V on Arduino UNO
gravitytds_PREDI.setAdcRange(1024); //1024 for 10bit ADC;4096 for 12bit ADC
gravitytds_PREDI.setKvalueAddress(8); //set the EEPROM address to store the k value,default address:0x08
gravitytds_PREDI.begin(); //initialization
gravityTds_OUT.setPin(TDS_OUT_Pin);
gravityTds_OUT.setAref(5.0); //reference voltage on ADC, default 5.0V on Arduino UNO
gravityTds_OUT.setAdcRange(1024); //1024 for 10bit ADC;4096 for 12bit ADC
gravityTds_OUT.setKvalueAddress(12); //set the EEPROM address to store the k value,default address:0x08
gravityTds_OUT.begin(); //initialization
}
void GravityTDS_results(){
//temperature = readTemperature(); //add your temperature sensor and read it
//Calculate TDS from Supply Water
gravityTds_SUP.setTemperature(temperature); // set the temperature and execute temperature compensation
gravityTds_SUP.getKvalue();
gravityTds_SUP.update(); //sample and calculate
tdsValue_SUP = gravityTds_SUP.getTdsValue(); // then get the value
//Calculate TDS from Output of Membrane
gravitytds_PREDI.setTemperature(temperature); // set the temperature and execute temperature compensation
gravitytds_PREDI.getKvalue();
gravitytds_PREDI.update(); //sample and calculate
tdsValue_PREDI = gravitytds_PREDI.getTdsValue(); // then get the value
//Calculate TDS from Output
gravityTds_OUT.setTemperature(temperature); // set the temperature and execute temperature compensation
gravityTds_OUT.getKvalue();
gravityTds_OUT.update(); //sample and calculate
tdsValue_OUT = gravityTds_OUT.getTdsValue(); // then get the value
if(tdsValue_SUP == prevtdsValue_SUP) {
Serial.print("Supply TDS reading hasnt changed (Current/Last Read): ");
Serial.print(tdsValue_SUP, 0); Serial.print("ppm");
Serial.print(" : ");
Serial.print(prevtdsValue_SUP); Serial.println("ppm");
delay(100);
// return;
} else {
prevtdsValue_SUP = tdsValue_SUP;
Serial.print("SUP TDS: "); Serial.print(tdsValue_SUP, 0); Serial.println("ppm");
Serial.println("Supply TDS Telemetry Sent Successfully!");
delay(100);
}
if(tdsValue_PREDI == prevtdsValue_PREDI) {
Serial.print("Pre-DI TDS reading hasnt changed (Current/Last Read): ");
Serial.print(tdsValue_PREDI, 0); Serial.print("ppm");
Serial.print(" : ");
Serial.print(prevtdsValue_PREDI); Serial.println("ppm");
delay(100);
// return;
} else {
prevtdsValue_PREDI = tdsValue_PREDI;
Serial.print("PRE-DI TDS: "); Serial.print(tdsValue_PREDI, 0); Serial.print("ppm");
Serial.println("Pre-DI TDS Telemetry Sent Successfully!");
delay(100);
}
if(tdsValue_OUT == prevtdsValue_OUT) {
Serial.print("Output TDS reading hasnt changed (Current/Last Read): ");
Serial.print(tdsValue_OUT, 0); Serial.print("ppm");
Serial.print(" : ");
Serial.print(prevtdsValue_OUT); Serial.println("ppm");
delay(100);
// return;
} else {
prevtdsValue_OUT = tdsValue_OUT;
Serial.print("OUT TDS: "); Serial.print(tdsValue_OUT, 0); Serial.println("ppm");
Serial.println("Output TDS Telemetry Sent Successfully!");
delay(100);
}
delay(3000);
}
void setup() {
Serial.begin(115200);
Serial.println("Booting...");
GravityTDS_setup();
delay(5000);
}
void loop() {
GravityTDS_results();
delay(200);
}
The GravityTDS.h library,
#ifndef GRAVITY_TDS_H
#define GRAVITY_TDS_H
#include "Arduino.h"
#define ReceivedBufferLength 15
#define TdsFactor 0.5 // tds = ec / 2
class GravityTDS
{
public:
GravityTDS();
~GravityTDS();
void begin(); //initialization
void update(); //read and calculate
void setPin(int pin);
void setTemperature(float temp); //set the temperature and execute temperature compensation
void setAref(float value); //reference voltage on ADC, default 5.0V on Arduino UNO
void setAdcRange(float range); //1024 for 10bit ADC;4096 for 12bit ADC
void setKvalueAddress(int address); //set the EEPROM address to store the k value,default address:0x08
float getKvalue();
float getTdsValue();
float getEcValue();
private:
int pin;
float aref; // default 5.0V on Arduino UNO
float adcRange;
float temperature;
int kValueAddress; //the address of the K value stored in the EEPROM
char cmdReceivedBuffer[ReceivedBufferLength+1]; // store the serial cmd from the serial monitor
byte cmdReceivedBufferIndex;
float kValue; // k value of the probe,you can calibrate in buffer solution ,such as 706.5ppm(1413us/cm)@25^C
float analogValue;
float voltage;
float ecValue; //before temperature compensation
float ecValue25; //after temperature compensation
float tdsValue;
void readKValues();
boolean cmdSerialDataAvailable();
byte cmdParse();
void ecCalibration(byte mode);
};
#endif
Then there is a .cpp file which I am not sure I understand if this is just an example file as it mentions in the header or if it is where i need to be looking because I cannot find "cal:" anywhere in the .h file but I see it in this file
/***************************************************
DFRobot Gravity: Analog TDS Sensor/Meter
<https://www.dfrobot.com/wiki/index.php/Gravity:_Analog_TDS_Sensor_/_Meter_For_Arduino_SKU:_SEN0244>
***************************************************
This sample code shows how to read the tds value and calibrate it with the standard buffer solution.
707ppm(1413us/cm)@25^c standard buffer solution is recommended.
Created 2018-1-3
By Jason <jason.ling@dfrobot.com@dfrobot.com>
GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution.
****************************************************/
#include <EEPROM.h>
#include "GravityTDS.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);}
GravityTDS::GravityTDS()
{
this->pin = A1;
this->temperature = 25.0;
this->aref = 5.0;
this->adcRange = 1024.0;
this->kValueAddress = 8;
this->kValue = 1.0;
}
GravityTDS::~GravityTDS()
{
}
void GravityTDS::setPin(int pin)
{
this->pin = pin;
}
void GravityTDS::setTemperature(float temp)
{
this->temperature = temp;
}
void GravityTDS::setAref(float value)
{
this->aref = value;
}
void GravityTDS::setAdcRange(float range)
{
this->adcRange = range;
}
void GravityTDS::setKvalueAddress(int address)
{
this->kValueAddress = address;
}
void GravityTDS::begin()
{
pinMode(this->pin,INPUT);
readKValues();
}
float GravityTDS::getKvalue()
{
return this->kValue;
}
void GravityTDS::update()
{
this->analogValue = analogRead(this->pin);
this->voltage = this->analogValue/this->adcRange*this->aref;
this->ecValue=(133.42*this->voltage*this->voltage*this->voltage - 255.86*this->voltage*this->voltage + 857.39*this->voltage)*this->kValue;
this->ecValue25 = this->ecValue / (1.0+0.02*(this->temperature-25.0)); //temperature compensation
this->tdsValue = ecValue25 * TdsFactor;
if(cmdSerialDataAvailable() > 0)
{
ecCalibration(cmdParse()); // if received serial cmd from the serial monitor, enter into the calibration mode
}
}
float GravityTDS::getTdsValue()
{
return tdsValue;
}
float GravityTDS::getEcValue()
{
return ecValue25;
}
void GravityTDS::readKValues()
{
EEPROM_read(this->kValueAddress, this->kValue);
if(EEPROM.read(this->kValueAddress)==0xFF && EEPROM.read(this->kValueAddress+1)==0xFF && EEPROM.read(this->kValueAddress+2)==0xFF && EEPROM.read(this->kValueAddress+3)==0xFF)
{
this->kValue = 1.0; // default value: K = 1.0
EEPROM_write(this->kValueAddress, this->kValue);
}
}
boolean GravityTDS::cmdSerialDataAvailable()
{
char cmdReceivedChar;
static unsigned long cmdReceivedTimeOut = millis();
while (Serial.available()>0)
{
if (millis() - cmdReceivedTimeOut > 500U)
{
cmdReceivedBufferIndex = 0;
memset(cmdReceivedBuffer,0,(ReceivedBufferLength+1));
}
cmdReceivedTimeOut = millis();
cmdReceivedChar = Serial.read();
if (cmdReceivedChar == '\n' || cmdReceivedBufferIndex==ReceivedBufferLength){
cmdReceivedBufferIndex = 0;
strupr(cmdReceivedBuffer);
return true;
}else{
cmdReceivedBuffer[cmdReceivedBufferIndex] = cmdReceivedChar;
cmdReceivedBufferIndex++;
}
}
return false;
}
byte GravityTDS::cmdParse()
{
byte modeIndex = 0;
if(strstr(cmdReceivedBuffer, "ENTER") != NULL)
modeIndex = 1;
else if(strstr(cmdReceivedBuffer, "EXIT") != NULL)
modeIndex = 3;
else if(strstr(cmdReceivedBuffer, "CAL:") != NULL)
modeIndex = 2;
return modeIndex;
}
void GravityTDS::ecCalibration(byte mode)
{
char *cmdReceivedBufferPtr;
static boolean ecCalibrationFinish = 0;
static boolean enterCalibrationFlag = 0;
float KValueTemp,rawECsolution;
switch(mode)
{
case 0:
if(enterCalibrationFlag)
Serial.println(F("Command Error"));
break;
case 1:
enterCalibrationFlag = 1;
ecCalibrationFinish = 0;
Serial.println();
Serial.println(F(">>>Enter Calibration Mode<<<"));
Serial.println(F(">>>Please put the probe into the standard buffer solution<<<"));
Serial.println();
break;
case 2:
cmdReceivedBufferPtr=strstr(cmdReceivedBuffer, "CAL:");
cmdReceivedBufferPtr+=strlen("CAL:");
rawECsolution = strtod(cmdReceivedBufferPtr,NULL)/(float)(TdsFactor);
rawECsolution = rawECsolution*(1.0+0.02*(temperature-25.0));
if(enterCalibrationFlag)
{
// Serial.print("rawECsolution:");
// Serial.print(rawECsolution);
// Serial.print(" ecvalue:");
// Serial.println(ecValue);
KValueTemp = rawECsolution/(133.42*voltage*voltage*voltage - 255.86*voltage*voltage + 857.39*voltage); //calibrate in the buffer solution, such as 707ppm(1413us/cm)@25^c
if((rawECsolution>0) && (rawECsolution<2000) && (KValueTemp>0.25) && (KValueTemp<4.0))
{
Serial.println();
Serial.print(F(">>>Confrim Successful,K:"));
Serial.print(KValueTemp);
Serial.println(F(", Send EXIT to Save and Exit<<<"));
kValue = KValueTemp;
ecCalibrationFinish = 1;
}
else{
Serial.println();
Serial.println(F(">>>Confirm Failed,Try Again<<<"));
Serial.println();
ecCalibrationFinish = 0;
}
}
break;
case 3:
if(enterCalibrationFlag)
{
Serial.println();
if(ecCalibrationFinish)
{
EEPROM_write(kValueAddress, kValue);
Serial.print(F(">>>Calibration Successful,K Value Saved"));
}
else Serial.print(F(">>>Calibration Failed"));
Serial.println(F(",Exit Calibration Mode<<<"));
Serial.println();
ecCalibrationFinish = 0;
enterCalibrationFlag = 0;
}
break;
}
}