Introduction: Mecanum Omni Wheels Robot With GRBL Stepper Motors Arduino Shield

Mecanum Robot - A project I wanted to build ever since I saw it on the Dejan's gread mechatronics blog:

Dejan really made a good job covering all the aspects from hardware, 3D printing, electronics, code and an Android app (MIT's App inventor)

This is a great overhoul project that refreshes all the skills of a maker.

I had few changes to do to the projects

I didnt want to use the custom made PCB he used , but an old GRBL shield I had at home.

I wanted to use BlueTooth



Step 1: Hardware

Printed the wheels and assembeled them as in here:

Connected 4 Stepper motors to the chassis (in my case an unused drawer up side down)

Routed the cables to the top of the robot.

Step 2: Electronics

I used my HC-06 BT module,

The hardest part was to set the GRBL shield to work with 4 Stepper motors since there's no good guide for that,

Theres a need to put Jumpers as can be seen in the attached picture, in order to make the "Tool" output of the shield to also control a stepper motor. also need to put "Enable" Jumper

wiring the 4 steppers and thats it.

I also supplied the power from 12V batteries - two stes - one for the Arduino and one for the GRBl Shield

Step 3: Arduino Code

/* === Arduino Mecanum Wheels Robot === Smartphone control via Bluetooth by Dejan, Libraries: RF24, AccelStepper by Mike McCauley:

*/ /* 12/11/2019 Gilad Meller ( - modify the code to work with GRBL arduino motor shield Stepper motors in the shield are mapped as (step/direction): 2/5 3/6 4/7 12/13 using A4988 driver 12V

Dejan's code uses SoftwareSerial and mine will use the standard RX,TX pins (0,1) of the Arduino Uno Note: Make sure to rempve the RX TX pins when uplading sketch to the arduino or the upload will fail.

*/ #include

// Define the stepper motors and the pins the will use AccelStepper LeftBackWheel(1, 2, 5); // (Type:driver, STEP, DIR) - Stepper1 AccelStepper LeftFrontWheel(1, 3, 6); // Stepper2 AccelStepper RightBackWheel(1, 4, 7); // Stepper3 AccelStepper RightFrontWheel(1, 12, 13); // Stepper4

int incomingByte = 0,c; // for incoming serial data int wheelSpeed = 100;

void setup() { Serial.begin(9600); // opens serial port, sets data rate to 9600 bps // Set initial seed values for the steppers LeftFrontWheel.setMaxSpeed(600); LeftBackWheel.setMaxSpeed(600); RightFrontWheel.setMaxSpeed(600); RightBackWheel.setMaxSpeed(600);


void loop() { if (Serial.available() > 0) { // read the incoming byte: incomingByte =;

c = incomingByte; switch (c) { case 71: Serial.println("I received Rotate right W"); rotateRight(); break; case 65: Serial.println("I received Rotate left Q"); rotateLeft(); break; case 1: Serial.println("I received BK/LFT "); moveRightBackward(); break; case 2: Serial.println("I received BK "); moveBackward(); break; case 3: Serial.println("I received BK/RT "); moveRightBackward(); break; case 4: Serial.println("I received LEFT "); moveSidewaysLeft();

break; case 5: Serial.println("I received STOP "); stopMoving(); break; case 6: Serial.println("I received RT "); moveSidewaysRight(); break; case 7: Serial.println("I received FWD/LFT "); moveLeftForward(); break; case 8: Serial.println("I received FWD "); moveForward(); break; case 9: Serial.println("I received FWD/RT "); moveRightForward(); break; default: Serial.print("Not a command "); Serial.println(incomingByte, DEC); break; } } //moveBackward(); moveRobot();


void moveRobot() { LeftBackWheel.runSpeed(); LeftFrontWheel.runSpeed(); RightFrontWheel.runSpeed(); RightBackWheel.runSpeed(); }

void moveForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveSidewaysRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveSidewaysLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void rotateLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void rotateRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveRightForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(wheelSpeed); } void moveRightBackward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftForward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(-wheelSpeed); } void stopMoving() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(0); }

Step 4: Appinventor

A new appinventor app with different and simpler functionallity (No Recordings)

Please send msg and I send to you - the uploads fails.

Take care.