The Tank Monitor Calibration Lab
Press the pushbutton to test the interactive circuit in real time.
- Arduino Uno microcontroller board
- LED indicator (green)
- 220 ohm current-limiting resistor
- Tactile pushbutton switch
- Jumper wires (male-male)
🔧 Build Your Piece-Wise Calibration Lab
struct CalPoint { float depth; float volume; };
const CalPoint table[] = {
{0.0, 0.0},
{30.0, 120.0}, // Conical base transition
{70.0, 600.0}, // Mid cylinder
{100.0, 1200.0} // Full capacity
};
const int NUM_POINTS = 4;
float interpolateVolume(float measuredDepth) {
if (measuredDepth <= table[0].depth) return table[0].volume;
if (measuredDepth >= table[NUM_POINTS-1].depth) return table[NUM_POINTS-1].volume;
for (int i = 0; i < NUM_POINTS - 1; i++) {
if (measuredDepth >= table[i].depth && measuredDepth <= table[i+1].depth) {
float slope = (table[i+1].volume - table[i].volume) / (table[i+1].depth - table[i].depth);
return table[i].volume + slope * (measuredDepth - table[i].depth);
}
}
return 0.0;
}
void setup() {
Serial.begin(9600);
float testDepths[] = {15.0, 30.0, 50.0, 85.0};
for (float d : testDepths) {
Serial.print("Depth: "); Serial.print(d);
Serial.print(" cm -> True Volume: ");
Serial.print(interpolateVolume(d)); Serial.println(" Liters");
}
}
void loop() {}
Piece-wise linear interpolation models irregular tank geometry accurately without heavy polynomial calculations.
⚗️ Test your model
| Test Condition / Action | Expected Result |
|---|---|
| Depth = 15cm (In Conical Base) | Interpolates on segment 1: outputs 60.0 Liters (slope = 4.0 L/cm) |
| Depth = 30cm (Transition Point) | Exact match with calibration anchor: outputs 120.0 Liters |
| Depth = 50cm (In Cylinder) | Interpolates on segment 2: outputs 360.0 Liters (slope = 12.0 L/cm) |
Add acoustic temperature compensation: calculate actual speed of sound using ambient temperature (v = 331.3 + 0.606 * T) before distance calculation!
📖 Our Story & Concepts
Real community water tanks and petroleum vessels are rarely simple rectangular cubes. Most industrial tanks feature a conical tapered bottom for sediment drainage and rounded spherical caps. Consequently, depth and volume do not share a linear relationship.
An ultrasonic sensor measures distance, not volume. While computing 3D calculus equations on embedded microcontrollers is computationally expensive, Piece-Wise Linear Interpolation (PWLI) offers an elegant solution: the curve is divided into linear segments between empirical calibration points, delivering rapid and accurate volumetric readouts.
</> Full Annotated Code Walkthrough
// Complete Ultrasonic Non-Linear Volume Station
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
const float TANK_HEIGHT = 120.0; // cm
struct Point { float d; float v; };
const Point lut[] = {
{0.0, 0.0}, {30.0, 120.0}, {70.0, 600.0}, {100.0, 1200.0}
};
float getDepth() {
digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long dur = pulseIn(ECHO_PIN, HIGH);
float distance = (dur * 0.0343) / 2.0;
return constrain(TANK_HEIGHT - distance, 0.0, 100.0);
}
float calcVolume(float depth) {
for (int i = 0; i < 3; i++) {
if (depth >= lut[i].d && depth <= lut[i+1].d) {
float m = (lut[i+1].v - lut[i].v) / (lut[i+1].d - lut[i].d);
return lut[i].v + m * (depth - lut[i].d);
}
}
return 0;
}
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(115200);
}
void loop() {
float waterDepth = getDepth();
float volumeLiters = calcVolume(waterDepth);
Serial.print("Depth(cm):"); Serial.print(waterDepth);
Serial.print(",Volume(L):"); Serial.println(volumeLiters);
delay(1000);
}
Piece-wise linear interpolation models irregular tank geometry accurately without heavy polynomial calculations.
▷ Expected Results & Troubleshooting
| Test Condition / Action | Expected Result |
|---|---|
| Depth = 15cm (In Conical Base) | Interpolates on segment 1: outputs 60.0 Liters (slope = 4.0 L/cm) |
| Depth = 30cm (Transition Point) | Exact match with calibration anchor: outputs 120.0 Liters |
| Depth = 50cm (In Cylinder) | Interpolates on segment 2: outputs 360.0 Liters (slope = 12.0 L/cm) |
⚑ Extension Challenges & Blueprints
- Level 1: Calibrate a horizontal cylindrical fuel tank using a 10-point lookup table.
- Level 2: Display water percentage, remaining liters, and days of water reserve on an LCD.
- Level 3: Implement an acoustic echo outlier rejection filter to eliminate splashing artifacts.