[Arduino] Ultrasonic Range Finder (XL-MaxSonar-EZ MB1240)

Last time I update this blog was almost a year ago… during this time, lots happened. I graduated from Lehigh University with a MechE degree, got 3 job offers. Got to choose 1, which is such a painful decision, but that will be for a later time. Long story short, I am back to Lehigh for a Master’s degree. For my thesis, I am building a “Guidance, Navigation and Control System for a Simulated Hopper Spacecraft”. Basically, building a tricopter / quadcopter to simulate the space hopper concept for space exploration. So I guess I will use this as my notebook again to document some work I’ve done, hopefully it will be easier when it’s time to write the paper.

So, ultrasonic sensor. A more expensive one, XL-MaxSonar.

We used the HC-SR04 back in 2012, so why XL-MaxSonar? Well, first off, it’s a bit more expensive and better documented, so it look better when my adviser ask what type of sensor I used in the multi-rotors. It seems that the sensor is way better performance and more reliable, have benefits such as noise resistance, longer range, auto real time calibration, higher accuracy, better resolution…  and it’s easier to obtain the range directly through several methods.

In a way, this ultrasonic sensor is much easier to use when compare to the HC-SR04. For this one, you really only need to read the data sheet and pick out useful information.

http://www.maxbotix.com/documents/XL-MaxSonar-EZ_Datasheet.pdf

Data Sheet
Reading this pdf, we got some useful data for our sensor. Mine is MB1240. Note that different model might have slightly different specs. For example, different signal representation.

  • Power Supply (Vcc):  3.3V to 5V
  • Minimum Range: 20 cm
  • Maximum Range: 760 cm
  • Pulse Width Signal: 58 uS / cm (microseconds per cm)
  • Analog Signal: Vcc/1024 per cm

Hardware Wiring
For this sensor, you only need 3 line. The voltage in, ground and signal. For voltage, I recommend plugging into the Arduino’s native 5V supply, ground to ground. For signal, it depends on which wiring method you trying to use. Pin 2 on the Sensor is the Pulse Width Output, hook that up to an open Digital Pin on the Arduino (I use Pin 12). If you want to do Analog, hook up Pin 3 from sensor to an open Analog Pin on the Arduino (I use A5). For Serial, hook up sensor’s RX to Arduino’s TX.

Obtaining Data
There are several ways to obtain data, there are listed as follow:

  • Pulse Width
  • Analog Voltage
  • Serial (RS232) [TX/RX]

So that’s not too bad, it’s not like we are doing SPI or I2C, anything complicated like that. I will do a tutorial on those later on. But for now, we are going to focus on the Pulse Width and the Analog Voltage Method. The Serial RS232, essentially, you just connect the TX pin from the sensor to the RX pin on the Arduino, then do a Serial Read. It’s easy and tell you directly what the range is in text, but I am ignoring this method because I think Serial communication is a but slower than the other methods. Since the multi-rotor control system’s speed is very important, we try to optimize it.

Pulse Width
For the pulse width method, we are going to use the pulseIn function from Arduino to measure the time between the low and high pulse. This is a method of pulse width modulation that is also used to control servo angle and electric motor speed. More about that at a later time. All you need to know for now is that the longer the duration between pulse (action of low signal turning into high), the greater the measured range is. From the data sheet, we got that the mathematical relation is that 58 uS (microsecond) per cm. The pulseIn function in Arduino return the duration between pulse in microsecond already, so all we really have to do is divide the duration by the conversion constant, 58 uS, to get cm. After running several tests, it seems that the timing in the Arduino is a bit off, so the represented distance is also a bit off. Therefore, it’s necessary to add an adjust on the Arduino side. In the code below, it will be denoted as Mode 1.

Analog Input
Other than the calibration issue, the pulse width method also seems to be slow. Therefore, we will speed this up by using the analog method. Essentially, the sensor output a certain voltage to represent the measured range. The higher the voltage, the higher the range. The mathematical relation is Vcc/1024 per cm as stated in the data sheet.

Consider using a 5V power supply, 5/1024 = .0049, 4.9 mV represent a cm in the analog sense. All we have to do is do an analogRead and convert that number into voltage (4.9 mV per unit again). Then divide the voltage by the conversion factor, 4.9 mV to get cm.

Code
As mentioned before Mode 1 is for Pulse Width and Mode 2 is for Analog. Since I don’t have a metric tape measuer in the lab, I converted the range into inches. Remember to re-wire when switching from Mode 1 (D12 to Sensor Pin 2) to Mode 2 (A5 to Sensor Pin 3).

// Yu Hin Hau
// Ultrasonic Sensor
// XL-MaxSonar
// March 11, 2014

int mode = 2;
double distance; 
double calibration;

void setup()
{
  Serial.begin(9600);
  pinMode(12, INPUT);
}

void loop()
{
  if(mode == 1)
  {
  //Read duration in microSeconds
  long duration = pulseIn(12, HIGH);
  
  //58 uS per cm for MB1240 XL-MaxSonar
  //Operation Range: 20 cm min (50 cm for accurate)
  distance = duration / 58.0; 
  calibration = -20;
  }
  else if (mode == 2)
  {
  //Analog In .49 mV per unit 
  double voltage = analogRead(5)*.0049;
  
  //.49 mV per cm
  distance = voltage/.0049;
  calibration = 0.0;
  }
  
  double cmToInch = 0.393701;

  //Analog Seems to be More Accurate due to PWM timing
  Serial.print((distance+calibration)*cmToInch);
  Serial.println(" in");
  delay(100);
}

Conclusion
Did some initial testing of the sensor earlier today, seems to work pretty good at reasonable angle to the flat surface. It give pretty accurate result (Analog) on various materials such as wall, floor, door, paper, wood, contrete, mud, grass, water, snow, hand… I am actually surprise that it out outdoor. This will be good for the quad’s landing protocol at low altitude. At normal cruise, I will probably use the barometic altimeter instead. That will be another post.

Advertisements

One thought on “[Arduino] Ultrasonic Range Finder (XL-MaxSonar-EZ MB1240)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s