Infinite Loop Robot Car (4-Wheel Chassis)
HARDWARE REQUIRED:
- PICUNO Microcontroller board
- 1 × 4-Wheel Chassis (with wheels, 4 DC motors, etc.) full set
- 1 × 298N Motor Driver
- 1 × 4xAA Battery pack (with fresh or rechargeable batteries)
- 1 × 9V Battery (optional for external power supply to PICUNO)
- Jumper wires
- USB cable
DESCRIPTION:
This project serves as the fundamental test for a 4-wheel robot chassis. The program commands the robot to perform a simple, repeating sequence of movements: it drives all four wheels forward for two seconds, stops for one second, drives in reverse for two seconds, and stops again. This sequence loops infinitely, providing a clear and continuous test of the robot's drive system, wiring, and power supply.
ASSEMBLY OF 2-WHEEL CHASIS KIT:
1.) Prepare the Chassis: If your chassis parts are acrylic, they often come with a protective paper or plastic film. Peel this film off all the pieces.
2.) Mount the Motors: Attach the four yellow DC motors to the lower chassis plate. Use the brackets and long screws/nuts that came with the kit to secure them firmly in place.
3.) Attach the Wheels: Push the four main wheels onto the plastic shafts of the motors. They should be a snug fit.
4.) Attach the Upper Chassis: Use the Screws/nuts to attach the upper chassis firmly. This will work as a holder for other components to be placed.
5.) Mount the Battery Holder: Use screws to attach the 4xAA battery pack at the top of the upper chassis.
6.) Mount the Electronics: Finally, mount the PICUNO and the L298N motor driver board onto the upper chassis, usually using screws/double tape. Position them such that to easily run wires to the motors.
ASSEMBLY OF 2-WHEEL CHASIS KIT:
1.) Prepare the Chassis: If your chassis parts are acrylic, they often come with a protective paper or plastic film. Peel this film off all the pieces.
2.) Mount the Motors: Attach the four yellow DC motors to the lower chassis plate. Use the brackets and long screws/nuts that came with the kit to secure them firmly in place.
3.) Attach the Wheels: Push the four main wheels onto the plastic shafts of the motors. They should be a snug fit.
4.) Attach the Upper Chassis: Use the Screws/nuts to attach the upper chassis firmly. This will work as a holder for other components to be placed.
5.) Mount the Battery Holder: Use screws to attach the 4xAA battery pack at the top of the upper chassis.
6.) Mount the Electronics: Finally, mount the PICUNO and the L298N motor driver board onto the upper chassis, usually using screws/double tape. Position them such that to easily run wires to the motors.
CIRCUIT DIAGRAM:
- OUT1 & OUT2: Connect these two screw terminals to the outputs for the first motor and second motor (e.g., two wheels from left side). Connect the two wires (black) from both DC motors to OUT1 and other two wires (red) to OUT2.
- OUT3 & OUT4: Connect these two screw terminals to the outputs for the third and fourth motor (e.g., two wheels from right side). Connect the two wires (red) from both DC motors to OUT3 and other two wires (black) to OUT4.
- Connect the positive terminal (+) of the 4xAA battery pack to the 12V screw terminal.
- Connect the negative terminal (-) of the 4xAA battery pack to the GND screw terminal.
- Also connect the GND terminal on the L298N to a GND pin on the microcontroller to create a common ground.
- Connect the IN1 pin (Left side wheels) to GPIO 8.
- Connect the IN2 pin (Left side wheels) to GPIO 9.
- Connect the ENA pin (Left motors speed) to GPIO 10.
- Connect the IN1 pin (Right side wheels) to GPIO 11.
- Connect the IN2 pin (Right side wheels) to GPIO 12.
- Connect the ENB pin (Right motors speed) to GPIO 13.
NOTE: Remove the ENA and ENB jumpers on the L298N motor driver.
OPTIONAL: You can power the PICUNO using an external power supply (9V Battery) through DC Jack, once you have uploaded the code to the microcontroller.
SCHEMATIC:
L298N Motor Driver:
OUT1 & OUT2 → Outputs for the Left side Motors.
OUT3 & OUT4 → Outputs for the Right side Motors.
12V → positive terminal (+) of 4xAA battery pack.
GND → negative terminal (-) of 4xAA battery pack → GND on PICUNO.
IN1 (Left side Motors) → GPIO 8
IN2 (Left side Motors) → GPIO 9
ENA (Left Motors speed) → GPIO 10
IN3 (Right side Motors) → GPIO 11
IN4 (Right side Motors) → GPIO 12
ENB (Right Motors speed) → GPIO 13
CODE -- C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 const int L_IN1_PIN = 8, L_IN2_PIN = 9, L_ENA_PIN = 10; const int R_IN3_PIN = 11, R_IN4_PIN = 12, R_ENB_PIN = 13; void setup() { pinMode(L_IN1_PIN, OUTPUT); pinMode(L_IN2_PIN, OUTPUT); pinMode(L_ENA_PIN, OUTPUT); pinMode(R_IN3_PIN, OUTPUT); pinMode(R_IN4_PIN, OUTPUT); pinMode(R_ENB_PIN, OUTPUT); Serial.begin(9600); Serial.println("Starting 4-wheel drive test..."); } // --- Helper Function --- void setMotorSpeed(char motor, int speed) { int duty = map(abs(speed), 0, 100, 0, 255); if (motor == 'L') { if (speed > 0) { digitalWrite(L_IN1_PIN, HIGH); digitalWrite(L_IN2_PIN, LOW); } else if (speed < 0) { digitalWrite(L_IN1_PIN, LOW); digitalWrite(L_IN2_PIN, HIGH); } else { digitalWrite(L_IN1_PIN, LOW); digitalWrite(L_IN2_PIN, LOW); } analogWrite(L_ENA_PIN, duty); } else if (motor == 'R') { if (speed > 0) { digitalWrite(R_IN3_PIN, HIGH); digitalWrite(R_IN4_PIN, LOW); } else if (speed < 0) { digitalWrite(R_IN3_PIN, LOW); digitalWrite(R_IN4_PIN, HIGH); } else { digitalWrite(R_IN3_PIN, LOW); digitalWrite(R_IN4_PIN, LOW); } analogWrite(R_ENB_PIN, duty); } } void loop() { // Go forward at 80% speed for 2 seconds Serial.println("Moving forward..."); setMotorSpeed('L', 80); setMotorSpeed('R', 80); delay(2000); // Stop for 1 second Serial.println("Stopping."); setMotorSpeed('L', 0); setMotorSpeed('R', 0); delay(1000); // Go backward at 80% speed for 2 seconds Serial.println("Moving backward..."); setMotorSpeed('L', -80); setMotorSpeed('R', -80); delay(2000); // Stop for 1 second before repeating Serial.println("Stopping."); setMotorSpeed('L', 0); setMotorSpeed('R', 0); delay(1000); }
pinMode() - explicitly setting each pin as an OUTPUT.
setMotorSpeed() function - uses digitalWrite() for direction and analogWrite() for speed.
analogWrite() - command for sending a PWM signal to control motor speed. It uses a value from 0 (off) to 255 (100% speed). The map() function converts the 0-100 speed percentage to this 0-255 range.
loop() - The loop() function in Arduino is naturally infinite, so placing the movement sequence inside it will cause it to repeat forever.
setMotorSpeed() function - uses digitalWrite() for direction and analogWrite() for speed.
analogWrite() - command for sending a PWM signal to control motor speed. It uses a value from 0 (off) to 255 (100% speed). The map() function converts the 0-100 speed percentage to this 0-255 range.
loop() - The loop() function in Arduino is naturally infinite, so placing the movement sequence inside it will cause it to repeat forever.
CODE -- PYTHON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 from machine import Pin, PWM from time import sleep # Left Motors (Motor A) L_IN1_PIN = 8 L_IN2_PIN = 9 L_ENA_PIN = 10 # Right Motors (Motor B) R_IN3_PIN = 11 R_IN4_PIN = 12 R_ENB_PIN = 13 # Left Motors L_IN1 = Pin(L_IN1_PIN, Pin.OUT) L_IN2 = Pin(L_IN2_PIN, Pin.OUT) L_ENA = PWM(Pin(L_ENA_PIN)) L_ENA.freq(1000) # Right Motors R_IN3 = Pin(R_IN3_PIN, Pin.OUT) R_IN4 = Pin(R_IN4_PIN, Pin.OUT) R_ENB = PWM(Pin(R_ENB_PIN)) R_ENB.freq(1000) # --- Helper Function --- def set_motor_speed(motor, speed): """Sets motor speed. speed is from -100 to 100.""" duty = int(abs(speed) / 100 * 65535) if motor == 'left': if speed > 0: # Forward L_IN1.high() L_IN2.low() elif speed < 0: # Backward L_IN1.low() L_IN2.high() else: L_IN1.low() L_IN2.low() L_ENA.duty_u16(duty) elif motor == 'right': if speed > 0: # Forward R_IN3.high() R_IN4.low() elif speed < 0: # Backward R_IN3.low() R_IN4.high() else: # Stop R_IN3.low() R_IN4.low() R_ENB.duty_u16(duty) print("Starting 4-wheel drive test...") while True: # Go forward at 80% speed for 2 seconds print("Moving forward...") set_motor_speed('left', 80) set_motor_speed('right', 80) sleep(2) # Stop for 1 second print("Stopping.") set_motor_speed('left', 0) set_motor_speed('right', 0) sleep(1) # Go backward at 80% speed for 2 seconds print("Moving backward...") set_motor_speed('left', -80) set_motor_speed('right', -80) sleep(2) # Stop for 1 second print("Stopping.") set_motor_speed('left', 0) set_motor_speed('right', 0) sleep(1)
PWM(Pin(L_ENA_PIN)) - Creates a Pulse Width Modulation object for a speed control pin. PWM is how we control the speed of the DC motors.
set_motor_speed() function - This is the core logic. It takes a motor ('left' or 'right') and a speed (-100 to 100). It sets the direction pins (IN1/IN2) correctly for forward or reverse and then sets the speed using PWM.
duty_u16() - This function sets the PWM duty cycle, which controls the motor's speed. A value of 65535 is 100% speed.
while True: - This creates an infinite loop that causes the forward-stop-backward-stop sequence to repeat forever.
set_motor_speed() function - This is the core logic. It takes a motor ('left' or 'right') and a speed (-100 to 100). It sets the direction pins (IN1/IN2) correctly for forward or reverse and then sets the speed using PWM.
duty_u16() - This function sets the PWM duty cycle, which controls the motor's speed. A value of 65535 is 100% speed.
while True: - This creates an infinite loop that causes the forward-stop-backward-stop sequence to repeat forever.