Introduction: Arduino Ball and Beam Project (sistema Barra Bola Con Arduino)

About: mechatronics engineer, maker

hola amigos en este caso construiremos un sistema barra bola, uno de los proyectos mas usados para aprender control automático, en el buscamos posicionar la bola en un punto determinado en un eje (barra) esta barra debe inclinarse cuando la bola es perturbada para posicionar siempre la bola en el punto establecido(punto de operación), nuestra variable a censar en este caso es la posición y el actuador a usar es un servomotor, como microcontrolador usaremos Arduino y el montaje mecánico en madera MDF cortada a laser.

Supplies

protoboard

Micro Servomotor SG90

Arduino o microcontrolador atmega 320

bola de ping pong

madera mdf de 3mm

servicio de corte laser

Sensor Ultrasonido HC-SR04

Step 1: Diseño Mecánico

primero debemos planear nuestro diseño mecánico del sistema teniendo en cuenta que debe tener un pivote o eje en este caso central, y un sistema biela manivela que transmitirá movimiento rotativo en una inclinación positiva y negativa en la barra donde rueda la bola y dado que nuestro servomotor es de 180 grados. la posición 90 grados del servomotor debe establecer la barra de forma horizontal así la mínima inclinación de la barra se presenta en la posición 0 del servomotor, barra horizontal en 90 grados y máxima inclinación en 180 grados.


determinar nuestro sensor de proximidad también condiciona directamente la exactitud de nuestro sistema, en este caso use un sensor de proximidad Ultrasonido HC-SR04 pero en otras aplicaciones se puede usar sensor infrarrojo Sharp Gp2y0a41sk0f

descargar el diseño mecánico: https://grabcad.com/library/ball-an-beam-model-with-arduino-1

Step 2: Simulaciones Y Cálculos

Step 3: Programación

puedes descargar el código de github : https://github.com/ymaogar/Ball_and_Beam_Arduino

librería pid :https://github.com/ymaogar/Arduino-PID-Library

librería new ping (esta garantiza mas precisión del sensor ultrasónico): https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home


#include<Servo.h>
#include<PID_v1.h>
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     11
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

const int servoPin = 9;                                               //Servo Pin

float Kp = 1.8;                                                    //Initial Proportional Gain
float Ki = 0.6;                                                      //Initial Integral Gain
float Kd = 1.1;                                                    //Intitial Derivative Gain
double Setpoint, Input, Output, ServoOutput;                                       

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);           //Initialize PID object, which is in the class PID.
                                                                                                                                      
Servo myServo;                                                       //Initialize Servo.


void setup() {

  Serial.begin(9600); //Begin Serial 
  myServo.attach(servoPin);                                          //Attach Servo

  Input = readPosition();                                            //Calls function readPosition() and sets the balls
                                                                     //  position as the input to the PID algorithm
  myPID.SetMode(AUTOMATIC);                                          //Set PID object myPID to AUTOMATIC 
  myPID.SetOutputLimits(-70,70);                                     //Set Output limits to -80 and 80 degrees. 
}

void loop()
{
  Setpoint = 19;
  Input = readPosition();                                            
 
  myPID.Compute();                                                   //computes Output in range of -80 to 80 degrees
  
  ServoOutput=81+Output;                                            // 102 degrees is my horizontal 
  myServo.write(ServoOutput);                                        //Writes value of Output to servo
}
      
      

float readPosition() 
{
  delay(40);                                                            //Don't set too low or echos will run into eachother.      
  long cm;
  cm = sonar.convert_cm(sonar.ping_median(5));
  
  if(cm > 40)     // 40 cm is the maximum position for the ball
  {cm=40;}
  
  Serial.println(cm);
  return cm;                                          //Returns distance value.
}