Ph meter and TDS meter node driver

Hello. Help write a sensor driver node. There is such a code from the manufacturer, but I don’t understand how to enter it into the program XOD

const int analogInPin = A0;
int sensorValue = 0;
unsigned long int avgValue;
float b;
int buf[10],temp;
void setup() {
Serial.begin(9600);
}

void loop() {
for(int i=0;i<10;i++)
{
buf[i]=analogRead(analogInPin);
delay(50);
}
for(int i=0;i<9;i++)
{
for(int j=i+1;j<10;j++)
{
if(buf[i]>buf[j])
{
temp=buf[i];
buf[i]=buf[j];
buf[j]=temp;
}
}
}
avgValue=0;
for(int i=2;i<8;i++)
avgValue+=buf[i];
float pHVol=(float)avgValue*5.0/1024/6;
float phValue = -5.70 * pHVol + 21.34;
Serial.print("sensor = ");
Serial.println(phValue);

delay(20);
}

Ignoring the extra code to take multiple readings, ignore extremes, and average remaining readings, This can be reduced to: Read the sensor, multiply, add, display result.

image

1 Like

why multiply = -28,5?

Because original code said:

/1024 is already done by XOD analog read (to get 0-1 range); /6 is for average of 6 numbers (which my example doesn’t have); leaving x5.0x(-5.70)

Thanks! can you help with a TDS meter? how to make temperature compensation from a sensor in a node?

float compensationCoefficient=1.0+0.02*(temperature-25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationVolatge=averageVoltage/compensationCoefficient; //temperature compensation
tdsValue=(133.42compensationVolatgecompensationVolatgecompensationVolatge - 255.86compensationVolatgecompensationVolatge + 857.39compensationVolatge)*0.5;

I think you need to quote the code above so * always appears instead of being interpreted as formatting commands

#define TdsSensorPin A1
#define VREF 5.0 // analog reference voltage(Volt) of the ADC
#define SCOUNT 30 // sum of sample point
int analogBuffer[SCOUNT]; // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0,copyIndex = 0;
float averageVoltage = 0,tdsValue = 0,temperature = 25;
void setup()
{
Serial.begin(115200);
pinMode(TdsSensorPin,INPUT);
}
void loop()
{
static unsigned long analogSampleTimepoint = millis();
if(millis()-analogSampleTimepoint > 40U) //every 40 milliseconds,read the analog value from the ADC
{
analogSampleTimepoint = millis();
analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer
analogBufferIndex++;
if(analogBufferIndex == SCOUNT)
analogBufferIndex = 0;
}
static unsigned long printTimepoint = millis();
if(millis()-printTimepoint > 800U)
{
printTimepoint = millis();
for(copyIndex=0;copyIndex<SCOUNT;copyIndex++)
analogBufferTemp[copyIndex]= analogBuffer[copyIndex];
averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF/ 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
float compensationCoefficient=1.0+0.02*(temperature-25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationVolatge=averageVoltage/compensationCoefficient; //temperature compensation
tdsValue=(133.42*compensationVolatge*compensationVolatge*compensationVolatge - 255.86*compensationVolatge*compensationVolatge + 857.39*compensationVolatge)*0.5; //convert voltage value to tds value
//Serial.print("voltage:");
//Serial.print(averageVoltage,2);
//Serial.print("V ");
Serial.print("TDS Value:");
Serial.print(tdsValue,0);
Serial.println("ppm");
}
}
int getMedianNum(int bArray[], int iFilterLen)
{
int bTab[iFilterLen];
for (byte i = 0; i<iFilterLen; i++)
bTab[i] = bArray[i];
int i, j, bTemp;
for (j = 0; j < iFilterLen - 1; j++)
{
for (i = 0; i < iFilterLen - j - 1; i++)
{
if (bTab[i] > bTab[i + 1])
{
bTemp = bTab[i];
bTab[i] = bTab[i + 1];
bTab[i + 1] = bTemp;
}
}
}
if ((iFilterLen & 1) > 0)
bTemp = bTab[(iFilterLen - 1) / 2];
else
bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
return bTemp;
}

That still didn’t come through correctly. You can edit the above entry, select the code, then click on the double-quote or </> icon at the top of the edit box. This will quote the code so it doesn’t try to do formatting. Check the results to the right of the edit window to make sure it is displaying correctly before submitting.

of course…sorry. Even so How to make a node in this case?

This is the important part of the code:

averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF/ 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value float compensationCoefficient=1.0+0.02*(temperature-25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); float compensationVolatge=averageVoltage/compensationCoefficient; //temperature compensation tdsValue=(133.42*compensationVolatge*compensationVolatge*compensationVolatge - 255.86*compensationVolatge*compensationVolatge + 857.39*compensationVolatge)*0.5; //convert voltage value to tds value

If you just want the temp of a single reading, you can ignore the getMedianNum function and just use the sensor value as your initial averageVoltage.

As before, we know the XOD analog-read already does the /1024 for us, so you just need to perform the rest of the calculations on your analog-read output.

In the compensationCoefficent calculation, temparature=25, so equation reduces to just 1, so compensationVoltage is just averageVoltage

There are square & cube nodes, so we can express the final formula as (using voltage as your analog-read value):
Temp = (133.42 * (voltage^3) - 255.86 * (voltage^2) + 857.39 * voltage) * 0.5

I’m guessing if temperatures you are measuring are not close to 25, then you will need to use a different compensationCoefficient.

1 Like

2020-01-19_00-38-44
one more problem. When measuring a TDS meter, it interferes with the PH meter. How to interrogate them in turn? I tried to set the delay, all the same the PH meter readings are distorted

I probably can’t help much with that. I don’t really know that much about the Arduino internals and dependencies. All I can do is make some guesses as to what is happening. There is some chance that ph meter reads restart before TDS meter read and calculations have finished. You could try increasing clock-IVAL to 4 and delay-T to 2 and see if that helps. If you delete the wire between delay-DONE and TDS meter-UPD, ph meter works fine without any other changes?

If removing pulse to TDS meter-UPD doesn’t fix the ph readings, the issue could be your wiring. Do the two meters share any resistors? Just guessing since I don’t know what you have done…

Another option could be that analog read requires a timer & delay or clock is conflicting with that. Using different analog input ports might resolve that issue. (not even sure this could be an issue…just another guess…)

in fact, the voltage tds of the sensor in water interferes with the simultaneous measurement of PH in one water. I’ll try to increase the delay time. Maybe there is some other way to turn on the sensors in series?

Ah…it sounds like the two sensors are shorting out through the water. If they are low-power devices, it might be possible to run their power pin to a digital output pin and only power on one device at a time using digital-write.

NOTE: if you are powering sensors on & off, you may need to wait after powering on to give sensor a chance to stabilize (10ms might be enough…)

powered by pin really helped!

Another problem is that the relay must be turned on when PH is greater than the specified number, and turned off when ph is less than the other specified number. I tried different schemes, but nothing works. If I use one greater node, then the relay works above ph 6.3, but turns off when lowering 6.3. I try to insert a flip flop node so that the relay does not turn off, but then the relay does not turn on at all

its not works

Try stinging the from the greater node to the TGL on the flip flip node and see if it works.

Edit : actually string the greater and lesser nodes to an “or” node and then string that to a “pulse on true node” and then string the the output pulse to the “TGL” on the flip-flop node and I think that should work.

TGL might work, but it runs the risk of getting out of sync (turning off when it should come on and on when it should go off)

I think the example above with greater and less controlling flop-flop should work, but you might have checks backward. You are checking for 6.3 greater than meter instead of meter greater than 6.3. (same for less compare)

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