Assitance with understanding using multiple variations of defined library calls

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;
    }
}

I think this is death by library....I am starting to reverse engineer it (not that complicated for you experts lol but for me its out there)

this is where I am up to so far.

I have 1 sensor reporting data, just need to test with the other 2 sensors and then from there re-engineer the way to update the kValue float which I think will be pretty straight forward, for the moment i can experiment with manually changing it to simulate doing a TDS calibration and see if those values match the example code data.

If you spot something (not sure anyone even is looking at this) please call it out as I might be going about this all the wrong way.

#include <EEPROM.h>
#include "GravityTDS.h"

//Define PinOut
#define TDS_SUP_Pin A0
#define TDS_PREDI_Pin A1
#define TDS_OUT_Pin A2

#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_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 = 1.0; //*************************************************
float kValue_PREDI = 1.0; //*************************************************
float kValue_OUT = 1.0; //*************************************************

int kValueAddress_SUP;
int kValueAddress_PREDI;
int kValueAddress_OUT;

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  //*************************************************
  pinMode(TDS_SUP_Pin,INPUT);  //*************************************************
  GravityTDS_readKValue_SUP();  //*************************************************

  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 GravityTDS_readKValue_SUP(){ //*************************************************
      EEPROM_read(kValueAddress_SUP, kValue_SUP);  
    if(EEPROM.read(kValueAddress_SUP)==0xFF && EEPROM.read(kValueAddress_SUP+1)==0xFF && EEPROM.read(kValueAddress_SUP+2)==0xFF && EEPROM.read(kValueAddress_SUP+3)==0xFF)
    {
      kValue_SUP = 1.0;   // default value: K = 1.0
      EEPROM_write(kValueAddress_SUP, kValue_SUP);
    }
}

void setup() {

  Serial.begin(115200);
  Serial.println("Booting...");
  GravityTDS_setup();
  delay(5000);
}

void loop() {

  GravityTDS_results();
  delay(200);
}

You've done a poor job of explaining what your problem is. You existing code already demonstrates creating 3 instances of the GravityTDS class:

GravityTDS gravityTds_SUP;
GravityTDS gravitytds_PREDI;
GravityTDS gravityTds_OUT;

It already demonstrates how to call the various methods on those instances:

  gravityTds_SUP.update(); 

  gravitytds_PREDI.update();   

  gravityTds_OUT.update();   

The only change I'd make is creating an array instead of the individual instances:

GravityTDS tdsArray[3];

Other than that, what do you feel is lacking?

Thanks for getting back to me, and yes I agree I am not the best at explaining my problem as I am not using the correct terminologies.

Issues I have:

  1. Calibrating the tds sensor, used by typing “ENTER” in the serial, followed by “CAL:” and then the value of the buffer solution.
    I don’t know how I get the project to calibrate sensor 2 and 3, because when I use the serial commands they just update the primary sensor values.

  2. It appears the calibration is lost when the device reboots, which I presume is because I am writing to the EEPROM by calling the “CAL:” function, but not reading from the EEPROM on boot

Could you explain why you suggest the tdsArray[3]?

Reading and acting upon the serial commands happens in the library's update() function. You're calling that on all the instances in the GravityTDS_results() function now, so maybe just add a serial print to display which one is being updated:

  Serial.println("Updating gravityTds_SUP");
  gravityTds_SUP.update();    

etc .....

The library already has an EEPROM read function that's called from begin() and an EEPROM write function that's called if calibration values are entered via update(). So, you shouldn't be trying to implement those yourself.

It would hugely cut the unnecessary redundancy your code currently has in handling each instance separately. You could instead just loop over all elements of the array.

No! The .h and .cpp files are both essential parts of the library. The former is simply a header that describes the library's interface to your application code. The latter contains the actual code that implements the library's functions.

Could you please elaborate on this further? How do I tell the serial (compare) which calibration I am entering?

If I added it, how does the code know to use it? Where else would I reference it?

You don't have to. The library knows which instance you're referring to because you specify it in the call to the class's functions, eg:

  gravityTds_SUP.update();     

You'd modify you application code to use indexed elements of the array rather than individual objects, eg:

   tdsArray[i].begin();

The advantage of this is greatly compacted code because you can handle all instances in a loop rather than individually.

I hope you can appreciate I’m still a bit confused so I’ll apologise in advance.

Would you be able to show me how my code would be different using this array functionality, I don’t quite understand it sorry :frowning:

So with the calibration I hear what you’re saying about it knowing what function it is in to know where to calibrate, however this is where I’m getting stuck.

I send the firmware, it begins giving me readings etc, but then for the calibration function to work, I click on serial monitor and type “ENTER” then press the enter key, then it calls the calibration function, but that’s where I’m stuck, it only seems to calibrate the 1st tds function, I don’t know how to tell it I want to send that call to the second function.

I can post a video in case I’m not making any sense.

I originally thought you could put a serial print to inform the user which instance is being updated before each call to update() in your GravityTDS_results() function. Something like this:

  Serial.println("Updating gravityTds_SUP");
  gravityTds_SUP.update();

  Serial.println("Updating gravityTds_PREDI");
  gravityTds_PREDI.update();

  Serial.println("Updating gravityTds_PREDI");
  gravityTds_OUT.update();

But, upon further reading the the library's code, I see it's timing will make that nearly impossible without adding ugly delays to your code.

So, I'm changing my advice to .... dump that library, it's crap. You'll be much better off learning enough coding to implement it's functionality in your own code. It can be done without using C++ classes. Or, perhaps, you can find a better library.

As far as arrays go, you should set that idea aside until you learn more coding. Sorry for bringing it up at this stage. There are any number of online resources, books, community college courses, etc. that can help you with that.

1 Like

Thank you all, I think this is why I said death by library, I started to realise most of it was just a bit silly to rely on so I started building out the code to have individual updates and variables.

Thank you so much for your replies though it’s what I was expecting to hear, I will take your advice and look into some basic classes to learn a bit more. Thank you so much for your time thus far

yep this is what I was saying i ended up realising lol, especially when i got my head around the library etc I realised how much i was relying on what seemed to be a super basic library

this is what I have so far but will end up working more on this in a few days, if you notice anything in there that is poor please let me know if you're bothered.

I plan to do away with the GravityTDS.h once I remove all the code dependent on it, i felt silly when i realised how simple the equation was.

#include <EEPROM.h>
#include "GravityTDS.h"

//Define PinOut
#define TDS_SUP_Pin A0
#define TDS_PREDI_Pin A1
#define TDS_OUT_Pin A2

#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 ReceivedBufferLength 15
#define TdsFactor 0.5  // tds = ec / 2

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; //*************************************************
float analogValue_SUP; //*************************************************
float voltage_SUP; //*************************************************
float ecValue_SUP; //*************************************************
float ecValue25_SUP; //*************************************************

int kValueAddress_SUP;
int kValueAddress_PREDI;
int kValueAddress_OUT;

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  //*************************************************
  pinMode(TDS_SUP_Pin,INPUT);  //*************************************************
  GravityTDS_readKValue_SUP();  //*************************************************

  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
  GravityTDS_update_SUP(); //*************************************************
  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 GravityTDS_readKValue_SUP(){ //*************************************************
      EEPROM_read(kValueAddress_SUP, kValue_SUP);  
    if(EEPROM.read(kValueAddress_SUP)==0xFF && EEPROM.read(kValueAddress_SUP+1)==0xFF && EEPROM.read(kValueAddress_SUP+2)==0xFF && EEPROM.read(kValueAddress_SUP+3)==0xFF)
    {
      kValue_SUP = 1.0;   // default value: K = 1.0
      EEPROM_write(kValueAddress_SUP, kValue_SUP);
    }
}

void GravityTDS_update_SUP() //*************************************************
{
	analogValue_SUP = analogRead(TDS_SUP_Pin);
	voltage_SUP = analogValue_SUP/1024*5.0;
	ecValue_SUP=(133.42*voltage_SUP*voltage_SUP*voltage_SUP - 255.86*voltage_SUP*voltage_SUP + 857.39*voltage_SUP)*kValue_SUP;
	ecValue25_SUP  =  ecValue_SUP / (1.0+0.02*(temperature-25.0));  //temperature compensation
	tdsValue_SUP = ecValue25_SUP * TdsFactor;
/*
	if(cmdSerialDataAvailable() > 0)
        {
            ecCalibration(cmdParse());  // if received serial cmd from the serial monitor, enter into the calibration mode
        }
*/        
}


void setup() {

  Serial.begin(115200);
  Serial.println("Booting...");
  GravityTDS_setup();
  delay(5000);
}

void loop() {

  GravityTDS_results();
  delay(200);
}

So just curious if you can confirm I am on the right track here. I have realised the ESP32 uses SPIFFS not EEPROM so I have excluded any of the calibration functions for now.

//Define PinOut
#define TDS_SUP_Pin A0
#define TDS_PREDI_Pin A1
#define TDS_OUT_Pin A2

#define ReceivedBufferLength 15
#define TdsFactor 0.5  // tds = ec / 2

float tdstemp = 25; 
float tdsAref = 5.0; 
float tdsAdcRange = 1024.0; 
float temperature;

float tdsValue_SUP = 0;
float kValue_SUP = 1.0; 
float analogValue_SUP; 
float voltage_SUP; 
float ecValue_SUP; 
float ecValue25_SUP; 


int kValueAddress_SUP[4];
int prevtdsValue_SUP;


float tdsValue_PREDI = 0;
float kValue_PREDI = 1.0; 
float analogValue_PREDI; 
float voltage_PREDI; 
float ecValue_PREDI; 
float ecValue25_PREDI; 


int kValueAddress_PREDI[8];
int prevtdsValue_PREDI;


float tdsValue_OUT = 0;
float kValue_OUT = 1.0; 
float analogValue_OUT; 
float voltage_OUT; 
float ecValue_OUT; 
float ecValue25_OUT; 


int kValueAddress_OUT;
int prevtdsValue_OUT;


char w_tdsValue_SUP[8];
char w_tdsValue_PREDI[8];
char w_tdsValue_OUT[8];

char SUP_kValue[8];
char PREDI_kValue[8];
char OUT_kValue[8];


void setup_TDS(){

  //Supply TDS Setup
  pinMode(TDS_SUP_Pin,INPUT);
  pinMode(TDS_PREDI_Pin,INPUT);
  pinMode(TDS_OUT_Pin,INPUT);
  readKValues();  
}

void readKValues(){ 
  kValue_SUP = 1.0;   // default value: K = 1.0
  kValue_PREDI = 1.0;   // default value: K = 1.0
  kValue_OUT = 1.0;   // default value: K = 1.0
}

void update_TDS(){ 

	analogValue_SUP = analogRead(TDS_SUP_Pin);
	voltage_SUP = analogValue_SUP/tdsAdcRange*tdsAref;
	ecValue_SUP=(133.42*voltage_SUP*voltage_SUP*voltage_SUP - 255.86*voltage_SUP*voltage_SUP + 857.39*voltage_SUP)*kValue_SUP;
	ecValue25_SUP  =  ecValue_SUP / (1.0+0.02*(temperature-25.0));  //temperature compensation
	tdsValue_SUP = ecValue25_SUP * TdsFactor;

	analogValue_PREDI = analogRead(TDS_PREDI_Pin);
	voltage_PREDI = analogValue_PREDI/tdsAdcRange*tdsAref;
	ecValue_PREDI=(133.42*voltage_PREDI*voltage_PREDI*voltage_PREDI - 255.86*voltage_PREDI*voltage_PREDI + 857.39*voltage_PREDI)*kValue_PREDI;
	ecValue25_PREDI  =  ecValue_PREDI / (1.0+0.02*(temperature-25.0));  //temperature compensation
	tdsValue_PREDI = ecValue25_PREDI * TdsFactor;

	analogValue_OUT = analogRead(TDS_OUT_Pin);
	voltage_OUT = analogValue_OUT/tdsAdcRange*tdsAref;
	ecValue_OUT=(133.42*voltage_OUT*voltage_OUT*voltage_OUT - 255.86*voltage_OUT*voltage_OUT + 857.39*voltage_OUT)*kValue_OUT;
	ecValue25_OUT  =  ecValue_OUT / (1.0+0.02*(temperature-25.0));  //temperature compensation
	tdsValue_OUT = ecValue25_OUT * TdsFactor;

}        

void calculate_TDS(){
  temperature = tdstemp;
  update_TDS();
  delay(3000);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Booting...");
  setup_TDS();
  delay(5000);
}

void loop() {
  calculate_TDS();
  Serial.print(tdsValue_SUP,0);
  Serial.println("ppm");
  Serial.print(tdsValue_PREDI,0);
  Serial.println("ppm");
  Serial.print(tdsValue_OUT,0);
  Serial.println("ppm");
  delay(200);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.