Pages: [1] 2   Go Down
Author Topic: Water TDS Measurement  (Read 2730 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone,
i was wondering if it's possible to make this type of TDS measurement work on a arduino. Here is the link http://hal.inria.fr/docs/00/63/56/52/PDF/TDS_Logger_RJP2011.pdf
He used a pic 18. I've done some experimenting with my arduino , breadboarded a circuit, wrote the code, and tested it with my oscilloscope. I don't think the arduino has the right kind of outputs...watching the oscilloscope the arduino pins seem to drain to ground then set to INPUT. You'd have to read the info in the link above to understand why that's a problem. smiley   Someone PLEASE prove my wrong.... smiley I'd love this to work...its so simple. I'd use a pic but, I'd have to learn to write code for one first and that seems alot trickier than arduino from want i've seen so far. I haven't been looking very long.
Thanks, Red
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 74
Posts: 7256
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Red,

I am not in your field but I have done contract work with water sensing and have the right background to understand your problem. Arduino has the right pins for your application. You may have set the pins or circuits wrong. BTW, fig.1 is missing a resistor. Trying to charge a capacitor without a resistor is going to damage the pins.

Show some pictures of your circuit and post your code. I can try to help you.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's been awhile since, I did those experiments. I'm getting close the to actually build the project now. posting on the forum was the last try at it with arduino before learning to program and buying hardware for the pic.  the circuit was exactly the same as fig 1 but, I had a resister in place for Rx (i didn't have a tds probe to play with). i tried many different values of resistors. Can't find the sketch i wrote back then. I think i may have deleted it after reading somewhere that the pins on the arduino where wrong kind. As far as the code i wrote, it basically went step by step with whats on page 3, in that paper i linked, changing pinModes to match the step and testing on the right pin using a while loop and a counter to see how long that pin was HIGH (i try many different delayMicroseconds in the while loop very small to larger to no delay at all).  It also showed a picture on page 4 of what the oscilloscope should look like. testing the circuit with my oscilloscope it looked like very straight  up and down spikes on the scope, like when pins  switched to an INPUT, the pin grounded and the voltage in the cap dropped very fast without going thru the resister. This  seemed to support what i read about the pins being wrong so, i gave up at the time.  I'll have to rebuild the experiment again. I'll be able to do a much better job of now, having a lot more practice writing code for the arduino.
thanks, red
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17301
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some basic background info:

Quote
Inside of a TDS meter is an electrical circuit which measures the resistance between its two electrodes when immersed in a liquid. This circuit applies an AC voltage to the electodes, and then measures the AC current which flows between the two electrodes. This reading is then corrected for temperature (if its a high quality instrument), and electrode geometry. The result is a measure of Total Ionic Content. The name Total Dissolved Solids is actually a misnomer, as a lot of dissolved solids will not read at all on a TDS meter since they do not ionize when they dissolve. Sugar is such a substance. If you were to dissolve a tablespoon of table sugar in a cup of distilled water and read it with a TDS meter, the resulting reading would be zero.

The reason AC is used instead of DC voltage on the electrodes is to keep the metals in the solution from plating onto the electrodes. With AC, anything that plates onto the negative electrode will in theory come off when the polarity reverses. AC also keeps the ions from migrating from one electrode to the other, thereby keeping the solution homogeneous.

Lefty
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 74
Posts: 7256
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If the curve you found drops too fast compared with fig. 4, your fake resistor rx is too small. Conductivity of some turbid water is very low. If you use a very large resistor to simulate the water, you will see a gradual drop in voltage instead of straight drops.
Logged


UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've done some experimenting with my arduino , breadboarded a circuit, wrote the code, and tested it with my oscilloscope. I don't think the arduino has the right kind of outputs...watching the oscilloscope the arduino pins seem to drain to ground then set to INPUT.

That behaviour is presumably not what you intended, so there is something wrong with your hardware or software or both. We'd need to see your circuit diagram and software to have any hope of guessing what's wrong.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I rewrote the code. its a little different than whats in the paper. I know its going to have to change to work in my project.  as it is this isn't working on the scope or with serial display. I know its likely a simple problem I'm just missing.
thanks, red

//  capacitor based TDS measurement

// pin 10 C+ -750K resistor---|----------|
//                            |          |     
//                      3.3 nF cap      5.6 M      to simulate Rx
//                            |         Resistor
// pin 9 C- --750K resistor---|          |
//                                       |
// pin 8 EC -----------------------------|

int capPos = 10; //C+
int capNeg = 9;  //C_
int EC = 8;      //EC

unsigned int timesThruAverage; //times thru "still high while loop"

void setup(){
Serial.begin(9600);
}

void loop (){
timesThruAverage = getTdsAverage(); //goto measuring function
Serial.println (timesThruAverage);   //display average times thru loop
delay(1000);
}

unsigned int getTdsAverage(){
 
  unsigned int timesThru = 0;
  unsigned int setDelay = 0;
  unsigned int runningTotal = 0;

  for(int i;i<100;i++){ //get a average of 100 times thru still high while loop
    //charge cap
    pinMode (capPos,OUTPUT);
    pinMode (capNeg, OUTPUT);
    pinMode (EC, INPUT);
    digitalWrite (capPos, HIGH);
    digitalWrite (capNeg, LOW);
    delayMicroseconds(100);
    //let cap drain thru Rx
    pinMode (capPos,INPUT); //set C+ to input to keep voltage from grounding a discharging thru this output pin
    pinMode (EC, OUTPUT); 
    digitalWrite (EC, LOW);
    //test to see how many times still high loop is HIGH before it goes low
    while (capPos == HIGH){ //still high loop
      timesThru += 1;
      delayMicroseconds (10);
    }
    setDelay = timesThru * 10; //set delays down the line so freq has even phases
    //fully discharge cap
    pinMode (capPos,OUTPUT);
    pinMode (capNeg, OUTPUT);
    pinMode (EC, INPUT); 
    digitalWrite (capPos, LOW);
    digitalWrite (capNeg, LOW);
    delayMicroseconds (setDelay);
   
    //the unmeasured half of ac phase
    pinMode (EC, OUTPUT);
    digitalWrite (EC, HIGH);
    delayMicroseconds(setDelay);
   
    runningTotal += timesThru;
  }
timesThru = runningTotal / 100;
return timesThru;
}
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

//  capacitor based TDS measurement

// pin 10 C+ -750K resistor---|----------|
//                                     |            |     
//                             3.3 nF cap      5.6 M      to simulate Rx
//                                     |          Resistor
// pin 9 C- --750K resistor----              |
//                                                   |
// pin 8 EC --------------------------------|
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hope that circuit is understandable. posting seems to mess it up
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 74
Posts: 7256
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The circuit is understandable. You don't need the resistor between pin 10 and capacitor to be so big as 750K something smaller will help charging the capacitor faster yet still restrict the current so it won't damage arduino. Something like 150ohm will be all you need. The other 750Kohm resistor between pin 9 and capacitor is not needed.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey, i made those changes. it's still is not working. probing with the oscilloscope shows a very ugly and noisily picture. the cap never gets charged to more than 1 volt in either direction. i ve got a rigol 1102e 1 GSa/s scope if that makes any difference. maybe the pins aren't switching between OUTPUT,  INPUT and or states fast enough. maybe writing the port registers directly would help.
thanks, red
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 74
Posts: 7256
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you post a screen shot of your scope?

The time constant for your setup is resistance * capacitance. You may calculate it yourself with what new value of resistance you used. You are waiting 100 microseconds. If the time constant is not in the order of 20-30 microseconds, you are not giving enough time to charge. I saw your code, your charging is right. I'm yet to read the rest of your code.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm going to work on changing the code to use the port registers directly. from what i've read it makes the code a good deal faster and changes all the pins at once. i'm afraid the charge in the cap is draining before it can be test.
red
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think that is writing right. because it doesn't work. I changed the circuit and code a bit. I hope someone can understand the help me fix the problem.
here is the new circuit and code. thanks, red
//  capacitor based TDS measurement

// pin 10 C+ - 150 ohm resistor----------|------------|       
//                                                   |               |
//                                             3.3 nF cap      760 ohm   to simulate Rx
//                                                   |           Resistor
// pin 9 C- --------------------------------|
//                                                                   |
// pin 8 EC ---------------------------------------------|

unsigned int timesThruAverage; //times thru "still high while loop"

void setup(){
Serial.begin(9600);
 
}
void loop (){
timesThruAverage = getTdsAverage(); //goto measuring function
Serial.println (timesThruAverage);   //display average times thru loop
delay(1000);
}

unsigned int getTdsAverage(){
 
  unsigned int timesThru = 0;
  unsigned int setDelay = 0;
  unsigned int runningTotal = 0;

  for(int i;i<100;i++){ //get a average of 100 times thru still high while loop
    //charge cap
    DDRB = B110;
   
   PORTB |= B100;
   delayMicroseconds(50);
    //let cap drain thru Rx
    DDRB = B011;
    PORTB = B000;
    //test to see how many times still high loop is HIGH before it goes low
    while (PINB & (1<<PINB2) == 1){ // while ill high loop on pin d10
      timesThru += 1;
      delayMicroseconds (10);
    }
    setDelay = timesThru * 10; //set delays down the line so feq has even phases
    //fully discharge cap
    DDRB = B110;
   
    PORTB = B000;
     delayMicroseconds (setDelay);
     // the other side or the ac wave this side is unmeasured
    DDRB = B111;
    PORTB = B001;
    delayMicroseconds(setDelay);
    PORTB = B000;
   
    runningTotal += timesThru;
  }
timesThru = runningTotal / 100;
return timesThru;
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 638
Posts: 50304
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  for(int i;i<100;i++){ //get a average of 100 times thru still high while loop
No. You have no clue how many times this will loop BECAUSE YOU ARE NOT INITIALIZING the loop index.

Local variables, like i, are not given initial values by the compiler. YOU have to do that.

Logged

Pages: [1] 2   Go Up
Jump to: