Embedded C Program for Line Follower Robot
if conditions and controls motors by setting output pins; for example, use if(sensor_left == 1 && sensor_right == 0) { move_left(); } to turn left when the left sensor detects the line.Examples
How to Think About It
if statements to check sensor values and control motor pins accordingly.Algorithm
Code
#include <avr/io.h> #define LEFT_SENSOR (PIND & (1 << PD0)) #define RIGHT_SENSOR (PIND & (1 << PD1)) void move_forward() { PORTB = 0x06; // Both motors forward } void turn_left() { PORTB = 0x04; // Left motor stop, right motor forward } void turn_right() { PORTB = 0x02; // Left motor forward, right motor stop } void stop() { PORTB = 0x00; // Stop motors } int main(void) { DDRD &= ~((1 << PD0) | (1 << PD1)); // Set PD0, PD1 as input DDRB = 0xFF; // Set PORTB as output for motors while(1) { if (LEFT_SENSOR && RIGHT_SENSOR) { move_forward(); } else if (LEFT_SENSOR && !RIGHT_SENSOR) { turn_left(); } else if (!LEFT_SENSOR && RIGHT_SENSOR) { turn_right(); } else { stop(); } } return 0; }
Dry Run
Let's trace sensor inputs through the code to see motor control decisions.
Sensors read
LEFT_SENSOR=1, RIGHT_SENSOR=0
Condition check
LEFT_SENSOR && RIGHT_SENSOR = 0 (false) LEFT_SENSOR && !RIGHT_SENSOR = 1 (true)
Action taken
turn_left() called, PORTB set to 0x04
| LEFT_SENSOR | RIGHT_SENSOR | Action | PORTB Value |
|---|---|---|---|
| 1 | 0 | turn_left() | 0x04 |
| 1 | 1 | move_forward() | 0x06 |
| 0 | 1 | turn_right() | 0x02 |
| 0 | 0 | stop() | 0x00 |
Why This Works
Step 1: Reading sensors
The program reads two sensors connected to input pins PD0 and PD1 using bitwise AND to detect line presence.
Step 2: Decision making
Using if conditions, the program decides the robot's movement based on which sensors detect the line.
Step 3: Motor control
Motor pins on PORTB are set to drive motors forward, turn left, right, or stop, controlling the robot's direction.
Alternative Approaches
#include <avr/io.h> int read_adc_channel(uint8_t channel) { ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); ADCSRA |= (1 << ADSC); while (ADCSRA & (1 << ADSC)); return ADC; } int main(void) { // Initialize ADC and motors // Use ADC values to decide motor control return 0; }
// Setup external interrupts on sensor pins to react immediately // Interrupt service routines adjust motor control int main(void) { // Setup code while(1) { // Main loop can be empty or handle other tasks } return 0; }
Complexity: O(1) time, O(1) space
Time Complexity
The program runs in an infinite loop with simple conditional checks, so each iteration runs in constant time.
Space Complexity
Uses fixed memory for variables and no dynamic allocation, so space is constant.
Which Approach is Fastest?
Direct sensor reading with simple if-else is fastest and simplest; ADC or interrupt methods add complexity and overhead.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Direct sensor input with if-else | O(1) | O(1) | Simple, fast line following |
| ADC sensor reading | O(1) | O(1) | Analog line detection, more precise |
| Interrupt-driven control | O(1) | O(1) | Responsive control, complex systems |