Introduction: DIY Omni Wheels Robot

About: I'm a generic and standard robot manufactured for the sole purpose of typing, I type on walls, wires, on the sidewalk and even sometimes on the air.

Recently I have designed this omni wheels robot, which can move on the ground agilely. This idea was inspired by a electronic trash can made one or two years ago by a Japanese guy, who in the video is throwing waste paper behind, knowing the controlled trash can will come up and catch the paper-ball.

The algorism inside is that the trash can first identify the paper-ball, and then calculate the possible drop point, and fast move to that point in respond. The motion transmission mechanism is smartly designed too, using only two motors to achieve the whole motion, one enables the wheel move forward or backward, while the other controls the angle of turn. In my design, I would like to improve the motion transmission mechanism. Instead of using ordinary wheels, I wanted to make a robot with omni wheels, driven by three 42 stepper motors. Robot Rovio was a good example for reference. I disassembled its movement mechanism and reverse engineered it. Then I started to think how to set up my own robot.

Step 1: Low Frame

I decided to make an experiment version at the beginning, which was of low cost and easy to assemble. First, the frame should be assembled very low in space.

Step 2:

Second, with enough strength, the wall of the frame should be as thin as possible. That’s how I made the first version with a simple round structure frame. The frame consisted of three triangle-shaped bases.

Step 3: Omni Wheels

Three omni wheels were equally spaced in the gap of bases, while each of them was driven by a 42mm stepper motor assembled on frame. In order to avoid barrier, a Robopeak laser radar was assembled on a round laser cut acrylic board at the top of the robot.

Step 4: Single Sided PCB

Once the mechanical parts were done, I started to build electrical parts. I made a temporary single sided PCB by heat transfer printing method (first transfer printing, then corroding, drilling, and at last welding).

Step 5:

The electric schematic diagram was referred to DreamMaker 3D printer main board. The stepper drivers’ signal pins are defined as the three axis movement of the 3D printer. In addition, a relay (5V to drive) was designed on to the board.

Step 6: Download Sources

I've put a link to download the pcb and 3D printable designs here:

Link

or

Link

Step 7: The Arduino Code

The code can be directly copied from here:

/*********************************************************************/
Code Author:DFRobot-Kelvin
Control Protocol:x100-y100-w100
                       X Direction:100mm/s
                       Y Direction:100mm/s
 
                       rotation to the left:100mm/s
 
/*********************************************************************/
#include 
double AcceleratedSpeed=400,whieelAcceleratedSpeed=500;//
double Step=0.03;//15*3.14/200/16
int xPul=25,
    xDir=23,
    xEnable=27,
    yPul=31,
    yDir=33,
    yEnable=29,
    zPul=37,
    zDir=39,
    zEnable=35,
    km_1=8;
Metro _Serial_=Metro(20);
double xspeed,yspeed,zspeed;
static double xSpeed,ySpeed,wheel;
long x_t,y_t,z_t;
void setup() {
  // put your setup code here, to run once:
    Serial3.begin(115200);
    pinMode(8,OUTPUT);
    pinMode(xPul,OUTPUT);
    pinMode(xDir,OUTPUT);
    pinMode(yPul,OUTPUT);
    pinMode(yDir,OUTPUT);
    pinMode(zPul,OUTPUT);
    pinMode(zDir,OUTPUT);
    pinMode(xEnable,OUTPUT);
    pinMode(yEnable,OUTPUT);
    pinMode(zEnable,OUTPUT);
    digitalWrite(xEnable,LOW);  
    digitalWrite(yEnable,LOW);
    digitalWrite(zEnable,LOW);    
    digitalWrite(km_1,HIGH);
}
void loop() {
  // put your main code here, to run repeatedly:
  static long t;
  if(_Serial_.check()==1)
   {
       serial();
       Speed(xSpeed,ySpeed,AcceleratedSpeed);
       //  Wheel(wheel);
       if(xspeed!=0)
           x_t=int(Step/abs(xspeed)*1000000);
       if(yspeed!=0)
           y_t=int(Step/abs(yspeed)*1000000);
       if(zspeed!=0)
           z_t=int(Step/abs(zspeed)*1000000);
        if(xspeed>0)
           digitalWrite(xDir,HIGH);
        else 
           digitalWrite(xDir,LOW);       
        if(yspeed>0)
           digitalWrite(yDir,HIGH);
        else 
           digitalWrite(yDir,LOW);
        if(zspeed>0)
           digitalWrite(zDir,LOW);
        else 
           digitalWrite(zDir,HIGH);
   }
 
  xMove(xspeed);
  yMove(yspeed);
  zMove(zspeed);
 
}
void serial()
{
    if(Serial3.available()==0) return;
    char buf=Serial3.read();
    switch(buf)
    {
      case 120://x
          xSpeed=Serial3.parseInt();
      break;
      case 121://y
          ySpeed=Serial3.parseInt();
      break;
     case 119://w
          wheel=Serial3.parsedouble();
      break;
    }
}
void Speed(double XSpeed,double YSpeed,double a)
{
    
    static double S_XSpeed=0,S_YSpeed=0;
   if (XSpeed>S_XSpeed)
   {
      S_XSpeed=S_XSpeed+a*0.02;
      if(S_XSpeed>XSpeed)
      {
         S_XSpeed=XSpeed;
      }
   }
   else{
      S_XSpeed=S_XSpeed-a*0.02;  
      if(S_XSpeedS_YSpeed)
   {
      S_YSpeed=S_YSpeed+a*0.02;
      if(S_YSpeed>YSpeed)
      {
         S_YSpeed=YSpeed;
      }
   }
   else{
      S_YSpeed=S_YSpeed-a*0.02;  
      if(S_YSpeedwheelspeed)
   {
      wheelspeed=wheelspeed+whieelAcceleratedSpeed*0.02;
      if(_wheelwheelspeed)
      {
         wheelspeed=_wheel;
      }
   }
   xspeed=xspeed+wheelspeed;
   yspeed=yspeed+wheelspeed;
   zspeed=zspeed-wheelspeed;  
}
void xMove(double xs)
{
    static long x_time=micros();
    if(xs!=0)
    {
        if(micros()-x_time>=x_t)
       {
           digitalWrite(xPul,HIGH);
           digitalWrite(xPul,LOW);
           x_time=micros();          
       }    
    }
}
void yMove(double ys)
{
    static long y_time=micros();
    if(ys!=0)
    {
        if(micros()-y_time>=y_t)
       {
           digitalWrite(yPul,HIGH);
           digitalWrite(yPul,LOW);
           y_time=micros();          
       }    
    }
}
void zMove(double zs)
{
    static long z_time=micros();
    if(zs!=0)
    {
        if(micros()-z_time>=z_t)
       {
           digitalWrite(zPul,HIGH);
           digitalWrite(zPul,LOW);
           z_time=micros();         
       }    
    }
}

Step 8: The Final Assembly Pic

That is how is looking right now. Complete design pic will be uploaded later as soon as the Trash can is fitted and sitting on top of it.

The Author is Swanglei, and a direct link to the article can be found here:

Link