Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2026:andrei.batasev:dorian.gilca [2026/05/09 21:05]
dorian.gilca created
pm:prj2026:andrei.batasev:dorian.gilca [2026/05/25 09:55] (current)
dorian.gilca
Line 1: Line 1:
 ====== Adaptive Cruise Control Vehicle ====== ====== Adaptive Cruise Control Vehicle ======
 +
 ===== Introduction ===== ===== Introduction =====
  
-What it does: +**What it does:** 
-This project consists of a small autonomous vehicle capable of maintaining a constant safe distance from a target ​vehicle or object in front of it.+This project consists of a small autonomous vehicle capable of maintaining a constant safe distance from a target object ​or vehicle ​in front of it.
  
-Its purpose: +**Its purpose:** 
-The main goal is to implement a real-time closed-loop control system (Adaptive Cruise Control) on an 8-bit microcontroller. It demonstrates bare-metal embedded programming by utilizing hardware interrupts, hardware timers, and a PID (Proportional-Integral-Derivative) control algorithm.+The main goal is to implement a real-time closed-loop control system (Adaptive Cruise Control) on an 8-bit microcontroller. It demonstrates bare-metal embedded programming by utilizing hardware interrupts, hardware timers, and custom serial protocols, completely avoiding high-level abstractions like Arduino libraries.
  
-The starting idea:+**The starting idea:**
 The idea is inspired by modern Advanced Driver Assistance Systems (ADAS) used in the automotive industry to prevent rear-end collisions and improve driving comfort. The idea is inspired by modern Advanced Driver Assistance Systems (ADAS) used in the automotive industry to prevent rear-end collisions and improve driving comfort.
  
-Why it is useful:+**Why it is useful:**
 It serves as a highly practical demonstration of low-level hardware control, bridging the gap between theoretical micro-processor architecture and real-world physical applications. It serves as a highly practical demonstration of low-level hardware control, bridging the gap between theoretical micro-processor architecture and real-world physical applications.
  
 ===== General Description ===== ===== General Description =====
  
-The system uses an array of ultrasonic ​sensors ​mounted on the front to continuously measure the distance to the vehicle ​ahead.+The system uses an ultrasonic ​sensor ​mounted on the front to continuously measure the distance to the obstacle ​ahead. ​
  
-Based on the calculated distance ​error (the difference between the desired safe distance and the actual measured distance), a PID control algorithm calculates the necessary adjustments. These adjustments are sent as PWM signals ​to a TB6612FNG ​motor driverenabling ​the car to smoothly accelerate or brakeAn optical encoder on the rear wheel provides closed-loop speed feedback to ensure accurate motor control. Optionally, the front steering is controlled by a servo motor to follow ​the target'​s trajectory.+Based on the calculated distance, a proportional ​control algorithm calculates the necessary ​speed adjustments to maintain ​safe gap. The system smoothly interpolates the motor speed using hardware PWM based on the target'​s distance. If the target is too close (under 25 cm), the vehicle applies the brakesIf the target is within the tracking range (25 cm 85 cm)it adjusts ​the speed dynamically ​to follow ​it.
  
-Block Diagram: +**Block Diagram:** 
-//To be uploaded//+ 
 + 
 +{{:​pm:​prj2026:​andrei.batasev:​schema_bloc.jpg?​300|}}
  
 ===== Hardware Design ===== ===== Hardware Design =====
  
-List of components:+**List of components:** 
 +  * Arduino UNO (ATmega328P Microcontroller) serving as the main processing unit. 
 +  * L293D Motor Drive Shield (featuring the 74HC595 shift register). 
 +  * 1x HC-SR04 Ultrasonic Sensor. 
 +  * 2x DC TT Motors (Rear-wheel or 4-wheel drive configuration). 
 +  * 2x 18650 Li-Ion Batteries (7.4V total) with holder. 
 +  * Robot car chassis with wheels. 
 +  * Dupont connecting wires.
  
-Arduino Nano (ATmega328P Microcontroller)+**Electrical Schematic:​**
  
-3x HC-SR04+ Ultrasonic Sensors 
  
-TB6612FNG Motor Driver 
  
-1x DC Motor with Optical Encoder (Rear traction)+{{:​pm:​prj2026:​andrei.batasev:​schema_electrica.jpg?​300|}}
  
-1x Servo Motor (Front steering) 
  
-LM2596 Step-Down Voltage Regulator+===== Software Design =====
  
-2x 18650 Li-Ion Batteries with holder+<code c> 
 +#include <​avr/​io.h>​ 
 +#include <​avr/​interrupt.h>​ 
 +#include <​util/​delay.h>​ 
 +#include <​stdio.h>​
  
-Breadboard and Dupont connecting wires+#define PM_BAUD 9600
  
-Electrical Schematic: +#define TRIG_PIN PC0 
-//To be uploaded after the circuit design is finalized.//​+#define ECHO_PIN PC1
  
-===== Software Design =====+#define LATCH_PIN PB4 
 +#define CLK_PIN ​  PD4 
 +#define EN_PIN ​   PD7 
 +#define DATA_PIN ​ PB0
  
-Development Environment:​+#define M1_A 2 
 +#define M1_B 3 
 +#define M2_A 1 
 +#define M2_B 4
  
-PlatformIO / Arduino IDE (using pure C/C++ and register-level programming)+volatile uint16_t timer_val = 0; 
 +volatile uint8_t echo_done = 0;
  
-Libraries and 3rd-party sources:+static int _usart0_putchar(char c, FILE *stream) { 
 +    if (c == '​\n'​) _usart0_putchar('​\r',​ stream); 
 +    while (!(UCSR0A & (1<<​UDRE0)));​ 
 +    UDR0 = c; 
 +    return 0; 
 +}
  
-Standard AVR libc (<​avr/​io.h>​<​avr/​interrupt.h>​)+static FILE USART0_stdout = FDEV_SETUP_STREAM(_usart0_putcharNULL, _FDEV_SETUP_WRITE);
  
-No high-level Arduino libraries ​(like analogWrite or pulseInwill be used for core functionalities,​ to adhere to the course requirements.+void usart_init() 
 +    UBRR0H = (unsigned char)(103>>​8);​ //br9600 
 +    UBRR0L = (unsigned char)103; 
 +    UCSR0B = (1<<​RXEN0) | (1<<​TXEN0);​ //act transmisia 
 +    UCSR0C = (1<<​USBS0) | (3<<​UCSZ00);​ //8b 
 +    stdout = &​USART0_stdout;​ 
 +}
  
-Algorithms and Structures:+void shift_out_data(uint8_t data) { 
 +    PORTB &= ~(1<<​LATCH_PIN);​  
 +     
 +    for(int i=0; i<8; i++) { //pt fiecare bit 
 +        PORTD &= ~(1<<​CLK_PIN);​ 
 +        if(data & (1 << (7-i))) { 
 +            PORTB |= (1<<​DATA_PIN);​ //punem val d 
 +        } else { 
 +            PORTB &= ~(1<<​DATA_PIN);​ 
 +        } 
 +        PORTD |= (1<<​CLK_PIN);​ //ridicam si coboram pin clock 
 +    } 
 +     
 +    PORTB |= (1<<​LATCH_PIN);​  
 +}
  
-PID Controller: A mathematical algorithm to smoothly calculate the motor speed based on the distance error.+void motors_init() { 
 +    DDRB |= (1<<​LATCH_PIN) | (1<<​DATA_PIN) | (1<<​PB3);​ 
 +    DDRD |= (1<<​CLK_PIN) | (1<<​EN_PIN) | (1<<​PD3);​
  
-Pin Change Interrupts ​(PCINT): Used to read the echo signals from the ultrasonic sensors without blocking the CPU.+    PORTD &= ~(1<<​EN_PIN);
  
-Hardware Timers: Configured at the register level to generate the fast PWM signals for the motor driver and the precise signal for the servo motor.+    TCCR2A = (1<<​COM2A1) | (1<<​COM2B1) | (1<<​WGM21) | (1<<​WGM20);​ 
 +    TCCR2B = (1<<​CS22);​ 
 +     
 +    OCR2A = 0; // punem viteza in registrii 
 +    OCR2B = 0;
  
-===== Obtained Results =====+    shift_out_data(0);​ 
 +}
  
-//This section will be updated after the hardware assembly and software implementation//​+void set_motor_dir(int m1_fwd, int m1_rev, int m2_fwd, int m2_rev) { 
 +    uint8_t shift_data = 0; 
 +    if (m1_fwd) shift_data |= (1<<​M1_A);​ 
 +    if (m1_rev) shift_data |= (1<<​M1_B);​ 
 +    if (m2_fwd) shift_data |= (1<<​M2_A);​ 
 +    if (m2_rev) shift_data |= (1<<​M2_B);​ 
 +    shift_out_data(shift_data);​ 
 +}
  
-===== Conclusions =====+void sonar_init() { 
 +    DDRC |(1<<​TRIG_PIN);​ //pc0 output 
 +    DDRC &~(1<<​ECHO_PIN); ​
  
-//This section will be updated at the end of the project//+    TCCR1A = 0; 
 +    TCCR1B = (1<<​CS11);​
  
-===== Download =====+    PCICR |(1<<​PCIE1);​ 
 +    PCMSK1 |(1<<​PCINT9);​ 
 +}
  
-//Source code and schematics will be uploaded here in a .zip archive and linked to a public GitHub repository at the end of the semester.//+ISR(PCINT1_vect) { 
 +    if (PINC & (1<<​ECHO_PIN)) { 
 +        TCNT1 = 0; 
 +    } else { 
 +        timer_val = TCNT1; 
 +        echo_done = 1; 
 +    } 
 +}
  
-===== Journal =====+int get_distance() { 
 +    echo_done ​0; 
 +     
 +    PORTC &~(1<<​TRIG_PIN);​ 
 +    _delay_us(2);​ 
 +    PORTC |(1<<​TRIG_PIN);​ 
 +    _delay_us(10);​ 
 +    PORTC &~(1<<​TRIG_PIN);​
  
-09.05.2026: Chosen the project topic, validated the idea with the laboratory assistant, and completed the initial OCW documentation ​(Introduction,​ General Description,​ Hardware List).+    uint32_t timeout = 60000; 
 +    while(!echo_done && timeout > 0
 +        timeout--;​ 
 +    }
  
-===== Bibliography/​Resources =====+    if(timeout ​== 0) return 400;
  
-Hardware Resources:+    return timer_val / 116; 
 +}
  
-ATmega328P Datasheet+int map_speed(int x, int in_min, int in_max, int out_min, int out_max) { 
 +    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 
 +}
  
-HC-SR04+ Ultrasonic Sensor specifications+int main() { 
 +    usart_init();​ 
 +    motors_init();​ 
 +    sonar_init();​ 
 +     
 +    sei(); 
 +    printf("​ACC System Bare Metal Started\n"​);​
  
-TB6612FNG Motor Driver datasheet+    int safe_dist = 25; 
 +    int max_dist = 85; 
 + 
 +    while(1) { 
 +        int dist = get_distance();​ 
 +        if(dist == 0 || dist > 400) dist = 400; 
 + 
 +        printf("​Dist:​ %d cm\n", dist); 
 + 
 +        if (dist > max_dist) { 
 +            set_motor_dir(0,​ 0, 0, 0); 
 +            OCR2A = 0; 
 +            OCR2B = 0; 
 +        } else if (dist > safe_dist) { 
 +            int speed = map_speed(dist,​ safe_dist, max_dist, 115, 220); 
 +            set_motor_dir(1,​ 0, 1, 0); 
 +            OCR2A = speed; 
 +            OCR2B = speed; 
 +        } else { 
 +            set_motor_dir(0,​ 0, 0, 0); 
 +            OCR2A = 0; 
 +            OCR2B = 0; 
 +        } 
 + 
 +        _delay_ms(50);​ 
 +    } 
 +    return 0; 
 +
 +</​code>​ 
 +**Development Environment:​** 
 +  * VS Code with PlatformIO (using pure C and register-level programming). 
 + 
 +**Libraries and 3rd-party sources:​** 
 +  * Standard AVR libc (<​avr/​io.h>,​ <​avr/​interrupt.h>,​ <​util/​delay.h>,​ <​stdio.h>​). 
 +  * **Zero** high-level Arduino libraries (like `analogWrite`,​ `digitalWrite`,​ or `pulseIn`) were used. 
 + 
 +**Algorithms and Hardware Features utilized:​** 
 +  * **Bit-Banging for Shift Register:** The L293D shield uses a 74HC595 shift register to control motor directions. A custom synchronous serial protocol was implemented (`shift_out_data`) to manually push bits to the latch, clock, and data pins using direct port manipulation (`PORTB`, `PORTD`). 
 +  * **Hardware Timers (Fast PWM):** Timer2 was configured at the register level (`TCCR2A`, `TCCR2B`) to generate a pure hardware Fast PWM signal on pins OC2A and OC2B. This controls the motor speed without utilizing CPU cycles. 
 +  * **Pin Change Interrupts (PCINT) & Timer1:** To avoid blocking the CPU while waiting for the ultrasonic echo, the Echo pin was mapped to a Pin Change Interrupt (`PCINT1_vect`). Timer1 counts the micro-seconds in the background, making the distance reading asynchronous and highly efficient. 
 +  * **Custom USART Stream:** The USART module was initialized manually (`UBRR0`, `UCSR0`), and the standard output stream (`stdout`) was redirected to the serial port, allowing the use of `printf()` for clean, professional real-time debugging. 
 + 
 +===== Obtained Results ===== 
 + 
 +The system reacts accurately and smoothly to dynamic environments.  
 +  * The custom non-blocking ultrasonic reading accurately updates the distance without hanging the main loop. 
 +  * The proportional mapping successfully overcomes the static friction of the DC motors by setting a calculated minimum PWM threshold (115), ensuring the car starts moving reliably even at low speeds. 
 +  * The car smoothly decelerates as it approaches the 25 cm safety threshold and completely halts to prevent collisions. 
 + 
 +**Final Project Photo:** 
 + 
 + 
 + 
 +{{:​pm:​prj2026:​andrei.batasev:​2111.jpeg?​200|}} 
 +{{:​pm:​prj2026:​andrei.batasev:​999.jpeg?​200|}} 
 +===== Conclusions ===== 
 + 
 +Implementing this project in a bare-metal C environment provided profound insights into the internal workings of the ATmega328P microcontroller. Stripping away the Arduino framework forced a deeper understanding of memory mapping, the crucial difference between polling and hardware interrupts, and the complexity of generating custom serial signals (bit-banging). The project successfully replicates an industrial ADAS concept on an 8-bit architecture. 
 + 
 +===== Download ===== 
 +{{:​pm:​prj2026:​andrei.batasev:​dorian_gilca.zip|Project Archive - Source Code and PlatformIO Configuration}} 
 + 
 +===== Journal ===== 
 + 
 +  * **09.05.2026**:​ Chosen the project topic and completed the initial OCW documentation. 
 +  * **17.05.2026**:​ Assembled the hardware components, tested the L293D motor shield, and resolved DC motor wiring issues. 
 +  * **19.05.2026**:​ Fully migrated to VS Code / PlatformIO. Successfully implemented bare-metal code integrating PCINT for the HC-SR04 sensor, Timer2 Fast PWM for motor speed, and custom bit-banging for directional control. Tuned the PWM thresholds to overcome static friction. 
 + 
 +===== Bibliography/​Resources =====
  
-Software ​Resources:+**Hardware ​Resources:** 
 +  * ATmega328P Datasheet (Microchip Technology) 
 +  * HC-SR04 Ultrasonic Sensor Specifications 
 +  * L293D Motor Shield Schematic & 74HC595 Datasheet
  
-AVR Libc Reference Manual+**Software Resources:​** 
 +  * AVR Libc Reference Manual 
 +  * PlatformIO Documentation
pm/prj2026/andrei.batasev/dorian.gilca.1778349912.txt.gz · Last modified: 2026/05/09 21:05 by dorian.gilca
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0