MaxBotix MaxSonar EZ4 Sensor; up and running

Hello all, I just wanted to post up my progress so far. This is day one for me as an Arduino owner, I feel I'm getting the hang of it OK.

Synopsis: I am designing a system that will measure the amount of water in a large tank, send email notifications when the level is low, and prevent a pressure pump that draws from the tank from running if the level is critically low. The thread about relay control of the pump is http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231937645/6#6, although I have not yet gotten that far.

First step was to prove that I could define an arbitrary range in inches, to be represented as 0-100%, and have the sensor readings output the position in that range. For the proof of concept, I used 10 LEDs for my "meter", and an 11th LED as my critically low indicator. This is the point at which the pump relay would be activated. The set point for the email notification is not in there, since the concept clearly works.

YouTube video is here:

Here's the sketch as well. I have serial output code in there for debugging purposes, which is commented out.

/*
Takes MaxSonar Analog input and shows the level
as a percentage of a range on 10 LEDs.

Carson C. Jan 2009
 */

int rangeMax = 36;      // (INCHES) Top end of the range we want to measure, i.e. "100%"
int rangeMin = 6;        // (INCHES) Bottom end of the range we want to measure, i.e. "0%" (There is no LED for 0%)
int rangeWarning = 10;    // (INCHES) Warning variable, turns on an additional LED when the reading is at or below this point

float currentPercent = 0;  // 0-100% range

int pinLEDLowEnd = 30;   // Lowest pin in the LED array
int pinLEDHighEnd = 39;  // Highest pin in the LED array
int pinLEDWarning = 40;  // Warning LED

int pinAnalogInput = 5;  // Analog Input pin for the range sensor

int pinSet;              // Used to define which pin is currently being turned on/off

float signalDivisor = 1.953;  // Tuning number for the analog signal

void setup() {
  // Assign the LED output pins
  for (int i=pinLEDLowEnd; i <= pinLEDHighEnd; i++) {
    pinMode(i, OUTPUT);
  }
  // Assign the warning LED pin
  pinMode(pinLEDWarning, OUTPUT);
  
  // Serial output for debugging
  //Serial.begin(9600);
}

void loop() {  
  float inches = float(analogRead(pinAnalogInput)) / signalDivisor; // Acquire the reading
  
  // If the sensor returns a position beyond our desired range, reel it in
  if (int(inches) > rangeMax) {
    inches = float(rangeMax);
  }
  if (int(inches) < rangeMin) {
    inches = float(rangeMin);
  }
  //Serial.print(int(inches));
  //Serial.print(" inches raw\n");
  
  currentPercent = (inches - rangeMin) / (rangeMax - rangeMin); // Calculate the current percentage position in the range
  currentPercent *= 100; // Convert the decimal back to a whole number
  
  // Set the meter LEDs
  pinSet = pinLEDLowEnd;
  for (int i = 10; i <= 100; i += 10) {
    if (int(currentPercent) >= i) {
      digitalWrite(pinSet, HIGH);
    } else {
      digitalWrite(pinSet, LOW);
    }
    pinSet++;
  }
  
  // Check the warning state and set the LED appropriately
  if (int(inches) <= rangeWarning) {
    digitalWrite(pinLEDWarning, HIGH);
  } else {
    digitalWrite(pinLEDWarning, LOW);
  }
  
  //Serial.print(int(currentPercent));
  //Serial.print("%\n");
}

Next step is to smooth out the data returned by the sensor. Pointers?

[edit]Looks like there's some smoothing stuff in the Playground. What a resource![/edit]

Kind of curious here, could I use a capacitor to smooth the signal in hardware? I have no clue what I'm talking about here mind you ;D

Thanks for the code

I will use the same sensor for a AGLawnmower - I just recieved my EZ4's and found this in the FAQ page -

maxbotix.com/MaxSonar-EZ1__FAQ.html#How_can_I_get_the_best_possible_accuracy_from_the_analog_voltage_output

Question,
I assume you will be connecting this to the top of your tank pointing down, so isn't the 6" rang 100% i.e. 6" from sensor to water serface, and the 36" 0%?

so isn't the 6" rang 100% i.e. 6" from sensor to water serface, and the 36" 0%?

Correct. I wrote this such that I can adjust the inches to actual once the sensor is installed. I'll also have to invert the logic at that time. It'll be straightforward to do however.

@MechatronicTek; Thanks for the link. I ended up going for the 50ms delay example, which cleans the signal enough for my purposes. I'll do all the rest of the smoothing over time in software. This'll be back-ended on a MySQL database, so I can rework the readings and graph them after collection.

Next up is to get this thing talking to my PHP web server, although at the moment I can't use the example code for the ethernet shield... the core files for the Illuminato need some caressing before it'll compile. :-/

I have plans for this same type of thing, actually. However it is on the back burner because of the 6" dead band. Placeing the sensor 6" above it's full point is not an option for me, it must be within 1".

However I have not had the chance lately to check the analog. Does the analog continue to be accurate at less than 6 inches?

Does the analog continue to be accurate at less than 6 inches?

No. I occasionally get a reading of 5 inches, but it's meaningless noise.