MB1240 Ultrasonic Sensor Guide for Arduino

This article is a summary of the tutorial written by Benne de Bakker of MakerGuides.com

Read the original article here

mb1240 aruduino ultrasonic sensor

The MB1240 XL-MaxSonar-EZ4 is a high-performance ultrasonic distance sensor with a range of 20 to 765 cm. While this tutorial is written for the MB1240, it can also be used for other MaxBotix sensors, and serves as a great reference for those interested in using an ultrasonic sensor with Arduino, including the MB1010 popular ultrasonic range finder.

In this tutorial, you will learn how the sensor works and how you can use it with an Arduino. I have included 3 examples with wiring diagrams that show the basic operation of the sensor. We will look at the different outputs of the sensor and how you can trigger the sensor with a push button. These examples are particularly useful for those looking for Arduino tutorial guidance on integrating sensors like the MB1200 ultrasonic sensor.

After each example, I break down and explain how the code works, so you should have no problems modifying it to suit your needs.

How does an ultrasonic sensor work?

An ultrasonic distance sensor works by sending out ultrasound waves. These ultrasound waves get reflected by an object and the ultrasonic sensor detects them. By measuring how much time passed between sending and receiving the sound waves, you can calculate the distance between the sensor and the object.

Distance (cm) = Speed of sound (cm/µs) × Time (µs) / 2

Where Time is the time between sending and receiving the sound waves in microseconds.

how ultrasonic sensors work

Note that you need to divide the result by two. This is because the sound waves traveled from the sensor to the object and back from the object to the sensor. So the distance between the sensor and the object is only half the distance that the sound waves traveled.

Information about the sensor

The MB1240 XL-MaxSonar-EZ4 is an ultrasonic distance sensor made by MaxBotix Inc. MaxBotix is a US-based manufacturer that specializes in ultrasonic sensors. They make sensors for all kinds of applications, both for indoor and outdoor use.

The MB1240 is one of their most popular sensors and is ideal for robotic applications. The XL-MaxSonar-EZ family has a high tolerance for interference from acoustic or electric noise. This means you can use it for robotic applications with multiple motors and servos. The MB1240 that I used in this tutorial has a range of up to 765 cm and offers a 1 cm resolution. Maxbotix also sells sensors with a 1 mm resolution (HRLV-MaxSonar-EZ) and a higher refresh rate (LV-MaxSonar-EZ). The HR line of sensors also features internal temperature compensation.

MB1240 XL-MaxSonar-EZ4 Specifications

Operating voltage 3.3 – 5.5 V
Operating current 3.4 mA average (100 mA peak)
Range (0)* 20 – 765 cm
Resolution 1 cm
Frequency 42 kHz
Reading rate 10 Hz
Sensor outputs Analog voltage, pulse width, RS232
Overall dimensions 22.1 x 19.9 x 25.11 mm
Operating temperature 0 – 65 °C
Advantage Small, light weight, narrow beam, automatic calibration (voltage, humidity, ambient noise), firmware filtering, easy to use
Engineered, Tested, & Assembled in USA
Cost Check price

*The sensor has virtually no dead zone, objects closer than 20 cm range as 20 cm.

For more information, you can check out the datasheet here:

MB1240 Datasheet

MaxBotix sensor outputs

As you might have seen in the specifications table above, the MaxBotix sensors of the MaxSonar family have different outputs: analog voltage, pulse width and RS232 serial (I2C sensors are also available). In this tutorial, we will look at both the analog voltage and pulse width outputs.

Analog voltage

This is probably the easiest way to read the measured distance from the sensor. The analog voltage output of the sensor outputs a linear voltage that gets larger as a target moves further away from the sensor.

analog voltage ultrasonic sensor

We can read this output with a microcontroller like the Arduino and calculate the distance by multiplying the reading by a constant scaling factor (this factor depends on the exact sensor type, see datasheet).

Pulse width

Another option is to use the pulse width output. This pin outputs a pulse width representation of the distance. You can use the pulseIn() function in the Arduino code to read the length of this output pulse in microseconds (µs). To get the distance, you need to multiply this reading with a constant scaling factor. For the MB7389, the scaling factor is 1 µs/mm. So you can simply multiply the TOF reading by 1 to get the distance in millimeters.

pulse width output ultrasonic sensor

For other types of sensors, you can find the scaling factors in the datasheets.

MaxBotix MB1240 vs Chinese Manufactured, 2 Transducer Sensor

When shopping for an ultrasonic range finder, you have probably come across some popular Chinese manufactured sensors. Those sensors and the MB1240 operate on a similar principle, but there are some key differences (mostly in quality and price).

The first thing you might notice is the difference in size. The MaxBotix MB1240 only uses one ultrasonic transducer for both sending and receiving the sound waves. Many Chinese manufactured alternatives, on the other hand, uses two. This means that the MB1240 is considerably smaller.

Mounting a sensor with two transducers can be difficult and often requires tiny screws, whereas the MB1240 has two holes for M3 bolts.

For me, the major advantages of the MaxBotix sensors are the automatic real-time calibration, small beam angle, high noise tolerance, and onboard filtering.

The MB1240 has a really narrow beam across its entire measuring range (for large objects). This makes it ideal for accurately mapping a room (obstacle avoiding robots) and means you won’t get early reflections from objects close to the sensor. One alternative sensor, in particular, has  a beam in the shape of a 15° 3D cone. This means that you can’t accurately measure objects that are far away from the sensor. The beam is simply too wide and will pick up objects that are closer to the sensor.

Furthermore, I like the continuous operation of the sensors (more on this later) and the analog output. The analog output makes programming the sensors super easy. These extra features are all very nice but note that the price is also quite a bit higher than that of the Chinese sensors. All in all, if you are looking for a high-quality reliable sensor then the MaxBotix sensors could be a good option. For comparison, check out the table below.

MB1240 vs Chinese Manufactured, 2 Transducer Sensor comparison table

  MB1240 Chinese Manufactured, 2 Transducer Sensor
Operating voltage 3.3 – 5.5 V 5 V
Operating current 3.4 mA average (100 mA peak) 15 mA
Range (0) 20 – 765 cm 2 – 400 cm
Resolution 1 cm >3 mm
Beam pattern see here 15° cone
Frequency 42 kHz 40 kHz
Sensor outputs Analog voltage, pulse width, RS232 Pulse Width
Dimensions 22.1 x 19.9 x 25.11 mm 45 x 20 x 15 mm
Temperature compensation* No No
Filtering Yes No
Real-time auto-calibration Yes No
Noise tolerance High Low
Engineered, Tested, & Assembled in USA China
     

*What you might not know, is that the speed of sound strongly depends on the temperature and humidity of the air. The speed of sound in air increases about 0.6 meters per second, per degree centigrade.

The XL-MaxSonar and LV-MaxSonar sensors assume an air temperature of 22.5 degrees Celsius. The HR line of sensors features internal temperature calibration, so you don’t need to add any sensors yourself. If you would like to see an example that includes a temperature sensor to calibrate the speed of sound in real-time, take a look at this guide.

Tools and materials

You can find the tools and materials needed for this tutorial in the links below.

Hardware components

Software

Wiring – Connecting MaxBotix MB1240 to Arduino UNO

As mentioned in the introduction, MaxBotix sensors can be operated in different modes. The wiring diagrams below show you how you can connect the MB1240 sensor to the Arduino for analog voltage or pulse width operation.

You can solder the wires directly to the sensor, or install some header pins (that is what I did) or a connector.

mb1240 ultrasonic sensor connected to an arduino

Pulse width wiring diagram

MB1240 Connections – Pulse width

MaxBotix MB1240 Sensor Arduino
GND GND
V+ 5 V
Pin 2 Pin 2

Which output you should use depends on the application. One important difference is that the analog voltage output shows the distance with a resolution of 5 mm, whereas the pulse width output gives a 1 mm resolution.

MaxBotix MB1240 Arduino example code – Analog voltage

With the following example, you can read out the measured distance and display it to the serial monitor. As you can see, the code is very simple but you can find some explanation on how it works below. This example is part of our arduino code examples collection for using sensors like the MaxBotix ultrasonic sensor Arduino setup.

You can upload the example code with the IDE.

 

/* Arduino example code for MaxBotix MB1240 XL-MaxSonar-EZ4 ultrasonic distance sensor: analog voltage output. More info: www.makerguides.com */
#define sensorPin A0
int distance = 0;
void setup() {
Serial.begin(9600);
}
void read_sensor() {
distance = analogRead(sensorPin) * 1;
}
void print_data() {
Serial.print("distance = ");
Serial.print(distance);
Serial.println(" cm");
}
void loop() {
read_sensor();
print_data();
delay(1000);
}

You should see the following output on the Serial Monitor (Ctrl + Shift + M).

MB1240 Serial Monitor output

How the code works

The first step is to define the connection pin. The statement #define is used to give a name to a constant value. When the program is compiled, the compiler will replace any references to this constant with the defined value. So everywhere you mention sensorPin, the compiler will replace it with A0 when the program is compiled.

  1. #define sensorPin A0

Next, we need to create a variable to store the measured distance.

  1. int distance = 0;

In the setup, we initialize serial communication at a baud rate of 9600. Later we will display the measured distance in the serial monitor, which can be accessed with Ctrl + Shift + M or Tools > Serial Monitor. Make sure the baud rate is also set to 9600 in the serial monitor.

  1. void setup() {
  2. Serial.begin(9600);
  3. }

After this, I created two functions: read_sensor and print_data.

In the read_sensor function, we simply read the analog voltage sensor output with the function analogRead(pin). The Arduino boards contain a multichannel, 10-bit analog to digital converter. This means that it will map the input voltage between 0 and the operating voltage into integer values between 0 and 1023. On an Arduino Uno, this results in 5 volts / 1024 units or, 4.9 mV per unit.

The MB1240 uses a scaling factor of (Vcc/1024) per cm or 4.9 mV/cm when using a 5 V power supply. This makes converting the analogRead value to centimeters super easy, you can simply multiply the result by 1 (analogRead(sensorPin) = distance in centimeters).

  1. void read_sensor() {
  2. distance = analogRead(sensorPin) * 1;
  3. }

In the print_data function, we print the measured distance to the serial monitor.

  1. void print_data() {
  2. Serial.print(“distance = “);
  3. Serial.print(distance);
  4. Serial.println(” cm”);
  5. }

In the loop, we first call the read_sensor function to get the distance and then call the print_data function to send it to the serial monitor. I added a delay of 1000 milliseconds, but you could reduce this to 100 if you want. The reading frequency of the MB1240 is 10 Hz so you can take 10 readings per second.

  1. void loop() {
  2. read_sensor();
  3. print_data();
  4. delay(1000);
  5. }

MaxBotix MB1240 Arduino example code – Pulse width

In this example, we will be using the other output of the sensor: the pulse width output.

 

/* Arduino example code for MaxBotix MB1240 XL-MaxSonar-EZ4 ultrasonic distance sensor: pulse width output. More info: www.makerguides.com */
#define sensorPin 2
long distance = 0;
long duration = 0;
void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
}
void read_sensor() {
duration = pulseIn(sensorPin, HIGH);
distance = duration / 58;
}
void print_data() {
Serial.print("distance = ");
Serial.print(distance);
Serial.println(" cm");
}
void loop() {
read_sensor();
print_data();
delay(1000);
}

Code explanation

After defining the connection pin, I created two variables: duration and distance. Duration stores the length of the pulse sent by the sensor. The distance variable is used to store the calculated distance.

  1. long distance = 0;
  2. long duration = 0;

In the setup, besides initializing serial communication, we also need to set the sensorPin as an INPUT. For this we use the function pinMode(pin, mode).

  1. void setup() {
  2. pinMode(sensorPin, INPUT);
  3. Serial.begin(9600);
  4. }

The read_sensor function is different from the previous example. Now we will not measure the analog voltage output, but the length of the pulse sent by the sensor. For this we use the function pulseIn(pin, value). This function waits for the pin to go from LOW to HIGH, starts timing, then waits for the pin to go LOW and stops timing. It returns the length of the pulse in microseconds.

After this, we can calculate the distance in centimeters by dividing the duration measurement by 58. For other MaxBotix sensors, you can find this scaling factor in the datasheet.

  1. void read_sensor() {
  2. duration = pulseIn(sensorPin, HIGH);
  3. distance = duration / 58;
  4. }

The rest of the code is the same as the previous example.


Trigger mode operation

All the MaxSonar sensors will operate in free-running mode by default. What this means is that the sensor will continue to range until the power is removed from the sensor. It sends out twenty 42kHz waves every 99 ms (10 Hz reading rate for MB1240, see datasheet for other sensors).

This is generally the easiest way to operate the sensor, as you do not have to trigger it yourself and can just take an analog voltage or pulse width reading to get the distance.

For some applications, like when running the sensor from a battery, it can be better to operate the sensor with a trigger. What this means is that you can tell the sensor to start a ranging cycle, but only when it is instructed to. This way, you can control the highest current draw from the sensor which is when it transmits a sonar pulse.

The sensor draws the most current when it sends out a sonar pulse.

To operate the sensor with a trigger, we will use an extra connection between pin 4 of the sensor and the Arduino. When you do not connect anything to this pin, like in the previous examples, the sensor will range at the refresh rate of the sensor mentioned in the sensor’s datasheet.

To trigger the sensor when needed, you need to connect pin 4 to a logic low. When you want to take a reading, you have to pull pin 4 high for a minimum of 20 μs. The sensor will then start a ranging cycle.

The wiring diagram below shows you which connections you need to make for this example.

MaxBotix-MB1240-ultrasonic-distance-sensor-with-Arduino-UNO-pulse-width-non-continuous-operation-wiring-diagram-schematic
MaxBotix MB1240 with momentary push button and Arduino wiring diagram

In this example, we will be using a momentary push button to trigger the sensor. You can buy these nice round push buttons on Amazon, that you can just plug into a breadboard. Connect one of the legs to ground and the diagonally opposite leg to Arduino pin 4.

The connections are also given in the table below.

MB1240 Connections – Trigger mode

Pin Arduino
GND GND
V+ 5 V
Pin 2 Pin 2
Pin 4 Pin 3
Button pin 1 Pin 4
Button pin 2 GND

MaxBotix MB1240 Arduino example code – Trigger with push button

You can use this example sketch to control the sensor with a trigger. In this case, the sensor will take a reading when you press the button and display the distance measurement on the Serial Monitor. You can also just call the read_sensor function when you want to take a reading.

 

/* Arduino example code for MaxBotix MB1240 XL-MaxSonar-EZ4 ultrasonic distance sensor with push button. More info: www.makerguides.com */
#define readPin 2
#define triggerPin 3
#define buttonPin 4
long distance = 0;
long duration = 0;
int buttonState = HIGH;
int previous = HIGH;
long time = 0;
long debounce = 200;
void setup() {
pinMode(readPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(triggerPin, OUTPUT);
digitalWrite(triggerPin, LOW);
Serial.begin(9600);
delay(3000);
Serial.println("Sensor is ready, waiting for button press!");
}
void read_sensor() {
digitalWrite(triggerPin, HIGH);
delayMicroseconds(20);
digitalWrite(triggerPin, LOW);
duration = pulseIn(readPin, HIGH);
distance = duration / 58;
delay(100);
}
void print_data() {
Serial.print("distance = ");
Serial.print(distance);
Serial.println(" cm");
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW && previous == HIGH && millis() - time > debounce) {
read_sensor();
print_data();
time = millis();
}
previous = buttonState;
}

You should see the following output in the Serial Monitor (Ctrl + Shift + M).

MB1240 trigger mode serial monitor output

How the code works

The first step is to define the connections. We will be using the pulse width output of the sensor to read the distance.

  1. #define readPin 2
  2. #define triggerPin 3
  3. #define buttonPin 4

Besides the duration and distance variables that we used in the previous example, we also need some new variables to store the state of the button. The time and debounce variables are used to debounce the input.

You can increase the debounce time if you are getting false triggers.

  1. long distance = 0;
  2. long duration = 0;
  3.  
  4. int buttonState = HIGH;
  5. int previous = HIGH;
  6. long time = 0;
  7. long debounce = 200;

In the setup, we set the triggerPin as output and the read and buttonPin as input. Note that I used INPUT_PULLUP in the pinMode function. There are 20K pullup resistors built into the Atmega chip that can be accessed from software. This setting pulls the buttonPin HIGH when it is not pressed and it will turn LOW when you press the button.

Next, we set the triggerPin LOW, so the sensor will not start ranging.

To print the sensor data, we begin serial communication at a baud rate of 9600.

  1. void setup() {
  2. pinMode(readPin, INPUT);
  3. pinMode(buttonPin, INPUT_PULLUP);
  4. pinMode(triggerPin, OUTPUT);
  5. digitalWrite(triggerPin, LOW);
  6. Serial.begin(9600);
  7. delay(3000);
  8. Serial.println(“Sensor is ready, waiting for button press!”);
  9. }

After this, I defined two functions, the read_sensor and print_data function.

In the read_sensor function, you can see that we set the triggerPin high for 20 microseconds. This will tell the sensor to send out a sonar pulse. Next, we read the length of the output pulse and convert it into the distance (this is the same as the previous example). I added a delay of 100 ms, as this is the minimum time between readings.

The print_data function is the same as in the previous examples.

  1. void read_sensor() {
  2. digitalWrite(triggerPin, HIGH);
  3. delayMicroseconds(20);
  4. digitalWrite(triggerPin, LOW);
  5. duration = pulseIn(readPin, HIGH);
  6. distance = duration / 58;
  7. delay(100);
  8. }

In the loop, we first read the state of the button (pressed / not pressed) and store it as buttonState. The next line checks if you have pressed the button (i.e. the input went from HIGH to LOW) and if you have waited long enough since the last press to ignore any noise.

If this is true, it calls the read_sensor and print_data function and resets the timer.

  1. void loop() {
  2. buttonState = digitalRead(buttonPin);
  3.  
  4. if (buttonState == LOW && previous == HIGH && millis() – time > debounce) {
  5. read_sensor();
  6. print_data();
  7. time = millis();
  8. }
  9.  
  10. previous = buttonState;
  11. }

Finally, the previous variable is set to the current buttonState.


Sensor dimensions

The exact dimensions of the sensor can be found in the picture below:
XL-MaxSonar-EZ-Mechanical Dimensions

CAD

MaxBotix provides free CAD files for all their sensors on their website. This makes designing custom parts or brackets to use with the sensor super easy. You can download a zip file with a 3D model of the sensor below (7 different file formats). More models of different sensors can be found on our website.

XL-MaxSonar-EZ CAD Files

 

Conclusion

In this article, Makerguides has shown you how you can use the MaxBotix MB1240 XL-MaxSonar-EZ4 ultrasonic distance sensor with Arduino.

We hope you have found the tutorial informative. 

We’d like to hear what you’ve done with our sensors?

Support Limitations

MaxBotix provides code examples as a reference starting place for our customer. At the time of development, the code examples worked for the given platform and setup. Due to the fast changing nature of these platforms (Hardware, OS and peripheral devises), we are unable to keep up with the changes in these code examples. Additionally, every system setup is different which further increases the complexity of the system and troubleshooting.

Support for code is very limited regarding our free sensor support system. We recommend using the platforms forums for support to help troubleshoot the code issue as these are the most up to date regarding information. We do offer paid engineering support for code if this is something you may be interested in. Please contact us if you would like to look into this.

Please see the Arduino forum for more support at this link: https://forum.arduino.cc/

Back to blog

Let's connect on your project!