water based potentiometer

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100

My project aims at finding x-coordinate of point of contact of finger and water surface using a rectangle-base box containing water with metal plate electrodes on both ends of the water.I am using the Arduino Uno R3.
So to minimize electrolysis even further and to get more real-time data,I will constantly swap the polarity of the voltage across the water and I need to increase the frequency of the pulse to match ADC sampling frequency / 12 (12=4 phases in 1 cycle * 3 analog inputs). But what is the ADC sampling frequency?. The page analogRead() says "so the maximum reading rate is about 10,000 times a second."To increase sampling frequency ,I decided that Arduino only prints raw analog data to my laptop and let my Java app do the rest calculation.I'll have to use Java to find the frequency at which Arduino prints analog data and then ,accordingly, decide the pulse frequency (injected into water).
Code:
void setup(){
Serial.begin(115200);
analogReference(INTERNAL); // 1.1V
}
void loop(){
Serial.println(analogRead(2));
Serial.println(analogRead(3));
Serial.println(analogRead(4));
}
the analog readings of pins A2 and A3( placed close to ,but not touching the metal plates at the two ends of the water) were offset by 150 units(that too fluctuates with time) .So I came up with this solution - A2 and A3 are read in real-time along with A4(finger electrode) and distance calculated by--
20cm * (dA4-dA3) / (dA2-dA3) .Here, dA2, dA3, dA4 denotes difference in the analog readings taken in the 1st and 2nd phase of the input pulse. This is the distance from right end(refer schematic).
So, in the 3rd and 4th phase of the input pulse the voltage at both ends of the water drops to -0.3V(to account for the skin generating bio-voltage of order 10mV<<0.3V) that must read as 0 at A4 and then rises up to 2V that must read as 1023 ,when the finger is dipped in water. When finger is outside the water it is very unlikely for A4 to read every 3rd and 4th input as 0 and 1023, in that same order, with that same frequency(due to noise, bio-voltages , etc). That detects whether finger is dipped even slightly or not.
Just that dipping my fingers depper into water changes skin impedance and hence the analog reading. Any way round this can you suggest?
 

ebeowulf17

Joined Aug 12, 2014
3,307
I don't think there's any predetermined adc sampling frequency. There's an upper limit to how fast it can go, but I think if you want a predictable frequency you should simply code accordingly. Do however many analog reads you want for each polarity, swap polarities, and do the next ones. If you want precision timing, you can use micros() or millis() for time references to determine when to take your next action. If you just want the correct number of reads per polarity switch, code in that number of reads before you code in the next polarity switch. I believe it's all in your hands!

As for locating a finger in water with those readings, I'm somewhat skeptical. I'm no expert though, and I'd love to be proven wrong, because it sounds pretty cool. Good luck!
 

DickCappels

Joined Aug 21, 2008
10,661
You might want to try a FET input voltage follower between your finger and the ADC input (assuming that is what A4 is. A large resistor and a capacitor to ground on the input to the buffer will assure that the input to the buffer drifts down toward ground when there is no finger in the circuit and (this is what the capacitor does) there is no large AC signal that the ADC might interpret as your finger jumping around.
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
If you want precision timing, you can use micros() or millis() for time references to determine when to take your next action. If you just want the correct number of reads per polarity switch, code in that number of reads before you code in the next polarity switch. I believe it's all in your hands!
No I want precision timing, so I will use micros() or millis() for time references to synchronise the signal with the analog read.
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
As for locating a finger in water with those readings, I'm somewhat skeptical. I'm no expert though, and I'd love to be proven wrong, because it sounds pretty cool. Good luck!
yeah , it's working pretty fine, but I need more precise analog inputs to locate the finger accurately.
Just that dipping my fingers depper into water changes skin impedance and hence the analog reading. Any way round this can you suggest?
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
As for locating a finger in water with those readings, I'm somewhat skeptical. I'm no expert though, and I'd love to be proven wrong, because it sounds pretty cool. Good luck!
alright, now this is really weird.(Note:- I'm powering the Arduino Uno and reading Serial data using my mobile phone and i'm outdoor ,away from ac mains hum)

->both water electrodes at GND , finger dipped into water, the analog input pin connected to my finger read ~60 units(AREF=DEFAULT (+5V) so 60 = +0.292V)
-> both water electrodes at +3.3V ,finger dipped into water, the analog input pin connected to my finger read ~740 units(AREF=DEFAULT (+5V) so 740 = +3.613V ). Input voltage was offset by +3.613 - 3.3V = +0.313V
->both water electrodes at GND ,finger dipped into water, the analog input pin connected to my finger read ~300 units(AREF=INTERNAL (+1.1V) so 300 = +0.322V)
->both water electrodes at GND , finger dipped into water, the analog input pin connected to my finger read ~100 units(AREF=EXTERNAL (+3.3V) so 100 = +0.322V)


->both water electrodes at GND ,the analog input pin itself dipped into water read ~40 units(AREF=DEFAULT (+5V) so 40 = +0.195V)
->both water electrodes at +3.3V ,the analog input pin itself dipped into water read ~720 units(AREF=DEFAULT (+5V) so 720 = +3.515V) Input voltage was offset by +3.515V - 3.3V = +0.215V
->both water electrodes at GND ,the analog input pin itself dipped into water read ~210 units(AREF=INTERNAL (+1.1V) so 210 = +0.225V)
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
alright now i need not worry about those funny voltages , since I'll be swapping polarity and considering the difference of the analog reads.Thus, the offset voltage will not change the final calculated distance. This is another reason to constantly swap polarity.
I think the only solution to the problem of varying voltage due to dipping the finger deeper is to insulate the rest of finger with electric tape, and allow only a small portion of my finger to be exposed.
But one last doubt, how do I detect whether the finger is still dipped in water or not ? Because the method I'd thought of earlier requires both water electrodes to be at the same voltage , and when read by analog input , it will have some offset.Please suggest a better method to detect whether the finger is still dipped in water or not .
 
Last edited:

DickCappels

Joined Aug 21, 2008
10,661
Reconsider my suggestion in post #3. If your finger does not load down your water curcuit the contact resistance should not matter. That is, provided that I understand your circuit.
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
I don't think there's any predetermined adc sampling frequency. There's an upper limit to how fast it can go, but I think if you want a predictable frequency you should simply code accordingly. Do however many analog reads you want for each polarity, swap polarities, and do the next ones. If you want precision timing, you can use micros() or millis() for time references to determine when to take your next action. If you just want the correct number of reads per polarity switch, code in that number of reads before you code in the next polarity switch. I believe it's all in your hands!

As for locating a finger in water with those readings, I'm somewhat skeptical. I'm no expert though, and I'd love to be proven wrong, because it sounds pretty cool. Good luck!
Reconsider my suggestion in post #3. If your finger does not load down your water curcuit the contact resistance should not matter. That is, provided that I understand your circuit.
I did it , I built a water touchpad sensor to track the position of my right index fingertip on a water surface! . Here's the Youtube video link -
 

Thread Starter

Sumit Aich

Joined Dec 3, 2016
100
That's super-cool! Great job.
Here's the Arduino c++ code for the project DIY Water Touchpad -
Code:
/* Project Title- DIY WATER TOUCHPAD
   Author- Sumit Aich
   Project Summary- The basic idea behind this sensor is the use of a parallelopiped water container
   as a water potentiometer device. It is similar to a 3-pin slide pot used in electronic circuits,
   with the 2 aluminium electrodes equivalent to the 2 end pins of a slide pot,
   and the right index fingertip is equivalent to the middle pin (voltage output) of a slide potentiometer.
   */

#define ELECTRODE_0  2  //left water electrode
#define ELECTRODE_1  3  //right water electrode
#define SENSOR_ADC   0  //right index fingertip (Vout of water potentiometer)
#define OFFSET_0     1  //left offset pin
#define OFFSET_1     2  //right offset pin
#define BAUDRATE 2000000

long offset_0,  //voltage at left offset pin
     offset_1,  //voltage at right offset pin
     read_0,    //fingertip voltage
     m, m1; //horizontal displacement of fingertip from OFFSET_0 pin (range from 0 to 50000)

void setup() {
  pinMode(ELECTRODE_0, OUTPUT);
  pinMode(ELECTRODE_1, OUTPUT);

  //set both water electrodes to +5V to pause electrolysis for a while
  digitalWrite(ELECTRODE_0, 1);
  digitalWrite(ELECTRODE_1, 1);
  Serial.begin(BAUDRATE);
  analogReference(DEFAULT);

}

void loop() {

  //Phase 1
  //swap polarity of voltage drop across water
  digitalWrite(ELECTRODE_0, 0);
  offset_0 = analogRead(OFFSET_0);
  offset_1 = analogRead(OFFSET_1);
  read_0 = analogRead(SENSOR_ADC);

  //check whether fingertip is inside or outside water
  digitalWrite(ELECTRODE_0, 1);
  if (analogRead(SENSOR_ADC) != 1023)
  {
    m = 51000;
  }
  else {
    m =  constrain((50000 * (read_0 - offset_0) / (offset_1 - offset_0)), 0, 50000);
  }
  Serial.print('$');//format requirement for SerialPortPlotter.exe
  Serial.print(m);//print horizontal displacement of fingertip from OFFSET_0 pin (range from 0 to 50000)
  Serial.println('\;');//format requirement for SerialPortPlotter.exe

  /*this delay is just a frequency restriction imposed by SerialPortPlotter.exe
    otherwise, it is not required if you are NOT using SerialPortPlotter.exe.
  */
  delay(10);

  //Phase 2
  //swap polarity of voltage drop across water
  digitalWrite(ELECTRODE_1, 0);
  offset_0 = analogRead(OFFSET_0);
  offset_1 = analogRead(OFFSET_1);
  read_0 = analogRead(SENSOR_ADC);

  //check whether fingertip is inside or outside water
  digitalWrite(ELECTRODE_1, 1);
  if (analogRead(SENSOR_ADC) != 1023)
  {
    m = 51000;
  }
  else {
    m1 = constrain((50000 * (offset_0 - read_0) / (offset_0 - offset_1)), 0, 50000);
  }
  Serial.print('$');//format requirement for SerialPortPlotter.exe
  Serial.print(m);//print horizontal displacement of fingertip from OFFSET_0 pin (range from 0 to 50000)
  Serial.println('\;');//format requirement for SerialPortPlotter.exe

  /*this delay is just a frequency restriction imposed by SerialPortPlotter.exe
    otherwise, it is not required if you are NOT using SerialPortPlotter.exe.
  */
  delay(10);

}
 
Top