Maxbotix LV-MaxSonar-EZ - random value drops

Hi,

I'm having a problem with my Maxbotix LV-MaxSonar-EZ0 sensors.
I've connected them to my Arduino 5v pin, and the voltage measured is 4,8 volts. The PW pin is connected to digital port 8 on the Arduino.

The code is simple:

int pin = 8;
long pulse, distance;

void setup() {
  Serial.begin(9600);
}

void loop() {
  pinMode(pin, INPUT);
  
  pulse = pulseIn(pin, HIGH);
  distance = pulse/147;
  
  Serial.println(distance);
  
  delay(500);
}

The sensor works accurate and at a great range exactly according to the specifications, the problem is a decrease in values that appears very random (sometimes it works for 30 seconds, sometimes for 2).

73
74
74
74
72
63
53
43
33
23
74
74
74
73

I've been looking everywhere but couldn't find anyone with this particular problem. The value keeps walking down until it reaches this certain value (always around 20) and then bumps back up.

I've tried connecting the AN pin to the A0 pin on the arduino and adjusted the code. As expected, this gives more noise but I think I'm seeing the same pattern here (the value bumps back up more slowly).

Does anyone know what the problem might be?

Thanks in advance :slight_smile:

first post :slight_smile:

Hello,

I saw your forum post and have review your issue.

Causes of Incorrect range readings (with a properly installed and properly powered sensor)

Multiple Sensor Applications (Cross Talk)
Ultrasonic Sensors output and receive sound information when taking a range reading. If multiple sensors are operational in the same environment this may cause one sensor to receive information sent by another sensor. To eliminate interference, we recommend running sensors in sequence. Refer to the examples of the three recommended ways to chain the sensors together.
http://www.maxbotix.com/uploads/Chaining_Application_Notes__AN_Output_Commanded_Loop_.pdf
http://www.maxbotix.com/uploads/Chaining_Application_Notes__AN_Output_Constantly_Looping_.pdf
http://www.maxbotix.com/uploads/Chaining_Application_Notes__AN_Output_Simultaneous_Operation_.pdf

External acoustic noise
External acoustic noise sources may cause false range readings, that make phantom objects appear (i.e. readings are too close).

Soft or angled targets
Also soft targets or angled targets can be missed occasionally. That is, there must be a return of sufficient amplitude for detection and if enough energy is not returned then the target is missed. This missed target issue can be exacerbated up close, where the returning energy must be detected in the presence of very high energy ring-down, so soft targets, or off axis targets, may not be detected easily. (We will set the sensor to optimize for this... but the rules of physics will still apply.)

Filtering in General
For filtering, do not average. Do not average. Do not average. (Did I say, do not average?) We have a lot of internal filtering in our products and if you receive readings that you feel must be filtered, do not use averaging. Instead, throwing out the incorrect range values will produce the best results. Averaging valid and invalid readings together will provide incorrect data.

Filtering
The filtering that works best, is either a Mode filter or a Median filter. (Did I forget to say, "Do not average the readings"?)

The Median Filter
The median filter would take the last group of readings and first sort them and then pull out the center reading. Here one might take three or more readings (up to say about 11 for people sensing) and after sorting the readings in order of range, pull out and use only the middle (median) reading. Fairly good filtering.

The Mode Filter
The mode filter would take the largest group of the same readings out of a set of even larger readings. Very robust filtering.
Filtering for most applications, the Very Simple Mode Filter

The simplest mode filter, is simple as this question, "Do the last two readings agree?" (with in a certain distance, and the certain distance depends upon how much variation one expects in the actual use. Even so most use the logic of "are these readings exactly the same")? If so, use the readings, otherwise throw away to oldest reading, and compare the next reading with the most current reading and do this again. Obviously with very noisy data, one might have to sample a larger group of readings, and pull out the most common reading, but for most applications, this simple two reading filter works very well.

Even so, for specific cases, one has to try and find out what works best.

Please let us know if you have any further questions. I request that you email me any questions at scott@maxbotix.com.

Best regards,

Scott Wielenberg
Technical Support & Sales
of MaxBotix Inc.
Phone: (218) 454-0766 Ext. 2
Fax: (218) 454-0768
Email: scott@maxbotix.com
Web: www.maxbotix.com

I had the just spent a day coding a median filter for the Maxbotix LV EZ-1, so thought I would share it. It takes 5 analog readings of a continuously running EZ1, stores them in an array, then sorts them in ascending order using an "insert sort". The middle value in the array is the median of the 5 values. This gets rid of spikes in the readings without averaging.

//Use of MaxSonar EZ1 sonar module in analog mode with arduino
// median filter of five consecutive readings to eliminate spikes
//
// Bill Gentles, Nov. 12, 2010
//borrowing an idea from the Arduino Forum on array sort
//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283456170/12
//the "insert sort" code is from whistler
//
//take 5 readings and store them in an array rangevalue[]
//using an "ascending insert sort" rearrange the array values in ascending order
//choose the middle element in the array, which will by definition be the median of the set of values
//
//Analog pin 1 for reading in the analog voltage from the MaxSonar device.
int anPin = 1;

//variables needed to store values
int arraysize = 5;  //quantity of values to find the median (sample size). Needs to be an odd number
int rangevalue[] = {0, 0, 0, 0, 0};    //declare an array to store the samples. not necessary to zero the array values here, it just makes the code clearer
//*********************************************************************************************
void setup() 
{

  //This opens up a serial connection to shoot the results back to the PC console
  Serial.begin(9600);
  printArray(rangevalue, arraysize);  
  delay(5000);        //wait a while to open serial monitor window

}
//********************************************************************************
void loop() 
{

  pinMode(anPin, INPUT);

  //MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information.
  //Maxbotix does not recommend averaging readings as the occasional value can be wildly inaccurate and skew the average
  //A median sort is the preferred method. 

   for(int i = 0; i < arraysize; i++)
   {                                                    //array pointers go from 0 to 4

    //Used to read in the analog voltage output that is being sent by the MaxSonar device.
    //The MaxSonar Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
    //The Arduino will map input voltages between 0 and 5 volts into integer values between 0 and 1023. 
    //This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit. 
    //Therefore, one unit from the arduino's ADC represents 0.5 inches

     rangevalue[i] = analogRead(anPin);
          Serial.print("i, value   ");
          Serial.print(i);
          Serial.print(" ,  ");
          Serial.print(rangevalue[i]);
          Serial.println();

     delay(10);  //wait between analog samples
    }  

   Serial.print("unsorted ");
   printArray(rangevalue, arraysize);
   Serial.println();
   isort(rangevalue, arraysize);
   Serial.print("sorted ");
   printArray(rangevalue, arraysize);
   Serial.println();
    
 // now show the medaian range   
    int midpoint = arraysize/2;    //midpoint of the array is the medain value in a sorted array
      //note that for an array of 5, the midpoint is element 2, as the first element is element 0
     Serial.print("median range value ");
     Serial.print(rangevalue[midpoint]);
     Serial.println();  
     Serial.println();  
  
  delay(3000);    //wait a while so you can read the values on the serial monitor

}   //end of loop

//*********************************************************************************
// sort function
void isort(int *a, int n)
               //  *a is an array pointer function
{
  for (int i = 1; i < n; ++i)
  {
    int j = a[i];
    int k;
    for (k = i - 1; (k >= 0) && (j < a[k]); k--)
    {
      a[k + 1] = a[k];
    }
    a[k + 1] = j;
  }
}
//***********************************************************************************
//function to print array values
void printArray(int *a, int n)
{
  
  for (int i = 0; i < n; i++)
  {
    Serial.print(a[i], DEC);
    Serial.print(' ');
  }
  
  Serial.println();
}

All the printing including the function printarray() is just there for debugging, and can be removed to tighten up the code. Running on a Duemilanova with Arduino18 environment.