In the previous two parts, we built the "infrastructure" for our robot:
- It can see — recognizing people, cars, furniture, and more
- It can feel — knowing when it's tilting, spinning, or moving through space
But if we're talking about a self-driving car, what comes next?
We're splitting this into two parts:
- Part 3A: Program two DC motors to move forward, backward, left, and right. That's it.
- Part 3B: Upgrade by mounting everything onto a real RC car, controlled wirelessly via Wi-Fi or Bluetooth from a laptop keyboard.
Now, we know what you're thinking: "This doesn't sound like a robot at all. Even Part 3B just sounds like... a remote-controlled car."
Fair point. Let's address that.
Is a Remote-Controlled Toy Car a Robot?
Absolutely not.
At first glance, controlling a car with a laptop keyboard looks no different from using a remote to drive an RC car around. But here's the thing — remember the "infrastructure" we built?
Our robot already has eyes and awareness. Sitting inside the house, while the robot roams outside, we can know when it needs to stop for an obstacle, when it should turn left, when it should turn right to reach a destination. A regular RC car? Completely helpless in that situation.
And it gets better. With those senses already in place, we can upgrade our Python program so the robot automatically stops when it detects something in its path — or automatically turns left when it sees "ABC Street" and right when it sees "DEF Road."
A toy RC car can't dream of doing any of that.
Adding a Brain: How the Command Chain Works
Before we build, let's picture how the "brain" of our robot works.
The brain is the laptop — more precisely, the Python program running on it. It listens to the keyboard, decides where to go, and sends commands to the motors.
👉 Python gives the order → Motors execute
Simple enough. But in reality, motors need to spin both directions, speed up, slow down, and stop instantly. We need something in the middle to manage all of that — a driver module.
👉 Python gives the order → Driver module → Motors execute
Still straightforward. But here's where real life gets complicated.
Just like in the office — not everyone "gets along" with everyone else. Different electronics have different standards; some components work perfectly together; others simply refuse to cooperate. Think of it like a corporate chain of command: the CEO (Python code) doesn't talk directly to every employee (motors). Orders go through Managers, then Team Leaders (the driver module), and finally reach the workers (motors).
So, we need a manager. That Manager is a microcontroller — a tiny single-chip computer whose job is to receive commands and translate them into physical actions: spin motor, stop motor, go left, go right.
Here's our official command chain:
👉 Python gives the order → Microcontroller → Driver module → Motors execute
Sounds complicated? Don't worry. Everything here is small, cheap, and beginner friendly. True to our "use what you have" philosophy, we only need to buy a few inexpensive parts. The final result won't be pretty — it'll look like a tangled mess of wires. But looks are deceiving. This "mess" behaves exactly like a real robot: upgrade the code, add sensors, and those motors will respond intelligently — fast, slow, forward, reverse, stop — reacting to real-world input.
What You Need (Components List)
| # | Component | Estimated Cost |
|---|---|---|
| 1 | Laptop | You already have one |
| 2 | USB to Mini-B cable | ~$5 on Amazon |
| 3 | Arduino Nano | ~$12 for 2 on Amazon |
| 4 | L298N H-Bridge Motor Driver Module | ~$7 for 2 on Amazon |
| 5 | DC Motors | ~$6 for 2 on Amazon |
| 6 | Small Breadboard | ~$4 on Amazon |
| 7 | Jumper Wires | Get all 3 types: M-F, M-M, F-F |
| 8 | 4×AA Battery Holder | ~$5 on Amazon |
You can also find starter kits on Amazon that bundle several of these together — that'll bring the total cost down nicely.
Everything here is reusable for future projects. If you've made it through Parts 1 and 2 and you're still excited — skipping a few Starbucks runs to fund this is probably worth it.
Meet the Arduino Nano
The Arduino Nano is our microcontroller — the Manager in our command chain. Because it's essentially a tiny computer, it needs to be treated like one. Just like your laptop asks for a driver when you plug in something new, the Arduino Nano needs a "driver" too — in this case, that means uploading code to it before we can use it.
Step 1: Prepare the Software and Driver
Download Arduino IDE (free) from the official Arduino website.
Install the CH340 Driver (important, but sometimes your computer handles this automatically): Most Arduino Nanos sold today use the CH340 chip for USB communication. If your computer doesn't recognize the board after plugging it in, search for "CH340 driver" and install it from the manufacturer's site.
Step 2: Connect and Configure the Board
Connect the Arduino Nano to your laptop using the USB to Mini-B cable — USB end into the laptop, Mini-B end into the Arduino Nano.
Open Arduino IDE, then:
- Select Board: Tools → Board → Arduino AVR Boards → Arduino Nano
- Select Processor: Tools → Processor → If it's an older board, choose ATmega328P (Old Bootloader); newer boards use ATmega328P
- Select Port: Tools → Port → Choose the correct COM port (e.g. COM3, COM4). Not sure which one? Unplug the cable, plug it back in, and see which port just appeared.
Step 3: Upload the Code
Paste the code below into the Arduino IDE editor. Click Verify (✔) to check for errors, then click Upload (➔) to flash it to the board. Wait for "Done uploading" at the bottom.
// Commands from Python via Serial to Control the L298N
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5
void setup() {
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop() {
if (Serial.available()) {
char cmd = Serial.read();
// Reset tất cả
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
if (cmd == 'F') { // Forward
digitalWrite(IN1, HIGH);
digitalWrite(IN3, HIGH);
} else if (cmd == 'B') { // Backward
digitalWrite(IN2, HIGH);
digitalWrite(IN4, HIGH);
} else if (cmd == 'L') { // Left
digitalWrite(IN1, HIGH);
digitalWrite(IN4, HIGH);
} else if (cmd == 'R') { // Right
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
}
// cmd == 'S' → Stop, all pins LOW
}
}Once uploaded, the Arduino Nano is set. You won't need to touch it again.
The Python Code (Our CEO)
If you've been with us since Parts 1 and 2, this part is almost too easy. Create a new file in PyCharm called motor.py and paste this in. Remember to change 'COM3' to match your actual Arduino port.
import serial
import keyboard
# Replace 'COM3' with your Arduino's actual port
# Windows: COM3, COM4... / Mac/Linux: /dev/ttyUSB0
ser = serial.Serial('COM3', 9600)
print("Arrow keys to control. Press ESC to quit.")
while True:
if keyboard.is_pressed('up'):
ser.write(b'F')
elif keyboard.is_pressed('down'):
ser.write(b'B')
elif keyboard.is_pressed('left'):
ser.write(b'L')
elif keyboard.is_pressed('right'):
ser.write(b'R')
else:
ser.write(b'S')
if keyboard.is_pressed('esc'):
break
ser.close()Wiring Everything Together
1. Mount the Arduino Nano on the Breadboard
Make sure the two rows of pins sit on opposite sides of the center gap.
2. Connect D2–D5 to the L298N
Take 4 Male-to-Female jumper wires. Plug the Male ends into pins D2, D3, D4, D5 on the Arduino Nano.
Plug the Female ends into IN1, IN2, IN3, IN4 on the L298N, following this mapping:
- Arduino D2 → L298N IN1 (Motor 1 forward)
Arduino D3 → L298N IN2 (Motor 1 backward)Arduino D4 → L298N IN3 (Motor 2 left)Arduino D5 → L298N IN4 (Motor 2 right)
3. Connect GND
Take 1 Male-to-Male jumper wire. One end into the GND pin on the Arduino Nano, other end into the GND on the L298N.
4. Connect the Motors
Motor 1 wires → OUT1 and OUT2 on the L298N. Motor 2 wires → OUT3 and OUT4 on the L298N.
5. Connect the Battery Pack
Red wire (+) from the battery holder → 12V terminal on the L298N. Black wire (−) → GND on the Arduino Nano.
6. Connect the USB Cable
Plug the USB end into your laptop, Mini-B end into the Arduino Nano. Both the Arduino Nano and the L298N should light up.
Full Wiring Diagram
Run It
Open PyCharm and run motor.py. Press the arrow keys — and watch your motors move.
Congratulations. You just took another solid step toward building your own Bumblebee. Or Optimus Prime. We don't judge.
Troubleshooting: Things That Will Go Wrong (And How to Fix Them)
Real talk — here's every problem we ran into during this build, so you don't have to suffer through them alone:
| Problem | Cause | Fix |
|---|---|---|
| No response when pressing arrow keys | Wrong COM port in Python code | Check Arduino IDE → Tools → Port and update motor.py |
"Access is denied" error | Arduino IDE is holding the COM port | Close Arduino IDE completely before running Python |
keyboard library not working | Needs admin privileges | Right-click PyCharm → Run as Administrator |
"No module named serial" | Wrong Python environment | Use PyCharm's built-in Terminal → pip install pyserial |
| Motors don't move, no errors | ENA/ENB jumpers missing | Plug jumper caps onto ENA and ENB pins on the L298N |
| Motors still don't move | Battery connected to 5V instead of 12V | Move the red wire to the 12V terminal on the L298N |











