Add an IR Break-Beam Sensor to an Arduino Project for Object Detection
2022-10-10 | By Maker.io Staff
Break-Beam sensors are an integral part of many projects that rely on a simple way of counting moving objects and living things, whether that be people passing through a doorway or coins traveling through a coin slot. However, these sensors are not only helpful in counting things, but they also come in handy when detecting the presence of someone or something in a specific area: for example, to prevent an automatic door from closing while somebody is standing in its way. This article introduces break-beam sensors, how they function, and how you can integrate them into your microcontroller-based projects.
What are Break-Beam Sensors?
These devices consist of two parts: one that casts a ray of light and another component that detects the presence or absence of that ray. These systems rarely utilize visible light. Instead, they rely on infrared (IR) light with a specific wavelength. The sensor part of the system is tuned to only react to the same IR wavelength that the emitter sends out.
This image shows a simple IR break-beam sensor that consists of an emitter (on the right) and a receiver (on the left).
The two parts are physically spaced apart so that whatever the system should detect or count needs to pass between the emitter and detector components. Whenever something or someone breaks the beam, the detector notices the absence of the previously present IR light beam, and the entire system can react to that event (e.g., by increasing a counter variable).
These sensors are cost-effective, fast in detecting motion, and easy to use. However, they consist of two parts, which may pose a problem in some situations. They also don't allow for precise position detection, and they don't provide any advanced features, such as object classification (i.e., they can't tell whether they're counting the correct object).
Some Project Ideas That Use Break-Beam Sensors
A simple coin-counting mechanism that only accepts one type of coin (e.g., US quarters) could utilize a break-beam sensor to count the number of coins a user inserted into a machine.
Next, a simple intruder detection system could recognize when somebody enters a room while the system is armed. This installation could also serve other purposes, such as turning on the lights when somebody enters a room or counting the number of people who entered.
Finally, you could place multiple sensors in a grid-like installation to build a simple position-detection system, similar to how IR touch screens detect where users place their fingers on the display’s surface.
This figure illustrates how you could use multiple break-beam sensors to build a simple position-detection system. An object, such as the yellow ball in this example, breaks two or more beams, allowing the system to determine the object’s horizontal and vertical position.
Using a Break-Beam Sensor in Your Projects
The most challenging aspect of integrating a break-beam sensor in a project is dealing with the power wires that each of the two parts of the sensor comes with. The emitter part usually doesn’t need any control signal to function. However, you could turn it on or off using a transistor to conserve energy in battery-operated projects. The receiver section only uses a single digital signal to tell the controller whether it detects an object. The sensor system used in this example further requires a single 10K pull-up resistor on its data signal line. However, you can circumvent adding an external resistor by utilizing the MCU’s internal pull-up resistor if possible:
This schematic diagram shows how to connect a simple break-beam sensor to any development board, such as the Arduino Nano 33 IoT.
Finally, you can determine whether some object broke the beam by checking whether the sensor’s input line is low. The sensor pulls the line low whenever something breaks the beam, and the external pull-up resistor pulls the line high again when the object is no longer obstructing the beam:
#define SENSOR_PIN 3 unsigned long lastDetection = 0UL; void setup() { pinMode(SENSOR_PIN, INPUT_PULLUP); Serial.begin(9600); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - lastDetection > 1000) { if(digitalRead(SENSOR_PIN)) Serial.println("No obstacle"); else Serial.println("Obstacle detected"); lastDetection = currentMillis; } }
In the code above, the setup function sets up the input pin for reading the sensor state and initializes the Arduino serial connection. Note that the pinMode function call enables the Arduino’s internal pull-up resistor, so there’s no need to add any external components in this case. Next, the loop function queries the sensor state once every second. If the sensor pin is low, some object breaks the beam, and the program informs the user that the sensor detected an obstacle.
This image shows the sensor connected to the Arduino development board. Unfortunately, managing the many wires that come with these sensors is no easy task.
Avoid Polling with Interrupts
The example above utilizes a technique called polling, which periodically checks whether a specific criterion (for example, the state of an input pin) is met. While this approach is simple to understand and implement, it also comes with a few drawbacks, such as putting unnecessary load on the CPU and potentially missing updates happening between the polling interval. Alternatively, you could also implement a sketch that uses interrupts to call a function whenever the input pin attached to the break beam sensor goes low:
#define SENSOR_PIN 2 boolean last_sensor_state = false; void setup() { Serial.begin(9600); pinMode(SENSOR_PIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), sensor_triggered, FALLING); } void sensor_triggered() { last_sensor_state = true; } void loop() { if(last_sensor_state) { Serial.println("Object detected!"); last_sensor_state = false; } // The CPU is free to do other things in the meantime }
In this revised example, the setup function initializes the serial monitor and the input pin. Here, the program also instructs the Arduino’s firmware to call a special method (sensor_triggered) whenever the sensor pin goes low (i.e., whenever the break beam sensor detects an obstacle). The sensor_triggered function then sets a flag which lets the loop function know that the sensor detected an object.
The new example is much less likely to miss updates that happen between the previously defined polling intervals, and it also takes some work off the CPU, as it doesn’t have to constantly check the sensor state. You can read more about interrupts and how to use them here!
Summary
Break-beam sensors are a straightforward and cost-effective way of detecting objects in various applications, for example, when counting the number of people entering a room. These sensors have two parts - an emitter and a receiver - and these systems typically use non-visible light, such as IR.
Apart from managing the power wires, connecting a break-beam sensor to a development board, such as an Arduino, is an easy task. Each of the two parts of the sensor comes with two power wires, and the receiver part includes an additional output signal wire that tells the MCU whether an object breaks the beam. The sensor in this example pulls the signal line low whenever it detects an object and requires an external pull-up resistor.
You can use polling or interrupts to detect when the sensor state changes. Polling is often simpler to implement and understand for beginners. However, it occupies potentially limited CPU time by constantly checking whether the sensor detected an input. Therefore, interrupts are often a better choice. However, most Arduino boards only support interrupts on a few input pins, which might not be available in large projects.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum