Programming your assembled miniAuto for basic movements and behaviors
🤖 From assembly to programming - bringing your robot to life
The miniAuto uses Mecanum wheels that allow omnidirectional movement. Each wheel has rollers at 45° angles that enable the robot to move forward, backward, sideways, and rotate without changing orientation.
First, let's set up the basic motor control functions for the miniAuto:
// miniAuto Basic Movement Setup
// Motor pin definitions
const int FL_PWM = 5; // Front Left PWM
const int FL_DIR = 4; // Front Left Direction
const int FR_PWM = 6; // Front Right PWM
const int FR_DIR = 7; // Front Right Direction
const int RL_PWM = 9; // Rear Left PWM
const int RL_DIR = 8; // Rear Left Direction
const int RR_PWM = 10; // Rear Right PWM
const int RR_DIR = 11; // Rear Right Direction
void setup() {
// Set all motor pins as outputs
pinMode(FL_PWM, OUTPUT);
pinMode(FL_DIR, OUTPUT);
pinMode(FR_PWM, OUTPUT);
pinMode(FR_DIR, OUTPUT);
pinMode(RL_PWM, OUTPUT);
pinMode(RL_DIR, OUTPUT);
pinMode(RR_PWM, OUTPUT);
pinMode(RR_DIR, OUTPUT);
Serial.begin(9600);
Serial.println("miniAuto Movement System Ready");
// Stop all motors initially
stopMotors();
}
void stopMotors() {
analogWrite(FL_PWM, 0);
analogWrite(FR_PWM, 0);
analogWrite(RL_PWM, 0);
analogWrite(RR_PWM, 0);
} Create functions for forward, backward, left, right, and rotational movement:
// Movement Functions for miniAuto
void moveForward(int speed) {
// All wheels forward
digitalWrite(FL_DIR, HIGH);
digitalWrite(FR_DIR, HIGH);
digitalWrite(RL_DIR, HIGH);
digitalWrite(RR_DIR, HIGH);
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
}
void moveBackward(int speed) {
// All wheels backward
digitalWrite(FL_DIR, LOW);
digitalWrite(FR_DIR, LOW);
digitalWrite(RL_DIR, LOW);
digitalWrite(RR_DIR, LOW);
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
}
void moveLeft(int speed) {
// Mecanum wheel pattern for left movement
digitalWrite(FL_DIR, LOW); // Front left backward
digitalWrite(FR_DIR, HIGH); // Front right forward
digitalWrite(RL_DIR, HIGH); // Rear left forward
digitalWrite(RR_DIR, LOW); // Rear right backward
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
}
void moveRight(int speed) {
// Mecanum wheel pattern for right movement
digitalWrite(FL_DIR, HIGH); // Front left forward
digitalWrite(FR_DIR, LOW); // Front right backward
digitalWrite(RL_DIR, LOW); // Rear left backward
digitalWrite(RR_DIR, HIGH); // Rear right forward
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
}
void rotateClockwise(int speed) {
// Right side backward, left side forward
digitalWrite(FL_DIR, HIGH);
digitalWrite(FR_DIR, LOW);
digitalWrite(RL_DIR, HIGH);
digitalWrite(RR_DIR, LOW);
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
}
void rotateCounterClockwise(int speed) {
// Left side backward, right side forward
digitalWrite(FL_DIR, LOW);
digitalWrite(FR_DIR, HIGH);
digitalWrite(RL_DIR, LOW);
digitalWrite(RR_DIR, HIGH);
analogWrite(FL_PWM, speed);
analogWrite(FR_PWM, speed);
analogWrite(RL_PWM, speed);
analogWrite(RR_PWM, speed);
} The following programs are based on the official Hiwonder miniAuto documentation and provide comprehensive motor testing capabilities using the manufacturer's advanced control functions.
Tests basic forward movement and in-place rotation using the Hiwonder velocity controller system. The robot moves forward for 1 second, turns left for 1 second, then turns right for 1 second.
// 5.2 Forward Movement & Turning Test
#include <Arduino.h>
const static uint8_t pwm_min = 50;
const static uint8_t motorpwmPin[4] = {10, 9, 6, 11}; // Motor PWM pins
const static uint8_t motordirectionPin[4] = {12, 8, 7, 13}; // Motor direction pins
void Motor_Init(void);
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift);
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3);
void setup() {
Serial.begin(9600);
Serial.setTimeout(500);
Motor_Init();
Velocity_Controller(0, 100, 0, 0); // Move forward
delay(1000);
Velocity_Controller(0, 0, 100, 0); // Turn left in place
delay(1000);
Velocity_Controller(0, 0, -100, 0); // Turn right in place
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
}
void loop() {
// Empty - single test sequence
}
void Motor_Init(void) {
for(uint8_t i = 0; i < 4; i++) {
pinMode(motordirectionPin[i], OUTPUT);
}
Velocity_Controller(0, 0, 0, 0);
}
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift) {
int8_t velocity_0, velocity_1, velocity_2, velocity_3;
float speed = 1;
angle += 90;
float rad = angle * PI / 180;
if (rot == 0) speed = 1;
else speed = 0.5;
velocity /= sqrt(2);
if (drift) {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed * 2;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed * 2;
} else {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed + rot * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed - rot * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed;
}
Motors_Set(velocity_0, velocity_1, velocity_2, velocity_3);
}
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3) {
int8_t pwm_set[4];
int8_t motors[4] = {Motor_0, Motor_1, Motor_2, Motor_3};
bool direction[4] = {1, 0, 0, 1}; // Forward direction defaults
for(uint8_t i = 0; i < 4; ++i) {
if(motors[i] < 0) direction[i] = !direction[i];
if(motors[i] == 0) pwm_set[i] = 0;
else pwm_set[i] = map(abs(motors[i]), 0, 100, pwm_min, 255);
digitalWrite(motordirectionPin[i], direction[i]);
analogWrite(motorpwmPin[i], pwm_set[i]);
}
} When you upload and run this code, your miniAuto should perform the following sequence:
💡 Troubleshooting: If the robot moves in unexpected directions, check your wiring connections and ensure the Bluetooth module is removed during upload.
🎬 Watch Official Demo: View Hiwonder GIF demonstration of this movement sequence.
Tests all four basic movement directions: forward, backward, left strafe, and right strafe. Each movement lasts 1 second, demonstrating the full omnidirectional capabilities of mecanum wheels.
// 5.3 Four-Direction Movement Test
#include <Arduino.h>
const static uint8_t pwm_min = 50;
const static uint8_t motorpwmPin[4] = {10, 9, 6, 11}; // Motor PWM pins
const static uint8_t motordirectionPin[4] = {12, 8, 7, 13}; // Motor direction pins
void Motor_Init(void);
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift);
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3);
void setup() {
Serial.begin(9600);
Serial.setTimeout(500);
Motor_Init();
Serial.println("Starting 4-direction movement test...");
// Forward movement
Serial.println("Moving Forward");
Velocity_Controller(0, 100, 0, 0);
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Backward movement
Serial.println("Moving Backward");
Velocity_Controller(180, 100, 0, 0);
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Left strafe
Serial.println("Moving Left");
Velocity_Controller(270, 100, 0, 0);
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Right strafe
Serial.println("Moving Right");
Velocity_Controller(90, 100, 0, 0);
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
Serial.println("4-direction test complete!");
}
void loop() {
// Empty - single test sequence
}
void Motor_Init(void) {
for(uint8_t i = 0; i < 4; i++) {
pinMode(motordirectionPin[i], OUTPUT);
}
Velocity_Controller(0, 0, 0, 0);
}
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift) {
int8_t velocity_0, velocity_1, velocity_2, velocity_3;
float speed = 1;
angle += 90;
float rad = angle * PI / 180;
if (rot == 0) speed = 1;
else speed = 0.5;
velocity /= sqrt(2);
if (drift) {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed * 2;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed * 2;
} else {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed + rot * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed - rot * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed;
}
Motors_Set(velocity_0, velocity_1, velocity_2, velocity_3);
}
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3) {
int8_t pwm_set[4];
int8_t motors[4] = {Motor_0, Motor_1, Motor_2, Motor_3};
bool direction[4] = {1, 0, 0, 1}; // Forward direction defaults
for(uint8_t i = 0; i < 4; ++i) {
if(motors[i] < 0) direction[i] = !direction[i];
if(motors[i] == 0) pwm_set[i] = 0;
else pwm_set[i] = map(abs(motors[i]), 0, 100, pwm_min, 255);
digitalWrite(motordirectionPin[i], direction[i]);
analogWrite(motorpwmPin[i], pwm_set[i]);
}
} When you upload and run this code, your miniAuto should demonstrate omnidirectional movement:
🔍 Key Observation: Notice how the robot maintains its orientation while moving in all four directions - this is the power of mecanum wheels!
🎬 Watch Official Demo: View Hiwonder GIF demonstration of four-direction movement.
Tests diagonal movements by controlling specific wheel combinations. Demonstrates advanced mecanum wheel kinematics: forward-left, backward-right, forward-right, and backward-left movements.
// 5.4 Diagonal Movement Test
#include <Arduino.h>
const static uint8_t pwm_min = 50;
const static uint8_t motorpwmPin[4] = {10, 9, 6, 11}; // Motor PWM pins
const static uint8_t motordirectionPin[4] = {12, 8, 7, 13}; // Motor direction pins
void Motor_Init(void);
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift);
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3);
void setup() {
Serial.begin(9600);
Serial.setTimeout(500);
Motor_Init();
Serial.println("Starting diagonal movement test...");
// Forward-Left diagonal
Serial.println("Moving Forward-Left");
Velocity_Controller(315, 100, 0, 0); // 45° angle for diagonal
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Backward-Right diagonal
Serial.println("Moving Backward-Right");
Velocity_Controller(135, 100, 0, 0); // 135° angle
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Forward-Right diagonal
Serial.println("Moving Forward-Right");
Velocity_Controller(45, 100, 0, 0); // 45° angle
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(500);
// Backward-Left diagonal
Serial.println("Moving Backward-Left");
Velocity_Controller(225, 100, 0, 0); // 225° angle
delay(1000);
Velocity_Controller(0, 0, 0, 0); // Stop
Serial.println("Diagonal movement test complete!");
}
void loop() {
// Empty - single test sequence
}
void Motor_Init(void) {
for(uint8_t i = 0; i < 4; i++) {
pinMode(motordirectionPin[i], OUTPUT);
}
Velocity_Controller(0, 0, 0, 0);
}
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift) {
int8_t velocity_0, velocity_1, velocity_2, velocity_3;
float speed = 1;
angle += 90;
float rad = angle * PI / 180;
if (rot == 0) speed = 1;
else speed = 0.5;
velocity /= sqrt(2);
if (drift) {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed * 2;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed * 2;
} else {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed + rot * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed - rot * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed;
}
Motors_Set(velocity_0, velocity_1, velocity_2, velocity_3);
}
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3) {
int8_t pwm_set[4];
int8_t motors[4] = {Motor_0, Motor_1, Motor_2, Motor_3};
bool direction[4] = {1, 0, 0, 1}; // Forward direction defaults
for(uint8_t i = 0; i < 4; ++i) {
if(motors[i] < 0) direction[i] = !direction[i];
if(motors[i] == 0) pwm_set[i] = 0;
else pwm_set[i] = map(abs(motors[i]), 0, 100, pwm_min, 255);
digitalWrite(motordirectionPin[i], direction[i]);
analogWrite(motorpwmPin[i], pwm_set[i]);
}
} When you upload and run this code, your miniAuto should demonstrate advanced diagonal movements:
⚡ Advanced Feature: These diagonal movements showcase the sophisticated kinematics possible with mecanum wheels - impossible with regular wheels!
🎬 Watch Official Demo: View Hiwonder GIF demonstration of diagonal movements.
Tests advanced drifting capabilities where the robot moves sideways while rotating. This demonstrates the drift parameter in the velocity controller, creating car-like drifting motion.
// 5.5 Drifting Movement Test
#include <Arduino.h>
const static uint8_t pwm_min = 50;
const static uint8_t motorpwmPin[4] = {10, 9, 6, 11}; // Motor PWM pins
const static uint8_t motordirectionPin[4] = {12, 8, 7, 13}; // Motor direction pins
void Motor_Init(void);
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift);
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3);
void setup() {
Serial.begin(9600);
Serial.setTimeout(500);
Motor_Init();
Serial.println("Starting drift movement test...");
// Clockwise drift
Serial.println("Drifting Clockwise");
Velocity_Controller(90, 80, 50, true); // Right movement with rotation and drift enabled
delay(2000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(1000);
// Counter-clockwise drift
Serial.println("Drifting Counter-Clockwise");
Velocity_Controller(270, 80, -50, true); // Left movement with opposite rotation and drift
delay(2000);
Velocity_Controller(0, 0, 0, 0); // Stop
delay(1000);
// Forward drift with rotation
Serial.println("Forward Drift with Rotation");
Velocity_Controller(0, 60, 40, true); // Forward with rotation and drift
delay(2000);
Velocity_Controller(0, 0, 0, 0); // Stop
Serial.println("Drift test complete!");
}
void loop() {
// Empty - single test sequence
}
void Motor_Init(void) {
for(uint8_t i = 0; i < 4; i++) {
pinMode(motordirectionPin[i], OUTPUT);
}
Velocity_Controller(0, 0, 0, 0);
}
void Velocity_Controller(uint16_t angle, uint8_t velocity, int8_t rot, bool drift) {
int8_t velocity_0, velocity_1, velocity_2, velocity_3;
float speed = 1;
angle += 90;
float rad = angle * PI / 180;
if (rot == 0) speed = 1;
else speed = 0.5;
velocity /= sqrt(2);
if (drift) {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed * 2;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed * 2;
} else {
velocity_0 = (velocity * sin(rad) - velocity * cos(rad)) * speed + rot * speed;
velocity_1 = (velocity * sin(rad) + velocity * cos(rad)) * speed - rot * speed;
velocity_2 = (velocity * sin(rad) - velocity * cos(rad)) * speed - rot * speed;
velocity_3 = (velocity * sin(rad) + velocity * cos(rad)) * speed + rot * speed;
}
Motors_Set(velocity_0, velocity_1, velocity_2, velocity_3);
}
void Motors_Set(int8_t Motor_0, int8_t Motor_1, int8_t Motor_2, int8_t Motor_3) {
int8_t pwm_set[4];
int8_t motors[4] = {Motor_0, Motor_1, Motor_2, Motor_3};
bool direction[4] = {1, 0, 0, 1}; // Forward direction defaults
for(uint8_t i = 0; i < 4; ++i) {
if(motors[i] < 0) direction[i] = !direction[i];
if(motors[i] == 0) pwm_set[i] = 0;
else pwm_set[i] = map(abs(motors[i]), 0, 100, pwm_min, 255);
digitalWrite(motordirectionPin[i], direction[i]);
analogWrite(motorpwmPin[i], pwm_set[i]);
}
} When you upload and run this code, your miniAuto should demonstrate spectacular drifting movements:
🏎️ Cool Factor: This is the most impressive test - your robot will look like it's performing automotive-style drifts! Perfect for demonstrations.
🎬 Watch Official Demo: View Hiwonder GIF demonstration of drifting movements.
Create a demonstration program that shows all movement capabilities of the miniAuto.
void loop() {
Serial.println("Starting movement demonstration...");
// Forward movement
Serial.println("Moving Forward");
moveForward(150);
delay(2000);
stopMotors();
delay(500);
// Backward movement
Serial.println("Moving Backward");
moveBackward(150);
delay(2000);
stopMotors();
delay(500);
// Left strafe
Serial.println("Strafing Left");
moveLeft(150);
delay(2000);
stopMotors();
delay(500);
// Right strafe
Serial.println("Strafing Right");
moveRight(150);
delay(2000);
stopMotors();
delay(500);
// Clockwise rotation
Serial.println("Rotating Clockwise");
rotateClockwise(120);
delay(1500);
stopMotors();
delay(500);
// Counter-clockwise rotation
Serial.println("Rotating Counter-Clockwise");
rotateCounterClockwise(120);
delay(1500);
stopMotors();
delay(500);
Serial.println("Movement demonstration complete!");
delay(3000);
}