Level Sensor for horizontal oval tank, table lookup

Yes, that's why I'm here :slightly_smiling_face:

Although I'm not looking forward to that calibration session if it's needed, our fastest pump is 2500l/h, so it's 3 hours without any breaks at best. We often only have 4 hours between the tank being emptied and the next milking! Although we do have spare holding tanks

Can we presume you have discussed the volume calibration with the maker of the tank. Dad's tank had a measuring stick and a chart on the wall to give the milk volume.

1 Like

Do i want a 2D array here? 170 rows and 2 columns?
Trying to investigate how to use arrays

Not yet, there doesn't appear to be anywhere for a dip stick to go. It would also have to be quite unwieldy (1.6m+), especially when at the top of a precarious ladder. I'm guessing there isn't much call for exact measurement in these tanks because most dairy farms don't process, so they just keep putting into the bulk tank until the tanker arrives and takes it all.
There are several reasons for this project, it would be handy to not have to climb the ladder, due to risk or falling and also cross-contamination with the palour staff.

You would need only 1 column

const int volume[170] = { 0, 1, 3, etc.};
1 Like

True, just twigged that whilst driving

The internet is helpful and using words like "c++ arrays" or C++ multidimensional arrays" might be a source of useful information.

But do you really need a multidimensional array?

No, as build_1971 just pointed out, i probably don't need multidimensional

Need, no. Especially if you have the complete set of calibration numbers from the process suggested by @Paul_KD7HB.

If you only have a subset though, it can help with early testing to fill in the ones you know and interpolate.

Also, having the single dimension is hiding an assumption about what the array index represents. In what is likely to be a tiny program, this isn't particularly important, but I'd go with the array of structs anyway if there is sufficient RAM.

Yeah i was just starting to pad out the recording spreadsheet to copy over thinking i could really do with keeping the 'index'

Do I understand that you are relying entirely on an unknown pump on a random tanker truck to measure your milk. On Dads farm, the only way the tanker driver knew how much milk he was removing was to measure in the tank.

I am not sure I understand your farm, but that is not your problem.

The tanker has an accurate flowmeter, so that we're paid accordingly. We don't really meter it going in, because there's no need. We bottle what we need and send off what we don't.

How often do you review the accuracy?

This is Arla, a massive farmer-owned co-op spanning Europe, i'm not saying big companies are without fault, it's just not something we really worry about.
As above, we don't really meter in and it'd be hard to verify ourselves.
We can only assume that they have to abide by the rules and calibration that we also have to with our pasteurisation equipment. It's not our job to check them but an independent body

There is an old saying in the US. Trust but verify.

Well we have government bodies to ensure companies operate within legislation, for example we have to correctly label our milk/cream/yoghurt and ensure the correct amount is in the labelled container, we have to ensure, and have yearly calibration tests on, our pasteurisation. Testing a fleet of hundreds of artic (semi-trailer) tankers is not within our control.

I've been reading this evening and i'm struggling to find code examples that i can understand and try to implement.
When i search for information of reading sensors and comparing in a array and other similar language i just get results about putting sensor data into an array.

Read the sensor to get the distance to the milk as an integer. Pick the milk volume in the array that has the index equal to the distance.

int distance = get distance by some means
Serial.println(MyArray[distance]);
1 Like

I get told tankArray was not declared when i try to reference it to display to serial

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// Replace with your network credentials
const char* ssid = "*SSID*";
const char* password = "*KEY*";
long duration;
int distance;
ESP8266WebServer server(80);   //instantiate server at port 80 (http port)
// defines pins numbers
const int trigPin = 14;  //D5
const int echoPin = 12;  //D6
int tankArray[170,2];

int tankArray[170,2] = {
{0,0},
{1,0},
{2,0},
{3,0},
{4,0},
{5,0},
{6,0},
{7,0},
{8,0},
{9,0},
{10,0},
{11,0},
{12,0},
{13,0},
{14,0},
{15,0},
{16,0},
{17,0},
{18,0},
{19,0},
{20,0},
{21,0},
{22,0},
{23,0},
{24,0},
{25,0},
{26,261},
{27,0},
{28,0},
{29,0},
{30,0},
{31,0},
{32,0},
{33,0},
{34,0},
{35,0},
{36,1350},
{37,0},
{38,0},
{39,0},
{40,0},
{41,0},
{42,0},
{43,0},
{44,0},
{45,0},
{46,0},
{47,0},
{48,0},
{49,0},
{50,0},
{51,0},
{52,0},
{53,0},
{54,0},
{55,0},
{56,0},
{57,0},
{58,0},
{59,0},
{60,0},
{61,0},
{62,0},
{63,0},
{64,0},
{65,0},
{66,2368},
{67,0},
{68,0},
{69,0},
{70,0},
{71,0},
{72,0},
{73,0},
{74,0},
{75,0},
{76,0},
{77,0},
{78,0},
{79,0},
{80,0},
{81,0},
{82,0},
{83,3415},
{84,0},
{85,0},
{86,0},
{87,0},
{88,0},
{89,0},
{90,0},
{91,0},
{92,0},
{93,0},
{94,0},
{95,0},
{96,0},
{97,0},
{98,0},
{99,0},
{100,0},
{101,0},
{102,0},
{103,0},
{104,0},
{105,0},
{106,0},
{107,0},
{108,0},
{109,0},
{110,0},
{111,0},
{112,0},
{113,0},
{114,0},
{115,0},
{116,0},
{117,0},
{118,0},
{119,0},
{120,0},
{121,0},
{122,0},
{123,0},
{124,0},
{125,0},
{126,0},
{127,0},
{128,0},
{129,0},
{130,0},
{131,0},
{132,0},
{133,0},
{134,0},
{135,0},
{136,0},
{137,0},
{138,0},
{139,0},
{140,0},
{141,0},
{142,0},
{143,0},
{144,0},
{145,0},
{146,0},
{147,0},
{148,0},
{149,0},
{150,0},
{151,0},
{152,0},
{153,0},
{154,0},
{155,0},
{156,0},
{157,0},
{158,0},
{159,0},
{160,0},
{161,0},
{162,0},
{163,0},
{164,0},
{165,0},
{166,0},
{167,0},
{168,0},
{169,0},
{170,0}
        };
/*
for (int i=0; i<tankArray.length-2; i=i+2) {
    if ((A >= tankArray[i]) && (A <= tankArray[i+2])) {
      newVal = tankArray[i+1] - ((tankArray[i+1]-tankArray[i+3]) * ((A-tankArray[i]) / (tankArray[i+2]-tankArray[i])));
      break;
    }
}
*/
String page = "";
double data; 
void setup(void){

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  pinMode(A0, INPUT);
  
  delay(1000);
  Serial.begin(115200);
  WiFi.begin(ssid, password); //begin WiFi connection
  Serial.println("");
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/", [](){
    page = "<h1>Sensor to Node MCU Web Server</h1><h3>Data:</h3> <h4>"+String(170-distance)+"</h4>";
    server.send(200, "text/html", page);
  });
  
  server.begin();
  Serial.println("Web server started!");
}
 
void loop(void){
  data = analogRead(A0);
  // Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(10);

// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(50);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

// Calculating the distance
distance= duration*0.034/2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(tankArray[distance]);
/*Serial.println(distance);*/
  delay(1000);
  server.handleClient();
}

May not solve your problem, but you declared your array twice.

You should do:
Serial.println(tankArray[0][distance]);

Also, distance should be an integer so you should at least cast it.

Maybe round() is better.
Serial.println(tankArray[0][round(distance)]);

1 Like