Calculations / Programming with Millone e-Tape

I’m using etape with an arduino uno and ethernet shield. Currently I’m using the programming shown below. The problem I’m having is probably a simple math issue, but I’m not sure. Essentially what is happening is I’m getting a 100% full reading when the container is full, but as it drains, I get 100% + readings. In other words, as the container drains, the readings go up, 101%, 102%, etc. The appnotes say to convert the analog reading to a digital value first, but that didn’t seem necessary when you can still calculate the percentage based on standard numbers. Anyways, I’ve spent hours trying to figure this out tonight, and I’d appreciate any help.

Here are a few links as well:
Appnotes: http://www.adafruit.com/datasheets/eTapeApp.pdf
e-Tape : https://www.adafruit.com/products/463

Thank you!

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;
int sensorMin = 550;
int sensorMax = 700;
void setup()
{
  // initialize serial communication with computer:
  Serial.begin(9600);                 
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;         
}
// the loop routine runs over and over again forever:
void loop() {
   // subtract the last reading:
  total= total - readings[index];       
  // read from the sensor: 
  readings[index] = analogRead(inputPin);
  // add the reading to the total:
  total= total + readings[index];     
  // advance to the next position in the array: 
  index = index + 1;                   

  // if we're at the end of the array...
  if (index >= numReadings)             
    // ...wrap around to the beginning:
    index = 0;                         

  // calculate the average:
  average = total / numReadings;       
  // send it to the computer as ASCII digits
  Serial.println(average); 
  float depth = sensorMax - average;
  Serial.println(depth);
  float depth2 = sensorMax - sensorMin;
  Serial.println(depth2);
  float percentFull = (depth / depth2) * 100;
  Serial.print("Percent Full %");
  Serial.println(percentFull);
  delay(10);
}

Son of a butt...I think I figured it out. Because I know virtually nothing about this arduino stuff, I assumed because I was using what adafruit calls a resistor divider (according to the tutorials tab) that I should use the divider example from the appnotes. However, once I read the inverting opp amp example, that seems like it should be the ticket. Unfortunately I'm not with my arduino at the moment so I cannot test it out. Hopefully this is the ticket, I'll find out tomorrow!

Yes, right . There are two experiments, reading data from sensor configured with resistor 560, and second one with inverting OPA. Math, of course , different. What more, there is two calibration constant:

int sensorMin = 550;
int sensorMax = 700;

that you have to measure with empty and full tank

So are you saying that my second equation should work?

I can't tell, till you post how you wired up sensor, as 1-st or 2-nd variant?

ah, sorry. I wired it according to the adafruit tutorial which they call a resistor divider.

Page 6:

V at Pin 2 = [Vdd x R eTape] / [ 2K? + R eTape]
The eTape sensor has lower resistance at higher liquid levels and higher resistance at lower liquid levels.
Therefore the maximum digital Voltage reading corresponds to an empty tank and minimum digital
Voltage reading corresponds to a full tank. Figure 7 depicts this relationship.

Adafruit says 560 OHm, but App Note using 2 K resistor. My guess, you have 560, so right formula: V in = [Vdd x R eTape] / [ 560 + R eTape]

And page 7:
...2. Take measurement, convert analog voltage to a digital value. - This is done in your code via "analogRead"
3. Subtract the measured digital value from the maximum digital value of the circuit (empty tank) - Maximum digital value is 1-st calibration constant, must be measured and known before this step.
and divide by range (maximum – minimum digital values) – this gives percent full. - Same here, Minimum digital value is 2-nd calibration constant, must be measured and known before this step.
4. Multiply the sensor length by the percent full value to get liquid level in cm.
5. Compute volumes.

I'll be honest, most of what you said is over my head. However, from what I gather you pretty much quoted me the same instructions I followed... for the most part. I took the last part out, step 4-5, because I only want to know the percent full, I don't care to know the exactly volumes.

Figure 7:
( sensorMax - average ) / (sensorMax - sensorMin) = %Full.

  float depth = sensorMax - average;
  Serial.println(depth);
  float depth2 = sensorMax - sensorMin;
  Serial.println(depth2);
  float percentFull = (depth / depth2) * 100;

Right.

OK, but you didn't really answer my question then. It seems you basically told me that the way I have calculated the percent full is correct. However, as the tank empties, the percent full goes up 100, 102, 103, when it should go down, 100, 99, 98.

I told you :

What more, there is two calibration constant:
Quote
int sensorMin = 550;
int sensorMax = 700;
that you have to measure with empty and full tank

If this digits not correctly measured BEFORE you make any calculation, you would get any wrong behavioral strangeness ever possible.

Correct, and I agree. The numbers I put into the code that you see are from me taking measurements with the tank full and the tank empty.

And which one corresponds to empty tank?

int sensorMin = 550; refers to tank empty.

No. According to :

  1. Subtract the measured digital value from the maximum digital value of the circuit (empty tank)

Is it possible, that you "swapped" ground-Vss and Vdd as it shown on figure 6?

I have double checked that. The way I understand, the two outside pins are Rref (1 and 4) pins, and the inside pins (2 and 3) are the Rsense pins. I Connected pin #2 of the sensor to ground, then pin #3 to a 560 ohm resistor. The other side of the 560 ohm resistor to the 5V on the Arduino. I then connected pin #4 to the point between the resistor and sensor and pin #1 to the A0 on the Arduino. Does that make sense?

Right now the data is just inverted, so it seems if I use the equation from the invert op example it would work. I just need to try it. Hopefully later today I'll get a chance.

Here is re-print from Adafruit tutorial:

Connect pin #2 of the sensor to ground, then pin #3 to a 560 ohm resistor. The other side of the 470 ohm resistor to VCC (3.3V or 5V for example) to create a resistor divider. The ADC pin connects to the point between the resistor and sensor.

Frankly, I have no clue what pin 1 or 4 made for, as I don't have sensor around. If you have a multimeter, you probably could "buzz" if there is "inter-connections" between 4 pins.
Or, wait a moment, http://www.adafruit.com/datasheets/eTape_Datasheet_12110215TC-8.pdf
says

The outer pins (pins 1 and 4) are the reference resistor (Rref) which can be used for temperature compensation.

Don't think you need pin 1 and 4 now, first follow adafruit tutorial. After you figure out all "strangeness" with inverse in data, you could "upgrade" hardware configuration with Wheatestone bridge, OPA, differential amplifier etc.