Difference between revisions of "VEX How-To Manual"
|Line 357:||Line 357:|
=== end() ===
=== end() ===
*The end() method stops all robot movement. It is meant for use at the end of the code, to stop the robot from looping the original code over and over again.
* The end() method stops all robot movement. It is meant for use at the end of the code, to stop the robot from looping the original code over and over again.
<i>Note: this method places the code within an <b>infinite loop</b>, therefore any code written after this method is called will not be run.</i>
<i>Note: this method places the code within an <b>infinite loop</b>, therefore any code written after this method is called will not be run.</i>
'' Syntax ''
'' Syntax ''
'' Example ''
'' Example ''
=== moveMotor() ===
=== moveMotor() ===
Revision as of 22:30, 28 January 2022
Goals for this Guide
- Specify restrictions on the VEX robots
- Basic introduction to kit components
- What are the parts and how to use them correctly
- Choice of pieces given different building purposes
- Robots motion
- Gear train
- Gear ratio
- Chart of clawbot pieces
VEX CAD Assembly
- Tips on troubleshooting the design and common CAD problems
- Design and implement CAD drawings in Fusion 360 for a VEX robot
- Introduction to the VEX Arduino Library
- How to import the library into Arduino to program the VEX Robot
- Classes and objects available to code the VEX robots’ movements
1. VEX Building
- Size Limitation
- A typical VEX robot should be smaller than 15x15 in. (slightly less than a tile).
- There’s no limitation in height, but if you plan to go for the extra credit ramp, there is a soft limitation in height.
- Robot Design
- No projectile or anything too crazy
- No jumping off the ramps for path planning
- For LAZ, a claw set MUST be attached to the robot. Sensors are optional.
NOTE: Your VEX robot CANNOT be identical to the traditional VEX clawbot. There must be something different and unique about your robot.
Nuts, Screws, and Wrench
- The Vex Kit that you received contains many materials, such as nuts, screws, and standoffs, designed to connect two or more bodies. The black screws are found in three sizes (Figure 1-1) and must be tightened by one of the keps nuts or nylock nuts (Figure 1-2).
- Keps Nuts are used for strong, yet removable bonds.
- Nylock Nuts are used for stronger, permanent bonds.
- To remove a nut, you need the help of the open end wrench (Figure 1-4) to keep it from turning. It provides grip and mechanism advantage in applying torque. The wrench you are given fits all nuts and standoffs.
- The second type of screw that you will see in your kit is the locking screw. Again, these golden screws come in a few sizes. They have a smaller width than the black screws, so they CANNOT be tightened by the Keps Nuts.
- These screws will be mainly used to secure the motors (Figure 1-5) into place.
- The screws can be tightened with the help of hex keys (Figure 1-6). The hex keys come in two different sizes (one with diameter 3/32” and one with diameter 5/64”), corresponding to the dimensions of the hole in screws. So try each hex key until the hex key’s end perfectly fits inside the drive of the screw.
Standoffs, Shaft Couplers, and Motor Post
- Instead of Keps Nuts, standoffs can also be used to secure screws in place. Standoffs are used to connect two different parts through screws or shafts, depending on the type of standoff.
- The screw standoff is used to connect two black screws (Figure 1-7). The shaft counterpart is called the shaft coupler. Motor posts (Figure 1-8) are used to connect shaft couplers to motors.
Note that standoffs and the couplers are NOT completely secured and can disassemble easily. Standoffs and couplers should only be used to connect parts that are already secured in place.
Shafts and Shaft Collars
- Your kit contains square shafts of two different lengths. The shafts are used by the motors to turn the gears and your wheels. Shafts can be secured in place by shaft collars (Figure 1-9).
- Shaft collars can be tightened with the thinner/longer (3/32”) hex key.
- Use two shaft collars to completely lock a part in place.
Bearing Flat and Bearing Attachment Rivet
- The square shafts are inherently smaller than the square holes in the structural metal pieces. Due to this, there will be rattling once the motor starts spinning.
- In order to minimize the rattling, bearing flats are used in conjunction with the structural part because the bearing flat’s hole is much more accommodating of the shaft’s size.
- The unused holes of the bearing flat can be tightly and smoothly secured with bearing attachment rivets (Figure 1-10, Figure 1-11).
- Spacers are used in order to properly position certain components of your robot, such as a gear. They come in different sizes and types, depending on the displacement needed.
- A regular spacer (Figure 1-12) can be put in anywhere in a shaft, while wheel spacers are designed to lock the wheels on the shafts.
- Bearing flats and shaft collars can also be used as spacers, if necessary.
Motors and High-Speed Gear
- The 2-Wire Motor 393 is the primary actuator you have for VEX. It can be used to build a rotational mechanism, drive bases, rotational joints, conveyor belts - anything that can spin. It can be configured to a “high speed” version with the help of the high-speed gear. Follow the Gear Change Procedure to increase your output speed by 60%.
- Each VEX kit is given a claw set that is pre-assembled and ready to grab and manipulate objects.
- It has a motor attached to the top of the claw bracket and is able to hold from a delicate feather to a 20 oz soda can.
- The main use of the claw is to grab and carry the plant sample back to the starting tile.
- Use this link to access the guide on how to assemble a claw set: https://content.vexrobotics.com/docs/276-2600-Claw-Assembly.pdf
- Zip ties are used to secure parts together are unable to be fixed in place with the conventional hardware components.
- Zip ties are more flexible in areas of usage but are limited by the lack of secureness compared to nuts and screws. There are zip ties of two different lengths in the kit.
- In order to tie a zip tie, wrap the long stem of the zip tie around such that the tail of the zip tie is inserted into the flat side of the head. Pull the tail of the zip tie into the desired length(Figure 1-16). If done correctly, the zip tie cannot be undone and can only be tightened.
- The VEX robot that you build will have to travel on the course. In order for the wheels to move, the wheel either has to be directly connected to the motor with a shaft or indirectly connected to the motor with a gear train.
- A gear train is made of a series of interlocking gears, either of varying sizes or similar sizes, with one gear of the gear train connected to an input source, such as a motor. As the motorized gear spins, every single gear in the gear train also turns.
- A wheel could be connected to any adjacent gears in order to turn that wheel as well. The length of the gear train depends on the distance between the motor and the desired wheel. Keep in mind that an odd number of gears in the gear train will cause the driven gears to spin in the same direction and an even number of gears in the gear train will cause the driven gears to spin in the opposite direction. Therefore, it is essential that gear trains have an odd number of gears in order to spin correctly. Gear trains are advantageous if both sets of wheels are traction wheels in order to have a smoother turn.
- Another method to induce motion is to let one set of wheels be freely spun due to the friction caused by another set of wheels that are powered by a motor. In this case, no gear train is used. This is advantageous if one set of wheels is omni-wheels that can freely turn. But for VEX MRR, having a gear train is recommended as we plan the robot to climb up a hill that is more than 30 degrees. Besides, the robot would perform point turn better with the help of the gear train.
- Making a gear ratio is one of the easiest ways to change the Mechanical Advantage in a mechanism or system to achieve the desired speed or torque. It expresses the relationship between a driving gear(the gear connected to the input power source, such as a motor) and a driven gear(the gear connected to the output, such as a wheel) in a system.
- When you have a system with a driving gear that is LARGER than the driven gear, you will increase the speed and decrease the torque. Otherwise, if the driving gear is SMALLER than the driven gear, you will increase the torque and decrease the speed.
- Gear ratio is expressed in this way: (Driving Gear Teeth):(Driven Gear Teeth), and gear reduction(another mathematical expression that describes the relationship) is expressed in reverse:(Driven Gear Teeth) /(Driven Gear Teeth). The following are a 12-teeth driving gear with a 36-teeth driven gear.
The gear ratio is 12:36, and the gear reduction is 36/12 = 3/1 = 3. That means that the output (driven gear) shaft is 3 times slower than the input (driving gear) shaft and has 3 times as much torque.
Please refer to Robot Construction Tips for Center of Gravity and Drive Train.
Chart of the Clawbot Pieces
Price List of the VEX Parts
Tips for Troubleshooting
- Before building:
- In the design process, make sure that wires of all motors can reach the motor shield located in the center of the robot, or the motors will break easily.
- Calculate the gear ratio and consider the feasibility of the design before putting them all together.
- While building:
- Always remember to add wheel spacers before putting wheels on shafts, or the wheels won’t sit steady.
- Wrap all cables with electrics tapes to prevent them from touching each other or the metal frame of the robot.
- Zip ties can be used to tie up your wires and secure batteries in place.
- While testing:
- If the robot can not climb up the ramp, make sure you are using gear train and rubber bands to add traction to your wheels.
- If the tips of wires connected to the motor came off, solder another pin to the motor/ask a TA for help.
- Weight distribution REALLY matters. Due to the importance of the center of gravity to the orientation and balance of the robot, it is important to consider where the center of gravity is when the robot is on unbalanced terrains, such as a ramp, and when the robot’s structure is being manipulated, such as a moving claw.
Here are a number of suggestions for the weight distribution:
- Generally, the center of gravity should be low on the robot in order for the robot to be stable on flat ground. If the center of gravity is too high, the robot might tilt and fall over.
- In addition, due to the effects of gravity, if the robot traverses up a ramp, the back of the robot contributes to the center of gravity more than the front of the robot. Thus it is optimal to have the center of gravity near the front of the robot in order to balance the robot on the hill. Otherwise, the robot would either not have enough power to travel up the hill.
Likewise, if the robot is traveling down a hill, the center of gravity should be adjusted towards the back of the robot in order to account for the effects of gravity. It is important that the center of gravity is aligned with the location of the motors in these scenarios or else the robot would tip over.
2. VEX CAD Assembly
Please thoroughly read the entire guide before starting your Fusion 360 assembly. There are some tips that will make creating your model much easier. Also, keep in mind it might take more than three Aligns to get your parts to snap into place at first, but once you complete a few and start to become comfortable with it, it should become faster. If you have any questions, feel free to ask a TA.
Preparation of Software
Invite to Collaborate in Fusion 360
- Download Fusion 360 from the Autodesk website
- Create an account with your NYU email or sign in
- Once downloaded, open Fusion 360
- In the top left corner of the window, click the Data Panel icon (Figure 2-1)
- In the Data Panel, click New Project. Name your project and press the Enter key
- Double click on the box with your project name. Go to the People tab at the top of the page
- Enter the email addresses of your teammates and click the Invite button
Download and Import VEX Parts
- Download the Autodesk VEX Kit of Parts (KoP). Make sure to download the Fusion 360 KoP for VEX EDR
- Extract the downloaded ZIP folder (Figure 2-2)
- In Fusion 360, go to the Data tab of your project and click New Folder. Name the new folder and press the Enter key. This folder will contain all the downloaded VEX parts for the project
- Double click the new folder that was just created. Click the Upload button
- In the dialog that just appeared, click Select Files
- In the File Explorer, navigate to the unzipped folder of VEX parts
- For Mac users, select the _MACOSX folder. For Windows users, select the Fusion_360_VEX_EDR_KOP folder. Select all the individual F3Z files in each folder to download. You can select all the F3Z files in individual folders but cannot select F3Z files from different folders. Select the files you believe you will need for your project. Click Open
- In the window that appears, click Upload
- The VEX parts will take a few minutes to upload from your files to Fusion 360. Once the upload is complete, click Close in the Job Status window. There should be new files in the Data Panel. You can double click one of the files to open the VEX part, or click and drag the files into your project to use them for the assembly
Creating the Assembly
In CAD, an assembly is a group of individual components that are aligned to each other using mating conditions. Mating conditions are definitions for the relative positions of components in respect to each other. Individual components usually require multiple mating conditions to become fully defined in 3D space. The general purpose of assemblies is to visualize how components become geometrically constrained in a system, and how these geometric constraints allow engineers to simulate, analyze, and evaluate their designs as to mimic real-life conditions. In Fusion 360, there are a few functions to generate mating conditions for assemblies. This guide will specifically cover the Align tool, Joint tool, and Rigid Group tool.
Note: "Connecting pieces" are screws, rods, shaft collars, wheels, etc.
The Align tool aligns the geometry from one component to the geometry of another component. The aligned geometry can be a surface, edge, or point. The Align tool is a simplified mating condition generator that makes all selected geometry coincident to each other.
- Move the two bodies being aligned close to one another using the Move/Copy tool (Figure 2-3)
- Under the Modify section of the toolbar, select the Align tool (Figure 2-4)
- The Align dialog will appear on the right side of the window (Figure 2-5). For the From profile, select the first surface, edge, or point being aligned. For the To profile, select the second surface, edge, or point. The first profile will become aligned to the second profile
- Repeat steps 1 - 3 using different points on the bodies being aligned until they are oriented as desired (Figure 2-6). Make sure the bodies are aligned as desired in the x-, y-, and z-directions
Rigid Group Tool
The Rigid Group tool locks the relative position of the selected components. The components are treated as a single object when moved or when joints are applied. Note that components like the wheels and motors are already sub-assemblies consisting of two or more bodies. They will have to be joined as a Rigid Group prior to being aligned with additional components.
- Select all the bodies of interest from the Browser on the left side of the window
- Go to the Assemble tab in the toolbar and select the Rigid Group tool (Figure 2-7). If prompted with a warning that states "some components have been moved", select Capture Position
- The Rigid Group dialog will appear on the right side of the window. Click OK to make the Rigid Group
In some instances, such as for the wheels, it will be required to align the gears of the drivetrain to the wheel before aligning the entire sub-assembly of the gears and wheel to the frame. Seeing that most designs have four wheels, repeating the process of aligning over and over can become tedious and time-consuming. Using the method below, sub-assemblies can be joined as one body and copied as many times as needed:
- Go to File > New Design in the same project as the rest of the VEX files
- Click and drag in desired components from the Data Panel
- Under the Modify tab of the toolbar, select the Align tool
- Align the components to each other
- Save the file in the same folder as all the downloaded Vex components
- Now you can drag newly made rigid group into the main robot assembly as many times as needed
Using this process whenever there are repeated components will greatly reduce the time needed to make the full assembly.
The VEX library is used in the EG1003 course to control the VEX robot and sensors using Arduino. The library is designed to more easily access the robot’s functionality. For more information on coding with Arduino, please reference the Arduino Coding Guide
The library is intended for use with the Adafruit Motor Shield V2, and VEX EDR 2-wire motors.
The library allows you to interface with the following sensors:
- MPU6050 Accelerometer and Gyroscope Sensor
- HC SR04 and VEX Ultrasonic Sensor
- VEX Touch/Button and VEX Limit Switch Sensor
- IR Obstacle Avoidance Sensor
The library also allows for the following functions of the motor board:
- Control single motor speed and direction
- Control two motors speed and direction simultaneously
Download the library files here
This library relies on multiple 3rd party libraries, including MPU6050, I2Cdev, and Adafruit Motor Shield V2, as well as inbuilt Arduino libraries including Wire.
There is one main class that controls the robot:
- Vex: commands the motor shield, and controls the motors for all robot movement
There are 2 classes that control different sensors:
- Gyro: reads data from the MPU6050 and provides the Euler angles around 3 axises
- Ultrasonic: reads the distance from itself to the nearest object it senses
Example files can be found by clicking on File>Examples>Vex. These Arduino C codes provided show the possibilities of the robot and provide tests for different functions.
- Movement Test: tests the standard robot movements, such as forward, turns, and claw movement
- Gyro Library Test: tests the gyro sensor to display the x,y, and z Euler angles
- Gyro Turning Test: tells the robot to do a 90o left and right turn based on the gyro sensor
- IR Obstacle Test: tests the IR obstacle avoidance sensor
- Touch Test: tests the touch sensor/limit switch to display whether or not the button/switch is pressed
- Ultrasonic Test: test the ultrasonic sensor by telling the robot to move forward until it is 5cm away from an obstacle
Importing the Library
- Open your main Arduino File.
- At the top of your screen, click on ‘Sketch,’ then ‘Include Library,’ then ‘Add .ZIP Library’’
- Next, find the library you would like to include. Make sure the file is unzipped. (If using Windows, to unzip a file, right-click the file and select ‘Extract All’). You must upload all four files in ‘EG VEX Libraries.’ Note: Arduino does not let you upload all of the libraries at once so repeat steps 2 and 3.
- Make sure to have ‘#include <Vex.h> ‘ at the top of your file.
Alternative Way to Import the Library
- Download the zipped EG VEX Libraries file here
- Extract the four libraries to separate folders
- Move the four libraries to the Arduino libraries folder
- This is usually Documents/Arduino/Libraries
- Restart the Arduino IDE to load the libraries
This class is used to interface with the motors connected to the Adafruit Motor Shield. The shield can support up to 4 DC motors and uses its own power source separate from the Arduino RedBoard.
The Adafruit Motor Shield comes with pins that connect the shield directly on top of the microcontroller. The shield can then be used just like the microcontroller, as it also has the standard pins used for the Arduino. In order to use the motor terminals labeled M1, M2, M3, and M4, the shield must be powered. For the VEX library, this should be done by connecting an external power source to the terminal shown in Figure 1. Figure 1 shows how to wire the motor shield with four DC motors and an external battery.
- In order to create a Vex object, the constructor must be called. Creating a Vex object allows you to call on the methods, which can also be referred to as functions, within the Vex Class. The constructor for a Vex object is empty meaning it has no parameters.
- Vex aNameForTheObject;
- Example: Vex Robot
- Create a Vex object named robot:
Note: All constructors should be called outside of functions setup() and loop(). Additionally, your Vex object can have any name (i.e Robot, vex, etc).
- The begin() method initializes the VEX robot. It must be called in the setup() function to use any other Vex methods.
Note: begin() does not initialize sensors. Refer to the documentation for the wanted sensor for reference on initializing these other modules.
- The setMotor() method sets up the motors for use with the motor shield. This function must be called in order to create the motor objects needed for the moveMotor() and moveTank() methods. It also cannot be used alone and must be called when setting an Adafruit_DCMotor object. See the example below for correct usage of the setMotor() method
- Adafruit_DCMotor* motor = vex.setMotor(port);
- In Figure 3-10, the third line of code creates a pointer (*) of type Adafruit_DCMotor that is named “motorA” and assigns it to the port in which the physical motor is connected to on the motor shield.
- port: An integer between 1 and 4, representing the motor port being used on the motor shield
- An Adafruit_DCMotor* object
- The end() method stops all robot movement. It is meant for use at the end of the code, to stop the robot from looping the original code over and over again.
Note: this method places the code within an infinite loop, therefore any code written after this method is called will not be run.
- Example: Robot.end();
- The moveMotor() method allows for the movement of a single motor, for a set power and time
- vex.moveMotor(motor, power, time);
- motor: an Adafruit_DCMotor* object, previously created using the setMotor() method.
- power: a double between -100 and 100. Positive numbers will move the motor clockwise, while negative numbers will move the motor counterclockwise. 0 will cause the motor to not move.
- time: a positive double, representing the number of seconds to run the motor.
- The moveTank() method allows for the movement of two motors simultaneously, for two different power values, over a set period of time
- vex.moveTank(motor1, motor2, power1, power2, time);
- motor1: an Adafruit_DCMotor* object, previously created using the setMotor() method
- motor2: an Adafruit_DCMotor* object, previously created using the setMotor() method
- power1: a double between -100 and 100. This value controls the power of motor1. Positive numbers will move the motor clockwise, while negative numbers will move the motor counterclockwise. 0 will cause the motor to not move.
- power2: a double between -100 and 100. This value controls the power of motor2. Positive numbers will move the motor clockwise, while negative numbers will move the motor counterclockwise. 0 will cause the motor to not move.
- time: a positive double, representing the number of seconds to run the motor
This class is used to interface with the MPU6050 Accelerometer and Gyroscope. It is created specifically to provide the values of the Euler Angles as calculated from the gyroscope. Note: As the Gyro class is made specifically for this function, it cannot be used to access the additional functionalities of the MPU6050 device. Any other use of the MPU6050 outside of this class is at the discretion of the student.
Figure 2 shows how to wire the MPU6050 sensor. Note that the Int pin on the MPU6050 must be connected to digital pin 2 on the Arduino board for the sensor to work within this library
VCC: 3V or 5V
- GND: ground
- SCL: analog pin 5
- SDA: analog pin 4
- INT: Digital Pin 2
- In order to create a Gyro object, the constructor must be called. Creating a Gyro object allows you to call on the methods, which can also be referred to as functions, within the Gyro Class. The constructor for a Gyro object is empty (has no parameters).
- The begin() method initializes the gyro. It must be called in the setup() function to use any other Gyro methods
Note: begin() only initializes the gyro sensor. Refer to the documentation for the wanted sensor for reference on initializing other modules
- The getZAngle() method returns the calculated Euler angle about the Z-axis
- A float (decimal) value representing the angle.
- The getYAngle() method returns the calculated Euler angle about the Y-axis
- A float value representing the angle
- The getXAngle() method returns the calculated Euler angle about the X-axis
- A float value representing the angle
The Ultrasonic Sensor is used to determine how far away an object is. This is useful for obstacle avoidance. The HC-SR04 ultrasonic sensor uses a process similar to echolocation to operate. The sensor transmits a high-frequency signal, then it receives the signal after it gets reflected by the object. The sensor determines the time elapsed between transmission and reception. This can be used to calculate the distance from the sensor to the object using the speed of sound (343m/s).
The ultrasonic sensor has four pins: Voltage (VCC), Ground (GND), Trigger (TRIG), and Echo. VCC and GND need to be connected to voltage and ground, respectively. Trigger (or transmitter) is used for the sensor to create the high-frequency signal that gets transmitted, while Echo (or receiver) is used to receive the reflected signal. Trig and Echo can be connected to any digital I/O pins. The working voltage for ultrasonic sensor is 5V, its maximum range is 4m, and its minimum range is 2cm. Male/female jumper wires can be used to connect the ultrasonic sensor to the breadboard. Figure 4A & 4B show how to correctly wire the ultrasonic sensor.
- VCC: 5V
- Trigger: digital I/O pin
- Echo: digital I/O pin
- GND: ground
- In order to create an Ultrasonic object, the constructor must be called. The Ultrasonic constructor takes two parameters, one for the trigger pin and one for the echo pin.
Note: The Trigger and Echo Pins refer to the pin number on the Arduino/Motor Shield the trigger/echo pins are wired to.
- Ultrasonic ultrasonic(triggerPin, echoPin);
- triggerPin: an integer representing the digital pin used for the trigger
- echoPin: an integer representing the digital pin used for the echo
- The begin() method initializes the ultrasonic sensor. It must be called in the setup() function to use any other ultrasonic methods.
- The checkUltrasonic() method returns the distance (in centimeters) between the sensor and the first object it detects.
Note: The minimum distance the sensor can detect is 2cm, while the maximum distance is 4m.
- A long representing the distance (in centimeters) between the sensor and the first object it detects.
The Touch Class is used to interface with the VEX touch sensor or VEX limit switch. The class provides boolean values representing when the switch on the sensor has been pressed.
The Touch Sensor is connected to two pins on the Arduino/Adafruit MotorShield, Ground (GND) and a Digital Pin. In Figure 5, the Digital Pin is connected to Digital Pin 3. The Touch Sensor works so that whenever it is pressed, a certain line of code or function can occur.
- GND: ground
- touchPin: Digital Pin
- The constructor takes one parameter, for the digital pin. The constructor must be called in order to create a Touch object
- Touch touch(pin);
- Pin: an integer representing the digital pin used by the sensor
- The begin() method is used to initialize the touch sensor. It must be called in the setup() function in order to use any other Touch methods
- The isPushed() method returns a boolean value depending on whether or not the button on the sensor has been pressed.
- A boolean value. True indicates the button has been pushed, while false indicates the button has not been pushed
This class is used to interface with the IR Obstacle Avoidance Sensor. This sensor will only return whether or not there is an obstacle directly in front of the sensor.
The sensor uses an infrared emitter LED. This signal is then received by an infrared receiver to determine whether or not there is an obstacle. The distance adjust terminal can be used to adjust the detection distance. Turning the screw counterclockwise will decrease the distance while turning the screw clockwise will increase the distance.
Note: As the IRObstacle class is made specifically for this function, it cannot be used to access the additional functionalities of the MPU6050 device. Any other use of the MPU6050 outside of this class is at the discretion of the student.
- Figure 7 shows how to wire the IR obstacle avoidance sensor
- VCC: 3V or 5V
- GND: ground
- OUT: digital pin
- In order to create an IRObstacle object the constructor must be called. It has one parameter for the digital pin.
- IRObstacle ir(pin);
- Pin: an integer representing the digital pin used for the sensor
- The begin() method initializes the IR obstacle avoidance sensor. It must be called in the setup() function to use any other IRObstacle methods
Note: begin() only initializes the IR obstacle avoidance sensor. Refer to the documentation for the wanted sensor for reference on initializing other modules.
- The isObstacle() method returns a boolean value depending on whether or not the sensor detects an obstacle.
- A boolean value. HIGH indicates an obstacle is detected, while LOW indicates no obstacle was detected