📋 Quick Summary
Build an autonomous obstacle-avoiding robot car using Arduino Uno, L293D motor shield, HC-SR04 ultrasonic sensor, and an SG90 servo motor for scanning. The robot detects obstacles, scans left and right to find the clearest path, and navigates autonomously. Includes complete wiring, code, and troubleshooting.
This guide shows you how to build an obstacle avoiding robot car step by step. So, you want to build a robot car that drives itself and dodges obstacles on its own? In this step-by-step tutorial, you will build a fully autonomous obstacle avoiding robot car using an Arduino, an L293D motor shield, an SG90 servo motor, and an HC-SR04 ultrasonic sensor. The robot continuously scans its surroundings with the ultrasonic sensor mounted on a servo, detects obstacles in its path, and automatically steers around them.
Overall, this Arduino obstacle avoiding robot car project is an excellent hands-on way to learn motor control, servo positioning, sensor integration, and basic autonomous navigation. It also brings together concepts from earlier OmArTronics tutorials on Arduino programming basics, servo motor control, ultrasonic distance sensing, and DC motor control with motor drivers. By the end, you will have a working DIY obstacle avoidance robot you built from scratch.
What You Will Learn
- How the HC-SR04 ultrasonic sensor detects obstacles by measuring distance
- How a servo motor sweeps the ultrasonic sensor to scan the environment left and right
- How the L293D motor shield drives two DC motors for forward, reverse, and turning movement
- How the Arduino code decides when to stop, reverse, and choose a new direction
- How to assemble the complete robot chassis with battery power, wiring, and 3D-printed mounts
- How to upload, test, and tune the obstacle avoidance code
How the Obstacle Avoiding Robot Car Works
Before we start building, first it helps to understand how all the parts work together. The robot uses a simple but effective sense-think-act loop to navigate around obstacles.
Ultrasonic Sensor (HC-SR04) — The Robot’s Eyes
The HC-SR04 ultrasonic sensor first sends out a short ultrasonic pulse and then listens for the echo that bounces back from objects. The Arduino measures the time between sending and receiving, then calculates the distance to the nearest obstacle. This measurement happens many times per second while the robot drives.
Servo Motor (SG90) — The Scanner
Essentially, the ultrasonic sensor is mounted on an SG90 servo motor. While driving forward, the servo sweeps the sensor left and right between 30° and 150° consequently, the robot has a wide view of the path ahead. When an obstacle is detected close by, the servo turns the sensor fully left (175°) and fully right (5°) to measure the distance on each side and determine which way has more space.
L293D Motor Shield — The Muscle
The L293D motor shield sits on top of the Arduino and controls two DC motors. It handles direction (forward or reverse) and speed (via PWM) for each motor independently. By running the left and right motors in different directions, as a result, the robot can turn in place.
Decision Logic — The Brain
The Arduino runs a continuous loop: measure distance, decide, and act. If the path ahead is clear (more than 40 cm), the robot drives forward at a steady speed while scanning. As an obstacle gets closer (between 15 cm and 40 cm), the robot gradually slows down. When the distance drops below 15 cm, the robot stops, looks left and right, and turns toward whichever side has more open space. If both sides are blocked (a dead end), the robot reverses first, then scans again and picks a new direction.
Components Needed (Bill of Materials)
Here is everything you need to build this Arduino obstacle avoiding robot car. Furthermore, most of these components are common and inexpensive.
| Component | Qty | Required / Optional | Purpose | Notes |
|---|---|---|---|---|
| Arduino Uno | 1 | Required | Main microcontroller — runs the obstacle avoidance code | Any Arduino Uno-compatible board works |
| L293D Motor Shield | 1 | Required | Drives and controls the two DC motors | Because it plugs directly on top of the Arduino Uno |
| DC Motors (3–6 V) | 2 | Required | Left and right drive wheels | Standard hobby geared DC motors |
| Servo Motor (SG90) | 1 | Required | Sweeps the ultrasonic sensor left and right to scan for obstacles | Any small 9g servo works |
| Ultrasonic Sensor (HC-SR04) | 1 | Required | Measures distance to obstacles using ultrasonic pulses | 4-pin module: VCC, Trig, Echo, GND |
| Jumper Wires | Several | Required | All electrical connections between components | Male-to-male and male-to-female |
| AA Rechargeable Batteries (1.5 V) | 8 | Required | Power supply for the motors and Arduino | 8 × 1.5 V = 12 V total. The motor shield accepts 5–12 V and powers the Arduino directly. |
| Battery Holders (4×AA) | 2 | Required | Hold and connect batteries in series | Wired in series to produce 12 V |
| Toggle Switch | 1 | Required | Main power on/off switch | Inline with the positive battery wire |
| Robot Chassis | 1 | Required | Frame to mount all components | Acrylic or 3D-printed platform |
| Wheels | 2 | Required | Attach to DC motors for movement | Match your motor shaft size |
| Support Wheel (Caster) | 1 | Required | Third point of contact for stability | Ball caster or swivel wheel |
| Screws, Nuts & Spacers | Assorted | Required | Mechanical assembly | M3 screws are common for Arduino and chassis |
| 3D-Printed Mounts | Set | Optional | Custom holders for servo motor, ultrasonic sensor, and Arduino | Can substitute with hot glue, zip ties, or brackets |
Step-by-Step Assembly Guide
Follow these steps to assemble the physical robot car before wiring and programming. Take your time with the mechanical build — a solid chassis makes everything else easier.
Step 1: Mount the Battery Holders
Secure both 4×AA battery holders to the underside or rear of the robot chassis using screws and nuts. Solder the output wires of the two holders in series (positive of one holder to negative of the other) so all 8 batteries are connected in series, thus producing a total of approximately 12 V.
Step 2: Install the Power Switch
Solder a toggle switch inline with the positive wire coming from the battery series. Also, mount the switch in an easily accessible spot on the chassis so that you can easily turn the robot on and off quickly.
Step 3: Attach the DC Motors
Solder wires to both terminals of each DC motor. Mount one motor on the left side and one on the right side of the chassis using screws, nuts, or motor brackets.
Step 4: Prepare the Arduino Mount
Similarly, if using the 3D-printed Arduino mount, heat the threaded brass inserts with a soldering iron and press them into the corresponding mounting holes. As a result, this method provides strong, reusable screw threads, so you can easily secure the Arduino.
Step 5: Mount the Arduino and Motor Shield
Secure the 3D-printed mount (or standoffs) onto the chassis. Next, place the Arduino Uno onto the mount and fasten it with screws. Then carefully plug the L293D motor shield onto the Arduino, while making sure all header pins are properly aligned.
Step 6: Install the Servo Motor
First, attach the 3D-printed servo motor mount to the front of the chassis using double-sided tape or screws. Then, insert the SG90 servo motor into the mount and secure it. The servo horn should be oriented so the ultrasonic sensor can rotate freely from left to right.
Step 7: Mount the Ultrasonic Sensor
Now, insert the HC-SR04 ultrasonic sensor into its 3D-printed bracket (or attach with hot glue). Secure the bracket onto the servo horn using a small screw so the sensor rotates with the servo.
Step 8: Attach the Support Wheel
For stability, mount the ball caster or swivel support wheel on the front or rear of the chassis (opposite the DC motors) because this gives the robot a stable three-point contact with the ground.
Step 9: Attach the Drive Wheels
Press the wheels onto the DC motor shafts on both sides. Also, make sure they are firmly attached and spin freely without rubbing on the chassis.
Wiring the Components
With the mechanical assembly complete, it is time to connect all the electrical components. The wiring diagram below shows the full circuit. Refer to the wiring table for a quick connection reference.

DC Motor Connections
| Motor | Motor Shield Terminal |
|---|---|
| Left DC Motor wire 1 | A− |
| Left DC Motor wire 2 | A+ |
| Right DC Motor wire 1 | B− |
| Right DC Motor wire 2 | B+ |
Servo Motor Connections
| Servo Wire | Connects To |
|---|---|
| Signal (orange/yellow) | Arduino digital pin 5 (on the motor shield header) |
| VCC (red) | 5 V pin on the motor shield |
| GND (brown/black) | GND pin on the motor shield |
Important: Connect the servo’s power wire to the 5 V pin on the motor shield, not the 3.3 V pin. The SG90 servo requires 5 V to operate reliably. Using 3.3 V will cause jittering and weak movement.
Ultrasonic Sensor (HC-SR04) Connections
| HC-SR04 Pin | Connects To |
|---|---|
| VCC | 5 V on the motor shield |
| Trig | Arduino digital pin 7 |
| Echo | Arduino digital pin 6 |
| GND | GND on the motor shield |
Power Supply Connections
| Battery / Switch Wire | Connects To |
|---|---|
| Positive (from switch output) | Motor shield Vin / power terminal (+) |
| Negative (battery ground) | Motor shield GND / power terminal (−) |
The L293D motor shield will regulate power for the Arduino (through the Vin pin), so you do not need a separate USB cable once the batteries are connected. Therefore, always double-check all connections before inserting batteries, because reversed polarity can damage components.
Insert the Batteries
Now, place all 8 AA rechargeable batteries into the holders. However, do not turn the switch on yet — we will upload the code first.
Arduino Code for the Obstacle Avoiding Robot Car
Next, below is the complete Arduino sketch that controls the obstacle avoiding robot car. Upload this code to your Arduino Uno using the Arduino IDE. Make sure you have the Servo library installed (it comes pre-installed with the Arduino IDE).
/**
* Author: Omar Draidrya
* Date: 2024-06-18
* This code controls a robot with ultrasonic sensors and servo motors to avoid obstacles.
*/
#include <Servo.h>
// Create a Servo object to control the servo motor
Servo myservo;
int pos = 0; // Variable to store the servo position
// Define motor pins
int directionA = 12; // Pin for direction of Motor A
int speedA = 3; // Pin for speed of Motor A
int brakeA = 9; // Pin for brake of Motor A
int directionB = 13; // Pin for direction of Motor B
int speedB = 11; // Pin for speed of Motor B
int brakeB = 8; // Pin for brake of Motor B
// Define ultrasonic sensor pins
int trigger = 7; // Trigger pin
int echo = 6; // Echo pin
long duration = 0; // Variable to store the duration of the echo
long distance = 0; // Variable to store the distance from the obstacle
int currentAngle = 90; // Start with the sensor facing forward
int scanDirection = 1; // 1 for right, -1 for left
void setup() {
// Attach the servo on pin 5 to the servo object
myservo.attach(5);
// Set the trigger pin as OUTPUT and the echo pin as INPUT
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
// Initialize Motor A pins
pinMode(directionA, OUTPUT);
pinMode(directionB, OUTPUT);
pinMode(brakeA, OUTPUT);
pinMode(brakeB, OUTPUT);
// Apply brakes (stop the motors)
digitalWrite(brakeA, HIGH);
digitalWrite(brakeB, HIGH);
// Set the servo to the center position initially
myservo.write(90);
delay(500);
}
void loop() {
// Measure the distance to the nearest obstacle
distance = measureDistance();
if (distance < 40) {
// Gradually reduce speed as the obstacle approaches
int speed = map(distance, 20, 40, 75, 128);
motorTurn(directionA, speedA, HIGH, speed);
motorTurn(directionB, speedB, HIGH, speed);
if (distance < 15) {
// Stop the motors
digitalWrite(brakeA, HIGH);
digitalWrite(brakeB, HIGH);
delay(500);
// Check surroundings
int leftDistance = checkDirection(175);
int rightDistance = checkDirection(5);
// Determine if the robot is in a dead end
if (leftDistance < 15 && rightDistance < 15) {
// Move backward
motorTurn(directionA, speedA, LOW, 128);
motorTurn(directionB, speedB, LOW, 128);
delay(500);
// Apply brakes
digitalWrite(brakeA, HIGH);
digitalWrite(brakeB, HIGH);
delay(500);
// Scan again after moving back
leftDistance = checkDirection(30);
rightDistance = checkDirection(150);
}
// Determine the best direction to turn
if (leftDistance > rightDistance) {
// Turn left
motorTurn(directionA, speedA, LOW, 128);
motorTurn(directionB, speedB, HIGH, 128);
} else {
// Turn right
motorTurn(directionA, speedA, HIGH, 128);
motorTurn(directionB, speedB, LOW, 128);
}
delay(500);
// Apply brakes
digitalWrite(brakeA, HIGH);
digitalWrite(brakeB, HIGH);
delay(500);
// Set the servo back to the center position
myservo.write(90);
delay(500);
}
} else {
// Move forward at a reduced speed
motorTurn(directionA, speedA, HIGH, 100);
motorTurn(directionB, speedB, HIGH, 100);
// Continuously scan left and right
currentAngle += scanDirection * 10;
if (currentAngle >= 150 || currentAngle <= 30) {
scanDirection = -scanDirection;
}
myservo.write(currentAngle);
delay(40); // Adjusted delay for more realistic servo movement
}
}
// Function to set the direction and speed of motors
void motorTurn(int directionPin, int speedPin, int direction, int speed) {
digitalWrite(directionPin, direction);
analogWrite(speedPin, speed);
if (directionPin == directionA) {
digitalWrite(brakeA, LOW);
} else {
digitalWrite(brakeB, LOW);
}
}
// Function to measure the distance using the ultrasonic sensor
int measureDistance() {
digitalWrite(trigger, LOW);
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);
duration = pulseIn(echo, HIGH);
distance = (duration / 2) / 29.1;
return distance;
}
// Function to check the distance in a specific direction
int checkDirection(int angle) {
myservo.write(angle);
delay(500); // Give the servo time to move
int measuredDistance = measureDistance();
return measuredDistance;
}
Code Explanation
Let us walk through each section of the code so you understand what every part does and can modify it confidently.
Pin Assignments
First, at the top of the sketch we define which Arduino pins connect to each component. For instance, Motor A (left) uses pins 12 (direction), 3 (speed/PWM), and 9 (brake). Motor B (right) uses pins 13, 11, and 8. The ultrasonic sensor trigger is on pin 7, echo on pin 6, and the servo signal is on pin 5. These pin numbers are dictated by the L293D motor shield — they are not arbitrary.
Distance Measurement
The measureDistance() function first sends a 10-microsecond pulse on the trigger pin and then waits for the echo. Afterwards, it calculates the distance in centimeters using the formula: distance = (duration / 2) / 29.1. The division by 2 accounts for the round trip of the sound wave, and 29.1 is the approximate number of microseconds per centimeter for sound in air.
Motor Control
The motorTurn() helper function essentially sets the direction and speed of a single motor. It writes the direction pin HIGH (forward) or LOW (reverse), sets the speed via analogWrite() (0–255), and releases the brake. Besides, the motor shield uses separate brake pins — so setting the brake HIGH stops the motor immediately.
Obstacle Detection and Speed Reduction
Inside the main loop(), the robot measures the distance ahead on every cycle, because this is essential for real-time navigation. For example, if the distance is between 15 cm and 40 cm, the robot does not stop — instead it gradually reduces speed using the map() function. The closer the obstacle, the slower the robot moves. This creates smooth, natural deceleration rather than an abrupt stop.
Left / Right Scan Logic
When the distance drops below 15 cm, the robot consequently stops both motors and then calls checkDirection(175) (look left) and checkDirection(5) (look right). The checkDirection() function rotates the servo to the given angle, waits for it to reach position, takes a distance reading, and returns it. The robot then compares the two distances and turns toward the side with more open space.
Dead-End Reverse Behavior
If both the left and right distances are below 15 cm, the robot is in a dead end. Therefore, it reverses for 500 ms, stops, and then scans again at slightly different angles (30° and 150°) to re-evaluate. This gives the robot a chance to back out of tight corners and find a new escape route.
Servo Sweep During Normal Driving
When the path ahead is clear (distance > 40 cm), the robot drives forward at a steady speed while the servo continuously sweeps the ultrasonic sensor between 30° and 150° in 10° increments. This wide sweep lets the robot detect obstacles approaching from the sides, not just directly ahead. Similarly, the scan direction reverses each time it reaches a boundary angle.
Upload, Test, and Observe
- Connect the Arduino to your computer via USB, and then open the Arduino IDE.
- Then, upload the sketch above to the Arduino Uno.
- Afterwards, disconnect USB, insert batteries, and then flip the power switch on.
- Observe the behavior: Specifically, the robot should drive forward, slow down as it approaches an obstacle, stop, scan left and right, and turn toward the clearer path.
- If the robot turns the wrong way, swap the two wires on one motor terminal (A+ and A−, or B+ and B−) to reverse that motor’s direction.
How to Tune the Robot
Every robot chassis, motor, and surface is different. Below are the key values in the code you can adjust in order to fine-tune the behavior of your obstacle avoiding robot car.
| Parameter | Default Value | What It Controls | Tuning Tip |
|---|---|---|---|
| Obstacle threshold (far) | 40 cm | Distance at which the robot starts slowing down | Increase for faster reaction; decrease if the robot stops too early |
| Obstacle threshold (close) | 15 cm | Distance at which the robot stops and scans | Increase if the robot crashes before stopping; decrease for tighter navigation |
| Forward speed | 100 (PWM) | Cruising speed when path is clear | Range 0–255. Higher = faster but harder to stop in time |
| Turn speed | 128 (PWM) | Speed during left/right turns | Increase if the robot does not complete the turn; decrease on slippery surfaces |
| Turn duration | 500 ms | How long the robot turns before stopping | Increase for wider turns; decrease for small adjustments |
| Reverse duration | 500 ms | How long the robot reverses in a dead end | Increase if the robot does not back up far enough |
| Servo scan range | 30°–150° | Sweep range during forward driving | Wider range = better side detection but slower scans |
| Servo scan step | 10° | Angle increment per loop cycle | Smaller = smoother scan but slower coverage |
| Servo scan delay | 40 ms | Pause between servo steps during sweep | Decrease for faster scanning; increase if servo jitters |
Understanding the L293D Arduino Motor Shield
Basically, the L293D motor shield is a plug-and-play board that stacks directly on top of the Arduino Uno. It simplifies motor control by providing screw terminals for motors and using dedicated control pins for direction, speed, and braking. Therefore, here is a quick overview of its key features and connections.

Key Features
- First, it controls up to two DC motors (or one stepper motor) independently
- Moreover, it handles up to 2 A continuous per motor channel
- Additionally, it supports PWM for smooth speed control
- Finally, it provides dedicated brake pins for instant stops

Motor Shield Pin Reference
| Function | Motor A Pin | Motor B Pin |
|---|---|---|
| Direction | 12 | 13 |
| Speed (PWM) | 3 | 11 |
| Brake | 9 | 8 |
For a deeper dive into motor drivers and how H-bridges work, see the full tutorial: Controlling DC Motors with L298N Dual H-Bridge and Arduino Motor Shield.
Troubleshooting Common Issues
If your obstacle avoiding robot car is not behaving as expected, work through these common issues before assuming a hardware defect.
Common Problems and Solutions
| Problem | Likely Cause | Solution |
|---|---|---|
| Robot does not move at all | No power, loose wiring, or brakes not released | First, check the power switch, battery voltage (should be ~12 V), and verify motor terminal connections. Make sure the code uploads without errors. |
| Only one motor runs | One motor not connected, or a broken wire | Instead, swap the working motor’s wires to the other terminal to test. Check solder joints on the motor. |
| Robot moves only in one direction | Motor wires swapped or direction pins wired incorrectly | Simply swap the two wires on the motor terminal that is running the wrong way (A+ and A−, or B+ and B−). |
| Ultrasonic sensor gives unstable or zero readings | Loose wiring, wrong pins, or object too close / too far | First, double-check Trig (pin 7) and Echo (pin 6) connections. The HC-SR04 range is approximately 2 cm to 400 cm. Add a small delay if readings fluctuate. |
Sensor, Direction, and Power Issues
| Problem | Likely Cause | Solution |
|---|---|---|
| Servo jitters or twitches | Insufficient power, servo connected to 3.3 V, or noisy power rail | First, make sure the servo VCC is connected to 5 V (not 3.3 V). Then, add a 100 µF capacitor across the servo power lines to smooth the supply. |
| Robot turns the wrong way | Left and right motors are swapped | Instead, swap the motor connections on the shield (move Motor A wires to Motor B terminals and vice versa), or swap the direction pin assignments in the code. |
| Robot reacts too late and crashes into obstacles | Distance threshold too low, or code delays too long | Therefore, increase the far threshold (e.g., from 40 cm to 50 cm) and reduce unnecessary delays in the loop. |
| Batteries drain very quickly | Motors drawing high current, or batteries not fully charged | First, use freshly charged NiMH batteries. Also, reduce motor speed if possible. Ensure no mechanical binding on wheels. |
| Arduino resets when motors start | Voltage drop from motor current draw | Instead, use a separate battery pack or add a large capacitor (470–1000 µF) across the motor shield power terminals. |
| Robot spins in circles | Both motors running in opposite directions, or one motor not turning | First, check direction pin assignments and then test each motor individually with a simple sketch before running the full code. |
Frequently Asked Questions (FAQ)
Essentially, an obstacle avoiding robot car is a small autonomous vehicle that uses sensors (typically an ultrasonic sensor like the HC-SR04) to detect objects in its path and automatically changes direction to avoid collisions — all without human control.
In short, the L293D motor shield is designed to plug directly into the Arduino Uno header. Although it will also fit an Arduino Mega, but not an Arduino Nano without an adapter. However, if you want to use a Nano, consider using a standalone L293D IC or an L298N module instead. See our L298N motor driver tutorial for an alternative approach.
Yes. The L298N is a common alternative that supports higher current. However, the wiring and pin assignments will differ since the L298N is a separate module rather than a shield. Consequently, you will need to adjust the code accordingly. Our DC motor control tutorial covers both options.
Basically, the sensor sends a short burst of ultrasonic sound (40 kHz) and measures how long it takes for the echo to return after bouncing off an object. Then, the Arduino converts this time into a distance in centimeters. For more details, see our ultrasonic sensor tutorial.
Without a servo, a fixed forward-facing sensor can only detect obstacles directly ahead. In contrast, by mounting the sensor on a servo that sweeps from 30° to 150°, consequently the robot gains a much wider field of view and can spot obstacles approaching from the sides before they are directly in front.
For this project, we use 8 AA rechargeable batteries wired in series for approximately 12 V. Furthermore, the L293D motor shield accepts 5 V to 12 V on its power input and regulates power for the Arduino. Alternatively, you can also use a 2S or 3S LiPo battery (7.4 V – 11.1 V) as long as the voltage stays within the shield’s rated range.
No. Although the 3D-printed mounts make the build cleaner and more robust, however, you can substitute them with hot glue, zip ties, double-sided tape, or small L-brackets from a hardware store.
Motor speed is controlled by the PWM value passed to analogWrite(). In the code, the forward cruising speed is set to 100 and the turning speed to 128 (out of a maximum of 255). Therefore, increase these values to go faster, or decrease them for slower, more controlled movement.
To solve this, first increase the far distance threshold from 40 cm to 50 cm or 60 cm. This makes the robot start slowing down earlier. Likewise, check that the ultrasonic sensor is getting accurate readings by opening the Serial Monitor and printing the distance values for debugging.
Absolutely. You can add IR sensors on the sides for edge detection, a second ultrasonic sensor for rear detection, or even a line-following sensor on the bottom. However, keep in mind that each additional sensor requires a free digital or analog pin on the Arduino and a small addition to the code.
Recommended Next Projects and Resources
Now that you have a working obstacle avoiding robot car, here are some ideas for your next build, along with related OmArTronics tutorials to further deepen your skills.
- Arduino Programming Basics — strengthen your foundation if you are new to Arduino
- How to Control a Servo Motor Using Arduino — go deeper into servo positioning and sweep patterns
- Exploring Ultrasonic Sensors Using Arduino — learn advanced distance measurement techniques
- Controlling DC Motors with L298N and Arduino Motor Shield — understand H-bridges and motor drivers in depth
- Add Bluetooth or Wi-Fi control — combine obstacle avoidance with remote control using an HC-05 module or ESP8266
- Add a line-following mode — use IR sensors to follow a black line on the floor and switch between line-following and obstacle avoidance
- Upgrade to a 4WD chassis — add two more motors for better traction and stability on rough surfaces
Conclusion
In conclusion, you have successfully built an obstacle avoiding robot car with Arduino, an L293D motor shield, a servo motor, and an HC-SR04 ultrasonic sensor. Along the way, you also learned how to wire DC motors, connect and read an ultrasonic distance sensor, control a servo for scanning, and write autonomous navigation logic. In summary, this project brings together the core skills of robotics: sensing the environment, making decisions, and controlling actuators.
From here, for example, you can expand the robot with additional sensors, add wireless control, or refine the obstacle avoidance algorithm for more complex environments. Ultimately, every improvement you make is a step closer to more advanced robotics projects. Happy building!
من أفضل ماشاهدت في هذا المجال بمافيه من توضيحات. سهل وميسر. تحياتي لكم أستاذي العزيز. أخوكم من سلطنة عمان
شكراً جزيلاً أخي سعيد على كلماتك الطيبة. سعيد جداً أن الشرح كان واضح ومفيد لك، هذا هو هدفي. تحياتي لك من ألمانيا إلى سلطنة عمان