0
0
Power-electronicsProgramBeginner · 2 min read

Embedded C Program for Obstacle Avoidance Robot

An obstacle avoidance robot in Embedded C reads sensor inputs using digitalRead() or ADC and controls motors with digitalWrite() to move forward or turn when an obstacle is detected, as shown in if(sensor_detects_obstacle) { stop_motors(); turn_robot(); } else { move_forward(); }.
📋

Examples

InputNo obstacle detected
OutputRobot moves forward
InputObstacle detected on front sensor
OutputRobot stops and turns right
InputObstacle detected on left sensor
OutputRobot stops and turns right
🧠

How to Think About It

To build an obstacle avoidance robot, first read the sensor values to detect obstacles. If an obstacle is detected, stop the motors and turn the robot away from the obstacle. If no obstacle is detected, keep moving forward. This simple decision-making loop runs continuously.
📐

Algorithm

1
Read obstacle sensor input
2
If obstacle detected, stop motors
3
Turn robot to avoid obstacle
4
If no obstacle, move forward
5
Repeat the process continuously
💻

Code

embedded_c
#include <avr/io.h>
#include <util/delay.h>

#define SENSOR_PIN (PIND & (1 << PIND2)) // Example sensor input pin
#define MOTOR_PORT PORTB
#define MOTOR_DDR DDRB
#define MOTOR_FORWARD (1 << PB0)
#define MOTOR_TURN (1 << PB1)

void move_forward() {
    MOTOR_PORT |= MOTOR_FORWARD;
    MOTOR_PORT &= ~MOTOR_TURN;
}

void turn_right() {
    MOTOR_PORT &= ~MOTOR_FORWARD;
    MOTOR_PORT |= MOTOR_TURN;
}

void stop_motors() {
    MOTOR_PORT &= ~(MOTOR_FORWARD | MOTOR_TURN);
}

int main(void) {
    MOTOR_DDR |= MOTOR_FORWARD | MOTOR_TURN; // Set motor pins as output
    DDRD &= ~(1 << PIND2); // Set sensor pin as input

    while(1) {
        if (SENSOR_PIN == 0) { // Obstacle detected (active low)
            stop_motors();
            _delay_ms(200);
            turn_right();
            _delay_ms(500);
        } else {
            move_forward();
        }
    }
    return 0;
}
Output
Robot moves forward when no obstacle; stops and turns right when obstacle detected
🔍

Dry Run

Let's trace the robot behavior when an obstacle is detected and when no obstacle is present.

1

Check sensor input

SENSOR_PIN reads 1 (no obstacle) or 0 (obstacle)

2

Decision making

If SENSOR_PIN == 0, stop motors and turn right; else move forward

3

Motor control

Set MOTOR_PORT bits to control motor direction

Sensor InputActionMotor_PORT State
1 (no obstacle)Move forwardMOTOR_FORWARD bit set, MOTOR_TURN bit cleared
0 (obstacle)Stop and turn rightMOTOR_FORWARD bit cleared, MOTOR_TURN bit set after delay
💡

Why This Works

Step 1: Sensor Reading

The program reads the sensor pin using PIND & (1 << PIND2) to detect obstacles.

Step 2: Motor Control

Motor pins are controlled by setting or clearing bits in PORTB to move forward or turn.

Step 3: Decision Loop

The main loop continuously checks sensors and decides to move forward or turn to avoid obstacles.

🔄

Alternative Approaches

Using ADC for analog distance sensor
embedded_c
#include <avr/io.h>
#include <util/delay.h>

void ADC_init() {
    ADMUX = (1 << REFS0); // AVcc reference
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
}

uint16_t ADC_read(uint8_t channel) {
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC));
    return ADC;
}

int main(void) {
    ADC_init();
    // Motor init code here
    while(1) {
        uint16_t distance = ADC_read(0); // Read sensor
        if (distance < 300) { // Threshold
            // Stop and turn
        } else {
            // Move forward
        }
    }
    return 0;
}
This approach uses analog sensors for more precise distance measurement but requires ADC setup.
Using interrupt for sensor detection
embedded_c
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int obstacle_detected = 0;

ISR(INT0_vect) {
    obstacle_detected = 1;
}

int main(void) {
    // Setup interrupt on sensor pin
    sei();
    while(1) {
        if (obstacle_detected) {
            // Stop and turn
            obstacle_detected = 0;
        } else {
            // Move forward
        }
    }
    return 0;
}
Using interrupts can make the robot respond faster to obstacles but adds complexity.

Complexity: O(1) time, O(1) space

Time Complexity

The program runs in a continuous loop with simple conditional checks, so time complexity per iteration is constant O(1).

Space Complexity

Uses fixed memory for variables and hardware registers, so space complexity is O(1).

Which Approach is Fastest?

Direct sensor polling is simple and fast for small robots; interrupt-based methods add responsiveness but more code complexity.

ApproachTimeSpaceBest For
Direct Sensor PollingO(1)O(1)Simple robots, easy to implement
ADC Analog SensorO(1)O(1)Precise distance measurement
Interrupt-based DetectionO(1)O(1)Fast response to obstacles
💡
Always debounce or filter sensor inputs to avoid false obstacle detection.
⚠️
Beginners often forget to set sensor pins as input or motor pins as output, causing the robot not to respond.