viernes, 30 de octubre de 2015

Ball and Beam

Hola muy Buenos días  :)

Aquí me tienen nuevamente con otra entrada muy interesante, para la implementación del proyecto, utilizamos la tarjeta de Arduino Uno. 

Espero que sea de su interés y claro lo mas importante, que les sea de gran utilidad para la realización de algún trabajo similar :) 

Ball and Beam

El sistema de ball and beam (bola y viga) es uno de los sistemas mas importantes para el estudio de los sistemas de control. Muchos métodos de control clásico y moderno se han utilizado para estabilizar el sistema de ball and beam. 

Una bola se coloca sobre una viga (figura siguiente), donde se le permite rodar con 1 grado de libertad a lo largo de la longitud de la viga. Un brazo de palanca esta unido a la viga en un extremo y del otro extremo un servomotor. A medida que el servomotor gira en un ángulo $\theta$, la palanca cambia el ángulo de la viga por un ángulo  $\alpha$.
Cuando el ángulo se cambia desde la posición horizontal, la gravedad hace que la bola ruede a largo de la viga.

Sistema Ball and Beam

Material


Arduino Uno
Servomotor


* Un balin (tamaño pequeño)

* Una viga (yo adapte dos reglas pequeñas pegandolas de los costados con forma de V)



Una vez explicado como funciona el sistema ball and beam, procedo a mostrarles el código implementado en Arduino.

Código Arduino


//Programa Ball and Beam
//Adriana Manzanárez 

///////////////////////////////
  #include <Servo.h>
  Servo myservo;                      // Creamos el objeto servo.
  const int numReadings = 15;
  int readings[numReadings];
  int index = 0;
  int total = 0;
  int input = 0;
  int angle = 0;                           //Variable del servomotor.
  int kp= 10;//2.4                       //Ganancia Proporcional
  float ki = 3.3;//1.7 - 2.4            //Ganancia Integral
  float kd = 17;  //3.3 -2.6          //Ganancia Derivativa
  float Pterm = 0; 
  float Iterm = 0; 
  float Dterm = 0; 
  int t = 10;
  int error = 0;
  int setpoint = 0;
  float val_1 = 0;
  float val_2 = 0;
  float delta = 0;
  float aceleracion = 0;
  
  int inputPin = 0;                        // Declaramos la entrada analogica
  
    void setup(){
      //Serial.begin(9600);
         for (int thisReading = 0; thisReading < numReadings; thisReading++ )
         readings[thisReading] = 0;
         myservo.attach(9);
   }
    void loop(){
   val_1 = analogRead(inputPin); //Lee el valor del pin analogico
   val_1 = map(val_1,77, 810, -366, 3669)   ; // 0, 1023, 0, 17//77, 810, -366, 366
   delay(t);
   val_2 = analogRead(inputPin); //Lee el valor del pin analogico
   val_2 = map(val_2,77, 810, -366, 366)   ;   
   delta = delta + val_2 - val_1;       //Se calclula la posición de delta.
   aceleracion = delta/t;       //Se calcula la aceleración del balin 
  
   total = total - readings[index];              // Sustrae la última posición
   readings[index] = analogRead(inputPin);       // Es leido desde el sensor
   total = total + readings[index];              //Agrega la siguiente posición.
   index = index + 1;                            //Establece la siguiente posición.
   if (index <= numReadings)
   index = 0;
   input = total/numReadings;                          //Calcula el promedio
   
   input = map(input, 77, 810, -366, 366);        //Se crea una regresión lineal. 
   error = input - setpoint;                               // Calculamos el error.
   
   Pterm = error * input;                      //Calculamos el valor proporcional
   Iterm = input;                                  //Calculamos el valor integral.
   Dterm = aceleracion;                       // Calculamos el valor derivativo.
   
  angle = (kp*Pterm) + (ki*Iterm) + (kd*Dterm); //Multiplicamos el controlador PID con las   ganancias del PID
   angle = map(angle, -366, 366, 100, 125);
   
   Serial.print ("Pocisión del Balin = ");
   Serial.print (input,DEC);
   Serial.print ("Ángulo del Servomotor = ");
   Serial.print (angle,DEC);
   Serial.print ("Error = ");
   Serial.print (error,DEC);
   
   myservo.write(angle);
   delay(t);
  }


Dejen comentarios si tienen alguna duda o sugerencias :)  Muchas gracias por leerme!!! <3
Que tengan un gran día
   .
-La única diferencia entre un buen y mal día es tu actitud.-Dennis S. Brown.



domingo, 25 de octubre de 2015

Convertidor de Código Binario a Gray en VHDL

Hola nuevamente! :) eh estado un poco desaparecida por estos lares, el día de hoy les dejo un programa de un Convertidor de Código Binario a Gray que realice en VHDL. 
Espero que sea de gran utilidad para ustedes, es un código muy sencillo y fácil de entender ;) cualquier duda o comentario es bienvenido. 

El código binario reflejado o código Gray, nombrado así en honor del investigador Frank Gray, es un sistema de numeración binario en el que dos valores sucesivos difieren solamente en uno de sus dígitos. El código Gray fue diseñado originalmente para prevenir señales ilegales (señales falsas o viciadas en la representación) de los switches electromecánicos, y actualmente es usado para facilitar la corrección de errores en los sistemas de comunicaciones, tales como algunos sistemas de televisión por cable y la televisión digital terrestre.
El Código Gray es un caso particular del sistema binario. Consiste en una ordenación de 2n números binarios de tal forma que cada número sólo tenga un dígito binario distinto a su predecesor. Esta técnica de codificación se originó cuando los circuitos lógicos digitales se realizaban con válvulas de vacío y dispositivos electromecánicos. Los contadores necesitaban potencias muy elevadas a la entrada y generaban picos de ruido cuando varios bits cambiaban simultáneamente. El uso de código Gray garantizó que en cualquier transición variaría tan sólo un bit. En la actualidad, el código Gray se sigue empleando para el diseño de cualquier circuito electrónico combinatorio, ya que el principio de diseño de buscar transiciones más simples y rápidas entre estados sigue vigente, a pesar de que los problemas de ruido y potencia se hayan reducido.
Es posible realizar esta conversión mediante una operación lógica XOR entre el número binario a convertir y el mismo número con un desplazamiento lógico a la derecha.

Objetivo

Realizar la descripción en VHDL del convertidor de código Binario a Gray mediante el algoritmo de conversión mencionado.

Tabla de Conversión

Código en VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity convertidor is
  Port (b : in bit_vector (7 downto 0);
           g : out bit_vector (7 downto 0));
end convertidor;
architecture Behavioral of convertidor is
begin
g <= b xor (b srl 1);
end Behavioral;


Código de Simulación 

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
  
ENTITY sim IS
END sim;

ARCHITECTURE behavior OF sim IS
 -- Component Declaration for the Unit Under Test (UUT)
 COMPONENT convertidor
 PORT(  b : in bit_vector (7 downto 0);
       g : out  bit_vector (7 downto 0));
    END COMPONENT;
   
--Inputs
signal b :bit_vector(7 downto 0) := (others => '0');

--BiDirs
   signal g :  bit_vector (7 downto 0);
   -- No clocks detected in port list. Replace <clock> below with
   -- appropriate port name

BEGIN
 -- Instantiate the Unit Under Test (UUT)
   uut: convertidor

PORT MAP (
          b => b,
          g => g    );

  -- Stimulus process
   stim_proc: process
   begin         
      -- hold reset state for 100 ns.
     wait for 100 ns;    

--  wait for <clock>_period*10;

      -- insert stimulus here
                  
          b <= "00000000"; wait for 100 ns;
              b <= "00000001"; wait for 100 ns;
              b <= "00000010"; wait for 100 ns;
              b <= "00000011"; wait for 100 ns;
              b <= "00000100"; wait for 100 ns;
              b <= "00000101"; wait for 100 ns;               
              b <= "00000110"; wait for 100 ns;              
              b <= "00000111"; wait for 100 ns;               
              b <= "00001000"; wait for 100 ns;          
              b <= "00001001"; wait for 100 ns;         
              b <= "00001010"; wait for 100 ns;
              b <= "00001011"; wait for 100 ns;
              b <= "00001100"; wait for 100 ns;
              b <= "00001101"; wait for 100 ns;
              b <= "00001110"; wait for 100 ns;
              b <= "00001111"; wait for 100 ns;


           wait;
   end process; 
END;

Implementación del código en la tarjeta Spartan 3E

Con las siguientes imágenes se demuestra que el código funciona, podemos observar que el encendido de los leds corresponde al numero Gray correspondiente al Decimal. 

Implementación del convertidor para el número 3.

Convertidor binario a gray para el número 4.


En verdad espero que sea de gran utilidad este código, si necesitan ayuda pueden escribirme. Gracias por leerme y que tengan un gran día :).

Saludos a todos!!