This project combines several components to build a simple robot that can detect and avoid obstacles. Students will integrate sensors and motors.
Mount the ESP32, L298N, and breadboard onto the robot chassis. Connect the L298N to the ESP32 and the two TT motors as described in Project 4 (using both motor channels of the L298N). Connect the external motor power supply to the L298N. Mount the HC-SR04 ultrasonic sensor to the front of the chassis. Connect the HC-SR04 to the ESP32 as described in Project 3, including the voltage divider for the Echo pin.
The MicroPython code will continuously read the distance from the ultrasonic sensor. If the distance is below a certain threshold, the robot will stop and perform an obstacle avoidance maneuver (e.g., turn in place, back up and turn). If no obstacle is detected, the robot will move forward.
A web interface could display the current distance reading and the robot’s current status (e.g., “Moving Forward”, “Obstacle Detected”, “Turning”).
# This script controls a robot with obstacle avoidance and displays status # and distance on an OLED screen. from machine import Pin, PWM, I2C # Import necessary classes import time # Import SSD1306 library. try: import ssd1306 except ImportError: print("ssd1306.py library not found. Please upload it.") class MockSSD1306: def __init__(self, width, height, i2c): print(f"MockSSD1306 initialized ({width}x{height}).") def fill(self, color): pass def text(self, text, x, y, color): pass def show(self): print(f"OLED display content not shown (ssd1306 library missing): {text}") ssd1306 = type('ssd1306', (object,), {'SSD1306_I2C': MockSSD1306})() # --- Motor Control Setup (from Project 4) --- in1_pin_A = 17 in2_pin_A = 16 ena_pin_A = 18 # PWM-capable in3_pin_B = 13 in4_pin_B = 12 enb_pin_B = 14 # PWM-capable in1_A = Pin(in1_pin_A, Pin.OUT) in2_A = Pin(in2_pin_A, Pin.OUT) in3_B = Pin(in3_pin_B, Pin.OUT) in4_B = Pin(in4_pin_B, Pin.OUT) pwm_ena_A = PWM(Pin(ena_pin_A), freq=1000) pwm_enb_B = PWM(Pin(enb_pin_B), freq=1000) def control_motor_A(direction, speed): speed = max(0, min(1023, speed)) if direction == "forward": in1_A.value(1) in2_A.value(0) elif direction == "reverse": in1_A.value(0) in2_A.value(1) else: # stop in1_A.value(0) in2_A.value(0) pwm_ena_A.duty(speed) def control_motor_B(direction, speed): speed = max(0, min(1023, speed)) if direction == "forward": in3_B.value(1) in4_B.value(0) elif direction == "reverse": in3_B.value(0) in4_B.value(1) else: # stop in3_B.value(0) in4_B.value(0) pwm_enb_B.duty(speed) # Function to move the robot and update OLED status def move_robot(left_direction, left_speed, right_direction, right_speed, status_text): control_motor_A(left_direction, left_speed) control_motor_B(right_direction, right_speed) print("Robot:", status_text) # Print to console for debugging # Update OLED status oled.text("Status:", 0, 16, 1) # Clear previous status text (optional, but good for fixed position updates) oled.fill_rect(0, 24, oled_width, 8, 0) # Clear line below status label oled.text(status_text, 0, 24, 1) oled.show() # Robot basic movements with OLED status update def move_forward(speed): move_robot("forward", speed, "forward", speed, "Moving Forward") def move_reverse(speed): move_robot("reverse", speed, "reverse", speed, "Moving Reverse") def turn_left(speed): move_robot("reverse", speed, "forward", speed, "Turning Left") def turn_right(speed): move_robot("forward", speed, "reverse", speed, "Turning Right") def stop_robot(): move_robot("stop", 0, "stop", 0, "Stopped") # --- Ultrasonic Sensor Setup (from Project 3) --- trigger_pin_us = 4 echo_pin_us = 5 trigger_us = Pin(trigger_pin_us, Pin.OUT) echo_us = Pin(echo_pin_us, Pin.IN) speed_of_sound_cm_per_us = 0.0343 def measure_distance(): trigger_us.value(0) time.sleep_us(2) trigger_us.value(1) time.sleep_us(10) trigger_us.value(0) pulse_start = time.ticks_us() pulse_end = time.ticks_us() timeout_us = 20000 # Timeout after 20ms start_time = time.ticks_us() while echo_us.value() == 0: pulse_start = time.ticks_us() if time.ticks_diff(pulse_start, start_time) > timeout_us: return -1 start_time = time.ticks_us() while echo_us.value() == 1: pulse_end = time.ticks_us() if time.ticks_diff(pulse_end, start_time) > timeout_us: return -1 pulse_duration_us = time.ticks_diff(pulse_end, pulse_start) if pulse_duration_us > 0: distance_cm = (pulse_duration_us * speed_of_sound_cm_per_us) / 2 return distance_cm else: return -1 # --- OLED Setup --- i2c_sda = 21 i2c_scl = 22 oled_width = 128 oled_height = 32 i2c = I2C(0, sda=Pin(i2c_sda), scl=Pin(i2c_scl), freq=400000) oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) # Clear the OLED display on startup oled.fill(0) oled.text("Robot Starting...", 0, 0, 1) oled.show() time.sleep(1) # --- Robot Control Logic --- obstacle_threshold_cm = 25 drive_speed = 600 turn_speed = 500 turn_duration = 0.8 # Duration in seconds for turning print("Starting obstacle avoidance robot script with OLED display...") # Start the main robot control loop. while True: # Measure the distance. distance = measure_distance() # --- Display Distance on OLED --- oled.fill_rect(0, 0, oled_width, 8, 0) # Clear previous distance text line oled.text("Dist: ", 0, 0, 1) if distance != -1: oled.text("{:.1f} cm".format(distance), 35, 0, 1) # Display value else: oled.text("N/A", 35, 0, 1) # Indicate no reading oled.show() # Update OLED with distance # Check for obstacle and control robot movement. if distance != -1 and distance < obstacle_threshold_cm: stop_robot() # This function also updates OLED status time.sleep(0.5) move_reverse(drive_speed) time.sleep(1) stop_robot() time.sleep(0.5) turn_right(turn_speed) time.sleep(turn_duration) stop_robot() time.sleep(0.5) time.sleep(0.5) # Give sensor time to settle distance_after_turn = measure_distance() print("Distance after turn:", distance_after_turn, "cm") else: move_forward(drive_speed) # This function also updates OLED status time.sleep(0.1) # This loop will run forever. # Troubleshooting notes: # - See troubleshooting notes from Project 7, Project 3 (Ultrasonic), and Project 2 (OLED). # - Ensure both ssd1306.py is on the ESP32. # - Debug motor control and ultrasonic sensor functionality independently first. # - Check OLED wiring and I2C communication.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.