Project showcase
Horizontal platform

Horizontal platform © GPL3+

Two servos and a ITG/MPU together with a UNO can keep a platform horizontal while moving the frame around

  • 2 views
  • 0 comments
  • 0 respects

Components and supplies

Apps and online services

About this project

I saw the servo tutorial from Nicholas and the MPU tutorial from Josh and I immediately had the idea to combine these two. I build a little platform that could move in two directions (X and Y). On the platform was the mpu registering the pitch and roll of the platform. The arduino processes these data and moves the servos in a direction so that the platform stays horizontal.

It is not going very fast but it works.

To demonstrate how it is processing the data I added 5 leds. 4 red) in a square and 1 (green) in the middle. when the platform is horizontal only the green led lights. Otherwise there are several other leds that indicate in which direction the platform is tilted. The variable "norm" gives the amount of degrees the platform may be from the exact horizontal position.

In the sketch are lines as: servox=servox+1 and:

servox=servox-1

The addition or substraction is depending on the way the servos are mounted and need some experimenting. Together with the above mentioned lines, the lines just before them (if (servox<179) and if (servox>0)) need to be replaced too.

Code

servompu.inoC/C++
#include<Wire.h>
#include <Servo.h>
#include <math.h>
const int MPU=0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ,servox,servoy,norm;
double pitch,roll;
Servo myservox;
Servo myservoy;

void setup(){
pinMode(7,OUTPUT);   // indicatie horizontaal;
pinMode(8,OUTPUT);   // indicatie pitch +;
pinMode(9,OUTPUT);   // indicatie pitch -;
pinMode(10,OUTPUT);   // indicatie roll +;
pinMode(11,OUTPUT);   // indicatie roll -;
myservox.attach(12);
myservoy.attach(13);
norm=2;
servox=90;    //middenpositie
servoy=90;    //tussen 0 en 179
myservox.write(servox);    //start op de middenpositie
myservoy.write(servoy);    //start op de middenpositie
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
//Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true);

int AcXoff,AcYoff,AcZoff,GyXoff,GyYoff,GyZoff;
int temp,toff;
double t,tx,tf;

//Acceleration data correction
AcXoff = -950;
AcYoff = -300;
AcZoff = 0;

//Temperature correction
toff = -1600;

//Gyro correction
GyXoff = 480;
GyYoff = 170;
GyZoff = 210;

//read accel data
AcX=(Wire.read()<<8|Wire.read()) + AcXoff;
AcY=(Wire.read()<<8|Wire.read()) + AcYoff;
AcZ=(Wire.read()<<8|Wire.read()) + AcYoff;

//read temperature data
temp=(Wire.read()<<8|Wire.read()) + toff;
tx=temp;
t = tx/340 + 36.53;
tf = (t * 9/5) + 32;

//read gyro data
GyX=(Wire.read()<<8|Wire.read()) + GyXoff;
GyY=(Wire.read()<<8|Wire.read()) + GyYoff;
GyZ=(Wire.read()<<8|Wire.read()) + GyZoff;

//get pitch/roll
getAngle(AcX,AcY,AcZ);
if (pitch<norm && pitch>-norm && roll<norm && roll>-norm)   // binnen de norm horizontaal
{
  digitalWrite(7, HIGH);
}
else
{
  digitalWrite(7, LOW);
}
if (pitch>norm)  // helt te veel voorover
{
  if (servox>0)
  {
   servox=servox-1;
   myservox.write(servox);
  }
  digitalWrite(8, HIGH);
}
else
{
  digitalWrite(8, LOW);
}

if (pitch<-norm)  // helt te veel achterover
{
  if (servox<179)
  {
   servox=servox+1;
   myservox.write(servox);
  }
  digitalWrite(9, HIGH);
}
else
{
  digitalWrite(9, LOW);
}
if (roll>norm)    // helt te veel naar links
{
  if (servoy<179)
  {
   servoy=servoy+1;
   myservoy.write(servoy);
  }
  digitalWrite(10, HIGH);
}
else
{
  digitalWrite(10, LOW);
}
if (roll<-norm)     // helt te veel naar rechts
{
  if (servoy>0)
  {
   servoy=servoy-1;
   myservoy.write(servoy);
  }

  digitalWrite(11, HIGH);
}
else
{
  digitalWrite(11, LOW);
}

//send the data out the serial port
//Serial.print("Angle: ");
//Serial.print("Pitch = "); Serial.print(pitch);
//Serial.print(" | Roll = "); Serial.print(roll);

//Serial.print("  Temp: ");
//Serial.print("Temp(F) = "); Serial.print(tf);
//Serial.print(" | Temp(C) = "); Serial.print(t);

//Serial.print("  Accel.: ");
//Serial.print("X = "); Serial.print(AcX);
//Serial.print(" | Y = "); Serial.print(AcY);
//Serial.print(" | Z = "); Serial.print(AcZ);

//Serial.print("  Gyroscope: ");
//Serial.print("X = "); Serial.print(GyX);
//Serial.print(" | Y = "); Serial.print(GyY);
//Serial.print(" | Z = "); Serial.println(GyZ);
//Serial.println(" ");
delay(20);
}

//convert the accel data to pitch/roll
void getAngle(int Vx,int Vy,int Vz) {
double x = Vx;
double y = Vy;
double z = Vz;

pitch = atan(x/sqrt((y*y) + (z*z)));
roll = atan(y/sqrt((x*x) + (z*z)));
//convert radians into degrees
pitch = pitch * (180.0/3.14);
roll = roll * (180.0/3.14) ;

}

Schematics

horizontal platform
servompu_uTgiBpgrZu.fzz

Comments

Similar projects you might like

Level Platform Using Accelerometer

Project tutorial by Mark Tashiro

  • 26,250 views
  • 19 comments
  • 40 respects

Servo-Controlled, Light-Tracking Solar Panel Platform

Project tutorial by scott mangiacotti

  • 18,131 views
  • 12 comments
  • 52 respects

Getting Started with the Smartcar Platform

by Dimitris Platis

  • 15,666 views
  • 10 comments
  • 51 respects

Arduino IoT with SAP HANA Cloud Platform

by derapados

  • 7,070 views
  • 11 comments
  • 10 respects

Bluetooth Controlled Servo

Project tutorial by JANAK13

  • 26,646 views
  • 24 comments
  • 48 respects

Arduino Horizontal POV Display

Project tutorial by Mirko Pavleski

  • 5,755 views
  • 1 comment
  • 25 respects
Add projectSign up / Login