Está en la página 1de 45

UPIITA-IPN Materia: Circuitos Lógicos

Proyecto. Brazo Robótico con RF Número de mesa: 1


Galván Escobar Adrián Raúl Nombre de la empresa: Mexilogics
Mata Prieto Varush Grupo: 2MV12
Varela Alpízar Benjamín
Fecha: 16 de junio de 2023

Resumen

En el presente reporte se documentan los códigos, diagramas y las evidencias de


funcionamiento para el sistema de brazo robótico de 4 grados de libertad que se controla
mediante RF (radiofrecuencia) comunicando 2 FPGA’s Amiba 2, por el envío de comandos
de un control hecho de push buttons para el movimiento del brazo y muestra en displays de
7 segmentos la dirección de movimiento del brazo. Los códigos implementados fueron
realizados en VHDL.

Abstract

This report documents the codes, diagrams and evidence of operation for the 4 degrees of
freedom robotic arm system that is controlled by RF (radio frequency) communicating 2
Amiba 2 FPGA's, by sending commands from a push button control for the arm movement
and displaying on 7 segment displays the direction of the arm movement. The implemented
codes were made in VHDL.

Índice
Resumen ................................................................................................................................. 1
Abstract ................................................................................................................................... 1
Problemática planteada ........................................................................................................... 2
Criterios de elección para los componentes de nuestro sistema: ............................................ 3
Características de nuestros componentes ............................................................................... 3
Circuitos esquemáticos: .......................................................................................................... 6
Cálculos realizados ................................................................................................................. 8
Códigos HDL........................................................................................................................ 10
Para el transmisor ........................................................................................................... 10
Programa principal: MASTER .......................................................................... 11
Componente U1: RS232 ...................................................................................... 13
Archivo de restricción de usuario (.ucf): ........................................................... 21

1
Para el receptor ............................................................................................................... 21
Código TOP SLAVE R ........................................................................................ 22
Componente U1: RS232 ...................................................................................... 27
Componentes U2, U3, U4 y U5: Servo_pos ........................................................ 35
Componente U6: DIV_CLK ............................................................................... 36
Componente U7: Display Result ......................................................................... 37
Archivo de restricciones de usuario (.ucf): ........................................................ 38
Fotos y video ........................................................................................................................ 40
Conclusiones......................................................................................................................... 43
Fuentes bibliográficas ........................................................................................................... 44

Problemática planteada

Para este proyecto se solicitó implementar un sistema de control a distancia con RF


(radiofrecuencia) de un brazo robótico de 3 o 4 de libertad, siendo para ambos casos un grado
de liberta la apertura y cierre de un gripper o de un lanzador de pelotas. El control del
movimiento debe ser realizado por botones o joysick y se pueden utilizar módulos de RF
comerciales (con excepción de los Bluetooth). Además, el sistema debe contar con
indicadores de movimiento visual (Display de 7 segmentos o LCD) e indicador audible de
los movimientos.
Para dar solución a esta problemática, comenzamos por enlistar los componentes de nuestro
sistema:
• Para el sistema fueron utilizadas 2 FPGA’s Amiba 2, donde la primera tendrá la
función de maestro en nuestra comunicación por RF, es decir, será la encargada de
enviar los comandos de movimiento de nuestro brazo robótico, mientras que la
segunda fungirá de esclavo, recibiendo los comandos y desplazando el brazo robótico
de acuerdo con las instrucciones que reciba.
• Para la comunicación por RF entre las FPGA’s se utilizaron los módulos de
transmisión y recepción de radiofrecuencia a una frecuencia de 433 [MHz]. Por
una parte, el transmisor (TX, de código de parte FS1000A) se conectó a la Amiba 2
maestro, mientras que el receptor (RX, de código de parte XY-MK-5V) se conecto a
la amiba 2 esclavo para la recepción de los comandos enviados.
• Para los módulos de transmisión y recepción se incorporaron antenas helicoidales de
cobre
• La estructura del brazo robótico se compro para que se acoplaran un mismo tipo de
servomotor
• Los servomotores utilizados para este brazo robótico fueron los de código de parte
SG 90 RC. Empleando un total de 4 servomotores, se controlaron la rotación,
2
desplazamiento hacia arriba y abajo del gripper, desplazamiento hacía el frente o
detrás del gripper y la apertura o cierre del gripper.
• El control para el envío de comandos se realizo con 8 push buttons y a cada uno de
estos un arreglo de 2 resistencias de 10 [kΩ].

Criterios de elección para los componentes de nuestro sistema:

• FPGA’s Amiba 2: Se implementaron 2 amiba 2 para el sistema dado que los


integrantes de Mexilogics contábamos con estas FPGA y nos permitió el trabajar en
la codificación fuera de los laboratorios. Además, esta tarjeta de desarrollo contaba
con los recursos necesarios para la implementación de nuestro proyecto. Para el
despliegue de los mensajes hacía que dirección se desplazaba nuestro brazo,
utilizamos 4 de los displays incorporados a la FPGA esclava (con el receptor de RF)
para mostrar los mensajes de desplazamiento.
• Módulos de transmisión y recepción por RF: Para el caso del emisor (FS1000A) y el
receptor (XY-MK-5V) estos se escogieron por ser módulos comerciales de bajo costo
y que cumplían con la función solicitada. En adición, la frecuencia a la que trabajan
estos módulos es de libre uso, evitando las interferencias con otros dispositivos que
implican este tipo de tecnología para el envío/recepción de datos.
• Las antenas helicoidales incorporadas a los módulos de transmisión y recepción se
escogieron para aumentar el alcance y la estabilidad de la transmisión.
• La estructura del Brazo robótico se compro pensando en el acoplamiento de los 4
servomotores del mismo tipo.
• Los servomotores SG90 se escogieron ya que son de los servomotores más versátiles
para la realización de nuestro proyecto, siendo capaces de desplazar objetos de peso
ligero y cumplir con la función solicitada.

Características de nuestros componentes

• FPGA Amiba 2 (Ver figura 1):


o Oscilador de 50 [MHz]
o 51 puertos I/O de propósito general
o 12 LEDs indicadores (de los cuales 8 son
de propósito general y que utilizamos
para la verificación del envío de
comandos)
o 9 switch de 2 posiciones (1 para
encendido/apagado de la FPGA y 8 de
propósito general)
o 6 pulsadores (1 para reset de la FPGA y
5 Pull-Down de propósito general)
o 8 displays de 7 segmentos de ánodo
Figura 1.- Vista superior – Amiba 2
común

3
o Puerto de expansión a protoboard (P1)
o Puerto de expansión hembra (P2)
o Puerto de expansión para LCD 16x2 (P3)

• Emisor FS1000A (ver figura 2)


o Tensión de alimentación: 3 a 12 [V] en DC
o Consumo de corriente en operación: 20~28 [mA]
o Consumo de corriente en standby: 4 [mA]
o Frecuencia de operación 433 [MHz]
o Velocidad de transferencia: 4 Kb/s
o Distancia de trabajo: 20 a 200 [m]
o Potencia de transmisión: 10 [mW]
o Su pinout se puede ver en la figura 2.
• Receptor XY-MK-5V (ver figura 2)
o Voltaje de operación: 5 [V] en DC
o Consumo de corriente en standby: 4 [mA]
o Frecuencia de operación: 433 [MHz]
o Su pinout se puede ver en la figura 2.

Figura 2.- Pinout FS1000A y XY-MK-5V

• Antena helicoidal de cobre (433 [MHz]) (ver figura 3)


• Rango de frecuencia: 433[MHz], este modelo de antena se diseñó
específicamente para los módulos comerciales de RF antes presentados.
• Ganancia: 2 decibeles
• Diámetro del cable: 6 [mm]
• Diámetro: 5 ± 0.5 [mm]
4
• Longitud: 34 [mm]

Figura 3.- Antena helicoidal

• Servomotor SG90 (4 unidades) (Ver figura 4)


• Peso: 9 gramos
• Dimensiones: 22.2 x 11.8 x 31 [mm]
• Torque: 1.8 Kg/cm
• Velocidad: 0.1s/60°
• Alimentación: 5 [V] en DC

Figura 4.- Servomotor SG90

5
Circuitos esquemáticos:

Para nuestro proyecto se consideraron los siguientes esquemáticos:


• FPGA Maestra (ver figura 5): Es aquella que contiene el transmisor de RF y está
compuesta por el módulo FS1000A y un control de 8 push buttons que se realizo para
el envío de comandos, ambos elementos conectados a los puertos de expansión de la
FPGA

Figura 5.- Diagrama esquemático –


FPGA Maestra

Para el diseño de los arreglos de 2 resistencias de 10 [kΩ] del control de 8 push buttons nos
basamos en el esquemático del manual de usuario de INTESC para la FPGA amiba 2 (ver
figura _)

Figura 6.- Diagrama esquemático –


push buttons para control de brazo
robótico

6
• FPGA esclava (Ver figura 7): Para esta FPGA se conectaron los servomotores de la
estructura del brazo robótico y el módulo de recepción de RF XV-MK-5V, además
se utilizaron sus leds incorporados para el reconocimiento y comprobación de la
recepción de los comandos de movimiento y el despliegue de mensajes indicadores
del desplazamiento en los 4 displays de 7 segmentos incorporados a la FPGA (ver
figura 8).

Servomotores
SG90

Figura 7.- Diagrama esquemático –


FPGA Esclava

7
Figura 8.- Diagrama esquemático –
FPGA Maestra para displays de 7
segmentos

Cálculos realizados

• Para el PWM:
Para el control del desplazamiento de nuestros servomotores se consideraron
desplazamientos máximos de 90° para no comprometer el cableado y generar alguna posible
falla o desconexión de los servomotores de la FPGA, el calculo se hizo considerando la figura
9.

Figura 9.- Periodo de señal para


PWM

8
𝑅𝑎𝑛𝑔𝑜 = 2𝑚𝑠 − 1𝑚𝑠 = 1𝑚𝑠
Frecuencia necesaria:
𝑅𝑎𝑛𝑔𝑜 1𝑚𝑠 −1
𝑓𝑛𝑒𝑠 = ( )−1 = ( ) = 90𝑘ℎ𝑧
𝑟𝑒𝑠𝑜𝑙𝑢𝑖𝑐𝑖ó𝑛 90
Divisor de frecuencia:
𝑓𝑒𝑛𝑡𝑟𝑎𝑑𝑎 50𝑀ℎ𝑧
𝐸𝑠𝑐𝑎𝑙𝑎 = = = 555.55
𝑓𝑠𝑎𝑙𝑖𝑑𝑎 90𝑘ℎ𝑧
Al ser el ciclo útil del 50%:
555.55
𝐸𝑠𝑐𝑎𝑙𝑎 = = 277
2
En 90khz:
1
𝑡 = = 11.11𝑢𝑠
90𝑘ℎ𝑧
En 90 iteraciones 1ms:
(11.11𝑢𝑠)(90) = 1𝑚𝑠
Para 20ms:
20(90) = 1800
Por lo que en el código se contará 1800 veces para comparar el pwm
Ya que son 90 grados, se le agrega un offset de 90 a la posición.
• Para la potencia consumida por los servomotores y el consumo por hora continua de
operación:
𝑃𝑜𝑡𝑒𝑛𝑐𝑖𝑎 = 𝐶𝑜𝑟𝑟𝑖𝑒𝑛𝑡𝑒 𝑐𝑜𝑛𝑠𝑢𝑚𝑖𝑑𝑎 ∗ 𝑇𝑒𝑛𝑠𝑖ó𝑛 𝑑𝑒 𝑎𝑙𝑖𝑚𝑒𝑛𝑡𝑎𝑐𝑖ó𝑛
Los servomotores consumen una corriente de 550mA y se alimentan con 5V
𝑃𝑜𝑡𝑒𝑛𝑐𝑖𝑎 = 4(550𝑚𝐴 ∗ 5𝑉) + 20𝑚𝑊 = 11.02𝑊
La potencia por hora:
11.02 ∗ 1ℎ𝑟 = 11.02𝑊/ℎ𝑜𝑟𝑎
• Longitud de onda de la radiofrecuencia
La longitud de onda se calcula con:
𝜆 = 𝑐/𝑣

9
Donde c es la velocidad de la luz y v es la frecuencia en Hertz:
𝜆 = 3𝑥108 /433𝑀ℎ𝑧
𝜆 = 0.693 𝑚
Al ser las ondas usadas para la transmisión electromagnéticas la forma de propagación tiene
la forma de estas las cuales son sinusoidales.

Códigos HDL

Estos se codificaron en Lenguaje VDHL y se implementaron 2 proyectos distintos: Uno para


la FPGA maestra (la que incluía el transmisor de RF y el control de 8 push buttorns) y otro
para la FPGA esclava (la que incluía el receptor de RF y los servomotores y se usaban los
leds y displays de 7 segmentos incorporados a esta FPGA).
Para el transmisor (ver figura 10): Este proyecto contiene un programa principal
(MASTER), un componente (RS232) y su archivo de restricciones (AMIBA2.ucf)

Figura 10.- Archivos del proyecto


para la FPGA Maestra

Archivo MASTER.vhd: en este código se realizó la transmisión de datos con ayuda de la


comunicación RS232, que controla el envío gracias a una máquina de estados la cual hace
que se almacenen los datos cuando mientras que el bit de fin de transmisión no esté activo,
cuando se active el fin de transmisión el bit de inicio de transmisión se desactiva hasta llegar
otra vez a la etapa de inicio.

Figura 11.- Máquina de estado


para la transmisión de la FPGA
Maestra

10
Archivo RS232.vhd: Con la ayuda de la librería de intesc se modificaron los valores para
adaptarse a la frecuencia de los módulos de transmisión de datos, este programa monitorea
el pulso que se envía conteniendo los datos que se enviarán a la FPGA que controla nuestro
brazo mecánico.
• Programa principal: MASTER
----------------------------------------------------------------------
------------
-- MEXILOGICS: CÓDIGO PARA MANDAR EL ESTDO DE 8 PUSHBUTTONS, YA QUE SE
NECESITAN 2 BOTONES
-- PARA CADA GRADO DE LIBERTAD, SE MANDARÁN A OTRA FPGA POR MEDIO DE
UN MÓDULO DE RADIO
-- FRECUENCIA
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity MASTER is
port(
CLK: in STD_LOGIC;
SWITCHES: in STD_LOGIC_VECTOR (7 downto 0);
TX: out STD_LOGIC
);
end MASTER;

architecture Behavioral of MASTER is

signal tx_in_s,rx_in_s: std_logic;


signal tx_fin_s,rx: std_logic;
signal datain_s,dout_s: std_logic_vector (7 downto 0);

-- SYMBOLIC ENCODED state machine: STATE


type STATE_type is (
ASIGNA, ENVIA
);
-- attribute enum_encoding of STATE_type: type is ... -- enum_encoding
attribute is not supported for symbolic encoding

signal STATE, NextState_STATE: STATE_type;

-- Declarations of pre-registered internal signals


component RS232 is
generic( FPGA_CLK : integer := 50000000;
BAUD_RS232 : integer := 9600
);
port( CLK : in std_logic;
RX : in std_logic;
TX_INI : in std_logic;
DATAIN : in std_logic_vector(7 downto 0);
TX_FIN : out std_logic;
TX : out std_logic;

11
RX_IN : out std_logic;
DOUT : out std_logic_vector(7 downto 0)
);
end component RS232;

begin

--COMPONENTE PARA LA COMUNICACIÓN RS232


--ASIGNANDO LA FRECUENCIA Y EL BAUDRATE REQUERIDO
u1 : rs232 generic map(
FPGA_CLK => 433_000_000,
BAUD_RS232 => 2400
)
port map( CLK => CLK,
RX => RX,
TX_INI => tx_in_s,
TX_FIN => tx_fin_s,
TX => TX,
RX_IN => rx_in_s,
DATAIN => datain_s,
DOUT => dout_s
);

----------------------------------------------------------------------
-- Machine: STATE
----------------------------------------------------------------------
------------------------------------
-- Next State Logic (combinatorial)
------------------------------------
STATE_NextState: process (STATE)
begin
NextState_STATE <= STATE;
-- Set default values for outputs and signals
-- ...
case STATE is
when ASIGNA =>
DATAIN_s <= SWITCHES;
NextState_STATE <= ENVIA;
when ENVIA =>
if TX_FIN_s = '0' then
NextState_STATE <= ENVIA;
TX_IN_s <= '1';
elsif TX_FIN_s = '1' then
NextState_STATE <= ASIGNA;
TX_IN_s <= '0';
end if;
--vhdl_cover_off
when others =>
null;
--vhdl_cover_on
end case;
end process;

------------------------------------

12
-- Current State Logic (sequential)
------------------------------------
STATE_CurrentState: process (clk)
begin
if clk'event and clk = '1' then
STATE <= NextState_STATE;
end if;
end process;

end Behavioral;

• Componente U1: RS232


----------------------------------------------------------------------
------------
-- MEXILOGICS: CONTROL POR PROTOCOLO RS232 UTILIZANDO LA LIBRERÍA DE
INTESC
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity RS232 is

--El generic es til cuando RS232 es parte de un TOP. SI no es parte de


un TOP

--entonces se deben poner tanto la frecuencia del FPGA como los


BAUDIOS como valores

--contantes en el generic

generic ( FPGA_CLK : INTEGER := 50000000; --


FRECUENCIA DEL FPGA POR EJEMPLO 50000000

BAUD_RS232 : INTEGER := 9600


--BAUDIOS. POR EJEMPLO 9600

);
port ( CLK : in std_logic ; --Reloj de
FPGA
RX : in std_logic ;
--Pin de recepcin de RS232

TX_INI : in std_logic ;
--Debe ponerse a '1' para inciar transmisin

TX_FIN : out std_logic ;


--Se pone '1' cuando termina la transmisin
TX : out std_logic ;
--Pin de transmisin de RS232

13
RX_IN : out std_logic ; --Se
pone a '1' cuando se ha recibido un Byte. Solo dura un

--Ciclo de reloj

DATAIN : in std_logic_vector(7
downto 0); --Puerto de datos de entrada para transmisin
DOUT : out std_logic_vector(7 downto 0)
--Puerto de datos de salida para recepcin
);
end RS232;

architecture Behavioral of RS232 is

CONSTANT FPGA_CLK2 : INTEGER := FPGA_CLK;

CONSTANT BAUD_RS2322 : INTEGER := BAUD_RS232 ;

CONSTANT BAUD_FPGA2 : INTEGER :=


FPGA_CLK2/BAUD_RS2322 ;
CONSTANT CLKBAUD2 : INTEGER := BAUD_FPGA2/2 ;

signal flanco_bajada : std_logic := '0';


signal clk_ini : std_logic := '0';

signal clk_tx_ini : std_logic := '0';


signal clk_flanco : std_logic := '0';

signal clk_tx_flanco : std_logic := '0';


signal rx_vector : std_logic_vector(4 downto
0) ;
signal rx_vector2 : std_logic_vector(4 downto
0) ;

signal tx_data : std_logic_vector(7


downto 0) ;

signal tx_data2 : std_logic_vector(7


downto 0) ;

signal dout_paralelo : std_logic_vector(9 downto


0) ;
signal clk_baud : natural range 0 to
CLKBAUD2 - 1;

signal clk_tx_baud : natural range 0 to


BAUD_FPGA2 - 1;
signal paralelo_paso : natural range 0 to 6 := 0
;

14
signal tx_maquina : natural range 0 to 6 := 0
;
signal n : natural
range 0 to 10 := 0 ;

signal tx_n : natural range 0 to


10 := 0 ;

begin

--Registro de corrimiento que muestrea RX en busca de condicion de


INICIO
rx_vector <= rx_vector2(3 downto 0) & RX;

process(CLK)
begin
if rising_edge(CLK) then
rx_vector2 <= rx_vector;
end if;
end process;

----------------------------------------------

--Genera un flanco de bajada siempre que la condicion "1100" sea


cierta
flanco_bajada <= '1' when rx_vector(4 downto 1) = "1100" else
'0';

--Maquina de estados que controla la rececion de 1 byte

RECEPCION: process(CLK)
begin
if rising_edge(CLK) then
if paralelo_paso = 0 then
n <= 0;

--Si hay un flanco de bajada en el estado 0 se debe a


una condicion de inicio
if flanco_bajada = '1' then
paralelo_paso <= 1;
else
paralelo_paso <= 0;
end if;

RX_IN <= '0';


elsif paralelo_paso = 1 then

--Inicia reloj de BAUDIOS


clk_ini <= '1';

15
paralelo_paso <= 2;
elsif paralelo_paso = 2 then

--Este flanco indica la mitad del bit de inicio


if clk_flanco = '1' then
paralelo_paso <= 5 ;
else
paralelo_paso <= 2;
end if;
elsif paralelo_paso = 3 then

--Si hay un flanco, quiere decir que ha terminado un


bit e inicia

--el siguiente
if clk_flanco = '1' then
paralelo_paso <= 4;
else

--SI no hay flanco, esta condicin indica la


salida y el trmino de la

--recepcion
if n < 10 then
paralelo_paso <= 3;
else
n <= 10;
paralelo_paso <= 6;
end if;
end if;
elsif paralelo_paso = 4 then

--Si hay un flanco, entonces indica que se encuentra en


medio de la recepcion

--y debe ir al paso cinco para incremntar "n"


if clk_flanco = '1' then
paralelo_paso <= 5 ;
else
paralelo_paso <= 4;
end if;
elsif paralelo_paso = 5 then

--Recibe bit a bit la informacin de entrada. "n" debe


contar hasta 8
n <= n + 1 ;
dout_paralelo(n) <= RX ;
paralelo_paso <= 3;
else

--En este ltimo paso, termina la recepcin y pone a un


la bandera RX_IN indicando

16
--que se ha recibido el BYTE y regresa al paso 0
(esperando otra recepcin)
DOUT<= dout_paralelo(8 downto 1);
clk_ini <= '0';
n <= 0;
paralelo_paso <= 0;

RX_IN <= '1';


end if;
end if;
end process;

--Reloj con frecuencia de BAUDIOS/2 para entrada. Siempre que termina,


enva un flanco en

--clk_flanco
process(CLK)
begin
if rising_edge(CLK) then
if clk_ini = '1' then
if clk_baud < (CLKBAUD2-1) then
clk_baud <= clk_baud + 1;
clk_flanco <= '0';
else
clk_baud <= 0;

--Pone clk_flanco a '1' en el desborde


clk_flanco <= '1';
end if;
else
clk_flanco <= '0';
clk_baud <= 0;
end if;
end if;
end process;

--Mquina de estados que controla transmisin de 1 BYTE

TRANSMICION: process(CLK)

begin

if rising_edge(CLK) then

if tx_maquina = 0 then

TX <= '1';

clk_tx_ini <= '0';

tx_n <= 0;

17
TX_FIN <= '0';

--Para iniciar la transmisin, debemos poner TX_INI a


'1' manualmente o a travs

--de otro modulo

if TX_INI = '1' then

tx_maquina <= 1;

--Cuando se pone TX_INI a '1', se carga la


informacin que se necesita enviar en

--tx_data usando el puerto DATAIN

tx_data <= DATAIN ;

else

tx_maquina <= 0;

tx_data <= "00000000";

end if;

elsif tx_maquina = 1 then

--Hace TX = '0', es decir, es el bit de inicio. Tambin


inicia el reloj para BAUDIOS

--de transmisin

TX <= '0';

clk_tx_ini <= '1';

tx_maquina <= 2;

elsif tx_maquina = 2 then

--El reloj de BAUDIOS indica cuando se ha enviado un


bit completo. Cuando este bit

--ha sido enviado, entonces se carga en TX el siguiente


bit usando la instruccin

--TX <= tx_data(0) y se pasa al estado 3

if clk_tx_flanco = '1' then

tx_maquina <= 3 ;

TX <=tx_data(0);

18
else

tx_maquina <= 2;

end if;

elsif tx_maquina = 3 then

--Se usa un registro de corrimiento para recorrer la


inforamcion del registro tx_data.

--Tx_data2 es un registro auxiliar que recibe la


informacin recorrida un lugar a la

--derecha. Antes de recorrer la informacion se compara


tx_n para saber cuantos bits

--ya se han enviado.

if tx_n < 9 then

tx_n <= tx_n + 1;

tx_data2 <= '1' & tx_data(7 downto 1);

tx_maquina <= 4;

--SI ya se envio el bit de paro, entonces la mquina de


estados se va al ltimo estado

else

tx_maquina <= 5;

end if;

elsif tx_maquina = 4 then

--Si an no se han enviado los 10 bits (8 de informacin,


1 de inicio y 1 de paro) entonces

--actualiza el registr tx_data con el valor de tx_data2


(que tiene la informacin recorrida

--un lugar a la derecha) y regresa al estado 2

tx_data <= tx_data2;

tx_maquina <= 2;

else

19
--Si ya esta en el ltimo estado, espera a que pongamos
TX_INI a '0' antes de regresar al

--estado inicial. Eso ha sido implementado como


proteccin contra posibles colisiones

--de BYTES

if TX_INI = '1' then

TX_FIN <= '1' ;

tx_maquina <= 5 ;

else

TX_FIN <= '0' ;

tx_maquina <= 0;

end if;

end if;

end if;

end process;

--RELOJ DE BAUDIOS PARA TRANSMISIN

process(CLK)
begin
if rising_edge(CLK) then
if clk_tx_ini = '1' then
if clk_tx_baud < (BAUD_FPGA2-1) then
clk_tx_baud <= clk_tx_baud + 1;
clk_tx_flanco <= '0';
else
clk_tx_baud <= 0;

--Pone clk_tx_flanco en el desborde


clk_tx_flanco <= '1';
end if;
else
clk_tx_flanco <= '0';
clk_tx_baud <= 0;
end if;
end if;
end process;

20
end Behavioral;

• Archivo de restricción de usuario (.ucf):


//MEXILOGICS
//Archivo de reestricciones de usuario (UCF)//

##Clock signal
Net "clk" LOC = E7 | IOSTANDARD=LVCMOS33;
#Net "clk" TNM_NET = sys_clk_pin;
#TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;

##TX
Net "tx" LOC = E15 | IOSTANDARD=LVCMOS33;

#SWITCHES
Net "switches<0>" LOC = F15 | IOSTANDARD = LVCMOS33; #D1
Net "switches<1>" LOC = D15 | IOSTANDARD = LVCMOS33; #D2
Net "switches<2>" LOC = B15 | IOSTANDARD = LVCMOS33; #D3
Net "SWitches<3>" LOC = B13 | IOSTANDARD = LVCMOS33; #D4
Net "SWitches<4>" LOC = A11 | IOSTANDARD = LVCMOS33; #D5
Net "SWitches<5>" LOC = C9 | IOSTANDARD = LVCMOS33; #D6
Net "SWitches<6>" LOC = A8 | IOSTANDARD = LVCMOS33; #D7
Net "SWitches<7>" LOC = C6 | IOSTANDARD = LVCMOS33; #D8

Para el receptor (ver figura 12): Este proyecto contiene un programa


principal (SLAVE) en el cual se utilizó una máquina de estados para
monitorear los bits de fin e inicio de transmisión de datos, en este caso, la
etapa recibe se queda en reposo mientras el bit de inicio esté bajo, cuando
cambie a un nivel alto se realiza la asignación de datos en el estado Muestra
(ver figura 13). Adicionalmente, con los datos recibidos se incluyen
contadores que se acumulan por cada vez que se presione un botón, lo cual
será útil para controlar los servomotores y su posición, se incluyen límites Figura 12.- Archivos del
en los contadores para proteger los mecanismos del brazo y los proyecto para la FPGA
servomotores, finalmente se cuenta con el divisor de reloj que cuenta los Esclava
20ms que necesita para comparar el servomotor y asignar la posición según
el rango regresado por el módulo siguiente , el archivo de restricciones AMIBA 2.ucf y los
siguientes componentes:
• U1-RS232.vhd
• U2-Servo_pos.vhd : Con los contadores del programa SLAVE, este módulo
compara la posición enviada en 20ms, con los límites calculados se asigna el offset
y se regresa el pwm adecuado para la posición del servomotor. Esta misma función
cumplen los componentes U3, U4 y U5 para los servomotores del brazo robótico
• U3-Servo_pos.vhd
• U4-Servo_pos.vhd
• U5-Servo_pos.vhd

21
• U6-DIV_CLK.vhd : divisor de reloj para que los datos puedan ser apreciados en el
display.
• U7-Display_result.vhd : muestra el tipo de movimiento que se está realizando en
displays de 7 segmentos

Figura 13.- Máquina de estados


para la FPGA Esclava

• Código TOP SLAVE R


----------------------------------------------------------------------
------------
--MEXILOGICS: CÓDIGO PARA LEER UN RECEPTOR DE UN MÓDULO DE 433 MHZ, LO
QUE PERMITE EL CONTROL DE
--UN BRAZO ROBÓTICO DE 4 GRADOS DE LIBERTAD EMPLEANDO SERVOMOTORES
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;

entity SLAVE_R is
port(
CLK: in STD_LOGIC; --RELOJ
LEDS: out STD_LOGIC_VECTOR (7 downto 0); --MUESTRA DE LECTURA
DOF1,DOF2,DOF3,DOF4: out std_logic; --CONTROL DE SERVOMOTORES
RX: in STD_LOGIC; --INGRESO DE DATOS DEL RECEPTOR
ANode,dsply: out std_logic_vector (7 downto 0); --CONEXIÓN A
DISPLAY DE 7 SEG
);

22
end SLAVE_R;

architecture Behavioral of SLAVE_R is

signal tx_in_s,rx_in_s: std_logic; --CONTROL DE DATOS DEL EMISOR


signal tx_fin_s,tx: std_logic;
signal datain_s,dout_s: std_logic_vector (7 downto 0);
signal asigna_led: std_logic_vector (7 downto 0);
signal clk_out,clk_lento: std_logic;
signal counter: integer range 0 to 277 := 0;
signal counter2: integer range 0 to 600_000;
signal pos1,pos2,pos3,pos4: std_logic_vector (6 downto 0) :=
"0000000";
signal sal_400Hz: std_logic;

-- SYMBOLIC ENCODED state machine: Sreg0


type Sreg0_type is (
RECIBE, MUESTRA
);
-- attribute enum_encoding of Sreg0_type: type is ... -- enum_encoding
attribute is not supported for symbolic encoding

signal Sreg0, NextState_Sreg0: Sreg0_type;

-- Declarations of pre-registered internal signals


--COMUNICACIÓN RS232 PARA EL TRANSMISOR Y RECEPTOR
component RS232 is
generic ( FPGA_CLK : integer := 50000000;
BAUD_RS232 : integer := 9600
);
port( CLK : in std_logic;
RX : in std_logic;
TX_INI : in std_logic;
DATAIN : in std_logic_vector(7 downto 0);
TX_FIN : out std_logic;
TX : out std_logic;
RX_IN : out std_logic;
DOUT : out std_logic_vector(7 downto 0)
);
end component RS232;

begin

--DECLARACIÓN DEL COMPONENTE DE COMUNICACIÓN RS232 CON LOS DATOS


ADECUADOS
--PARA EL MÓDULO SELECCIONADO
u1 : rs232 generic map(
FPGA_CLK => 433_000_000,
BAUD_RS232 => 2400
)
port map( CLK => CLK,

23
RX => RX,
TX_INI => tx_in_s,
TX_FIN => tx_fin_s,
TX => TX,
RX_IN => rx_in_s,
DATAIN => datain_s,
DOUT => dout_s
);

--LOS SIGUIENTES COMPONENTES CONTROLAN LA POSICIÓN INDIVIDUALMENTE DE


CADA
--SERVOMOTOR
u2: entity work.Servo_pos port map(
clk => clk_out,
posi => pos1,
servo => dof1
);

u3: entity work.Servo_pos port map(


clk => clk_out,
posi => pos2,
servo => dof2
);

u4: entity work.Servo_pos port map(


clk => clk_out,
posi => pos3,
servo => dof3
);

u5: entity work.Servo_pos port map(


clk => clk_out,
posi => pos4,
servo => dof4
);

u6: entity work.DIV_CLK port map(


clk => clk,
SAL_400Hz => SAL_400Hz
);

--SE MUESTRA EN EL DISPLAY LA ACCIÓN REALIZADA


u7: entity work.Display_result port map(
SELEC => asigna_led,
SAL_400Hz => SAL_400Hz, --A seal de reloj U4
DISPLAY => dsply, --A segmentos de display
AN => ANode --A nodos del display
);

--MÁQUINA DE ESTADOS QUE CONTROLA LA COMUNICACIÓN RS232


----------------------------------------------------------------------
-- Machine: Sreg0
----------------------------------------------------------------------

24
------------------------------------
-- Next State Logic (combinatorial)
------------------------------------
Sreg0_NextState: process (Sreg0)
begin
NextState_Sreg0 <= Sreg0;
-- Set default values for outputs and signals
-- ...
case Sreg0 is
when RECIBE =>
if RX_IN_S = '1' then
NextState_Sreg0 <= MUESTRA;
elsif RX_IN_S = '0' then
NextState_Sreg0 <= RECIBE;
end if;
when MUESTRA =>
asigna_led <= DOUT_S;
NextState_Sreg0 <= RECIBE;
--vhdl_cover_off
when others =>
null;
--vhdl_cover_on
end case;
end process;

------------------------------------
-- Current State Logic (sequential)
------------------------------------
Sreg0_CurrentState: process (clk)
begin
if clk'event and clk = '1' then
Sreg0 <= NextState_Sreg0;
end if;
end process;

--DIVISOR DE FRECUENCIA PARA EL SERVOMOTOR


freq_divider: process(clk) begin
if rising_edge(clk) then
if counter = 277 then
clk_out <= not clk_out;
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
end process;

--DIVISOR DE FRECUENCIA PARA EL MOVIMIENTO DEL BRAZO


divider: process(clk) begin
if rising_edge(clk) then
if counter2 = 600_000 then
clk_lento <= not clk_lento;
counter2 <= 0;

25
else
counter2 <= counter2 + 1;
end if;
end if;
end process;

--CONTROLADOR DE LA POSICIÓN DE LOS SERVOMOTORES DELIMITANDO SUS


MÁXIMOS Y MÍNIMOC
process(clk_lento, asigna_led,pos1,pos2) begin
if clk_lento'event and clk_lento = '1' then --Actualizacin de
la posicin
if pos1 = x"7E" then --Si llega a su mximo no se puede
mover
if asigna_led(0) = '1' then
pos1 <= pos1;
elsif asigna_led(1) = '1' then
pos1 <= pos1 - '1';
end if;
elsif pos1 = x"01" then --Si llega a su mnimo no se
puede mover
if asigna_led(0) = '1' then
pos1 <= pos1 + '1';
elsif asigna_led(1) = '1' then
pos1 <= pos1;
end if;
else
if asigna_led(0) = '1' then --Al presionar el
botn se incrementa la posicin
pos1 <= pos1 + '1';
elsif asigna_led(1) = '1' then --Se decrementa
al presionar el otro botn
pos1 <= pos1 - '1';
end if;
end if;

if pos2 = x"7E" then


if asigna_led(2) = '1' then
pos2 <= pos2;
elsif asigna_led(3) = '1' then
pos2 <= pos2 - '1';
end if;
elsif pos2 = x"01" then
if asigna_led(2) = '1' then
pos2 <= pos2 + '1';
elsif asigna_led(3) = '1' then
pos2 <= pos2;
end if;
else
if asigna_led(2) = '1' then
pos2 <= pos2 + '1';
elsif asigna_led(3) = '1' then
pos2 <= pos2 - '1';
end if;
end if;

26
if pos3 = x"7E" then
if asigna_led(4) = '1' then
pos3 <= pos3;
elsif asigna_led(5) = '1' then
pos3 <= pos3 - '1';
end if;
elsif pos3 = x"01" then
if asigna_led(4) = '1' then
pos3 <= pos3 + '1';
elsif asigna_led(5) = '1' then
pos3 <= pos3;
end if;
else
if asigna_led(4) = '1' then
pos3 <= pos3 + '1';
elsif asigna_led(5) = '1' then
pos3 <= pos3 - '1';
end if;
end if;

if pos4 = x"7E" then


if asigna_led(6) = '1' then
pos4 <= pos4;
elsif asigna_led(7) = '1' then
pos4 <= pos4 - '1';
end if;
elsif pos4 = x"01" then
if asigna_led(6) = '1' then
pos4 <= pos4 + '1';
elsif asigna_led(7) = '1' then
pos4 <= pos4;
end if;
else
if asigna_led(6) = '1' then
pos4 <= pos4 + '1';
elsif asigna_led(7) = '1' then
pos4 <= pos4 - '1';
end if;
end if;

end if;
end process;

leds <= asigna_led; --ASIGNACIÓN DE LOS DATOS TRANSMITIDOS A UNOS LEDS


PARA VERIFICAR
--EL FUNCIONAMIENTO

end Behavioral;

• Componente U1: RS232


----------------------------------------------------------------------
------------

27
-- MEXILOGICS: CONTROL POR PROTOCOLO RS232 UTILIZANDO LA LIBRERÍA DE
INTESC
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity RS232 is

--El generic es til cuando RS232 es parte de un TOP. SI no es parte de


un TOP

--entonces se deben poner tanto la frecuencia del FPGA como los


BAUDIOS como valores

--contantes en el generic

generic ( FPGA_CLK : INTEGER := 50000000; --


FRECUENCIA DEL FPGA POR EJEMPLO 50000000

BAUD_RS232 : INTEGER := 9600


--BAUDIOS. POR EJEMPLO 9600

);
port ( CLK : in std_logic ; --Reloj de
FPGA
RX : in std_logic ;
--Pin de recepcin de RS232

TX_INI : in std_logic ;
--Debe ponerse a '1' para inciar transmisin

TX_FIN : out std_logic ;


--Se pone '1' cuando termina la transmisin
TX : out std_logic ;
--Pin de transmisin de RS232

RX_IN : out std_logic ; --Se


pone a '1' cuando se ha recibido un Byte. Solo dura un

--Ciclo de reloj

DATAIN : in std_logic_vector(7
downto 0); --Puerto de datos de entrada para transmisin
DOUT : out std_logic_vector(7 downto 0)
--Puerto de datos de salida para recepcin
);
end RS232;

architecture Behavioral of RS232 is

28
CONSTANT FPGA_CLK2 : INTEGER := FPGA_CLK;

CONSTANT BAUD_RS2322 : INTEGER := BAUD_RS232 ;

CONSTANT BAUD_FPGA2 : INTEGER :=


FPGA_CLK2/BAUD_RS2322 ;
CONSTANT CLKBAUD2 : INTEGER := BAUD_FPGA2/2 ;

signal flanco_bajada : std_logic := '0';


signal clk_ini : std_logic := '0';

signal clk_tx_ini : std_logic := '0';


signal clk_flanco : std_logic := '0';

signal clk_tx_flanco : std_logic := '0';


signal rx_vector : std_logic_vector(4 downto
0) ;
signal rx_vector2 : std_logic_vector(4 downto
0) ;

signal tx_data : std_logic_vector(7


downto 0) ;

signal tx_data2 : std_logic_vector(7


downto 0) ;

signal dout_paralelo : std_logic_vector(9 downto


0) ;
signal clk_baud : natural range 0 to
CLKBAUD2 - 1;

signal clk_tx_baud : natural range 0 to


BAUD_FPGA2 - 1;
signal paralelo_paso : natural range 0 to 6 := 0
;

signal tx_maquina : natural range 0 to 6 := 0


;
signal n : natural
range 0 to 10 := 0 ;

signal tx_n : natural range 0 to


10 := 0 ;

begin

--Registro de corrimiento que muestrea RX en busca de condicion de


INICIO
rx_vector <= rx_vector2(3 downto 0) & RX;

process(CLK)

29
begin
if rising_edge(CLK) then
rx_vector2 <= rx_vector;
end if;
end process;

----------------------------------------------

--Genera un flanco de bajada siempre que la condicion "1100" sea


cierta
flanco_bajada <= '1' when rx_vector(4 downto 1) = "1100" else
'0';

--Maquina de estados que controla la rececion de 1 byte

RECEPCION: process(CLK)
begin
if rising_edge(CLK) then
if paralelo_paso = 0 then
n <= 0;

--Si hay un flanco de bajada en el estado 0 se debe a


una condicion de inicio
if flanco_bajada = '1' then
paralelo_paso <= 1;
else
paralelo_paso <= 0;
end if;

RX_IN <= '0';


elsif paralelo_paso = 1 then

--Inicia reloj de BAUDIOS


clk_ini <= '1';
paralelo_paso <= 2;
elsif paralelo_paso = 2 then

--Este flanco indica la mitad del bit de inicio


if clk_flanco = '1' then
paralelo_paso <= 5 ;
else
paralelo_paso <= 2;
end if;
elsif paralelo_paso = 3 then

--Si hay un flanco, quiere decir que ha terminado un


bit e inicia

--el siguiente
if clk_flanco = '1' then
paralelo_paso <= 4;
else

30
--SI no hay flanco, esta condicin indica la
salida y el trmino de la

--recepcion
if n < 10 then
paralelo_paso <= 3;
else
n <= 10;
paralelo_paso <= 6;
end if;
end if;
elsif paralelo_paso = 4 then

--Si hay un flanco, entonces indica que se encuentra en


medio de la recepcion

--y debe ir al paso cinco para incremntar "n"


if clk_flanco = '1' then
paralelo_paso <= 5 ;
else
paralelo_paso <= 4;
end if;
elsif paralelo_paso = 5 then

--Recibe bit a bit la informacin de entrada. "n" debe


contar hasta 8
n <= n + 1 ;
dout_paralelo(n) <= RX ;
paralelo_paso <= 3;
else

--En este ltimo paso, termina la recepcin y pone a un


la bandera RX_IN indicando

--que se ha recibido el BYTE y regresa al paso 0


(esperando otra recepcin)
DOUT<= dout_paralelo(8 downto 1);
clk_ini <= '0';
n <= 0;
paralelo_paso <= 0;

RX_IN <= '1';


end if;
end if;
end process;

--Reloj con frecuencia de BAUDIOS/2 para entrada. Siempre que termina,


enva un flanco en

--clk_flanco
process(CLK)
begin
if rising_edge(CLK) then

31
if clk_ini = '1' then
if clk_baud < (CLKBAUD2-1) then
clk_baud <= clk_baud + 1;
clk_flanco <= '0';
else
clk_baud <= 0;

--Pone clk_flanco a '1' en el desborde


clk_flanco <= '1';
end if;
else
clk_flanco <= '0';
clk_baud <= 0;
end if;
end if;
end process;

--Mquina de estados que controla transmisin de 1 BYTE

TRANSMICION: process(CLK)

begin

if rising_edge(CLK) then

if tx_maquina = 0 then

TX <= '1';

clk_tx_ini <= '0';

tx_n <= 0;

TX_FIN <= '0';

--Para iniciar la transmisin, debemos poner TX_INI a


'1' manualmente o a travs

--de otro modulo

if TX_INI = '1' then

tx_maquina <= 1;

--Cuando se pone TX_INI a '1', se carga la


informacin que se necesita enviar en

--tx_data usando el puerto DATAIN

tx_data <= DATAIN ;

else

32
tx_maquina <= 0;

tx_data <= "00000000";

end if;

elsif tx_maquina = 1 then

--Hace TX = '0', es decir, es el bit de inicio. Tambin


inicia el reloj para BAUDIOS

--de transmisin

TX <= '0';

clk_tx_ini <= '1';

tx_maquina <= 2;

elsif tx_maquina = 2 then

--El reloj de BAUDIOS indica cuando se ha enviado un


bit completo. Cuando este bit

--ha sido enviado, entonces se carga en TX el siguiente


bit usando la instruccin

--TX <= tx_data(0) y se pasa al estado 3

if clk_tx_flanco = '1' then

tx_maquina <= 3 ;

TX <=tx_data(0);

else

tx_maquina <= 2;

end if;

elsif tx_maquina = 3 then

--Se usa un registro de corrimiento para recorrer la


inforamcion del registro tx_data.

--Tx_data2 es un registro auxiliar que recibe la


informacin recorrida un lugar a la

--derecha. Antes de recorrer la informacion se compara


tx_n para saber cuantos bits

--ya se han enviado.

33
if tx_n < 9 then

tx_n <= tx_n + 1;

tx_data2 <= '1' & tx_data(7 downto 1);

tx_maquina <= 4;

--SI ya se envio el bit de paro, entonces la mquina de


estados se va al ltimo estado

else

tx_maquina <= 5;

end if;

elsif tx_maquina = 4 then

--Si an no se han enviado los 10 bits (8 de informacin,


1 de inicio y 1 de paro) entonces

--actualiza el registr tx_data con el valor de tx_data2


(que tiene la informacin recorrida

--un lugar a la derecha) y regresa al estado 2

tx_data <= tx_data2;

tx_maquina <= 2;

else

--Si ya esta en el ltimo estado, espera a que pongamos


TX_INI a '0' antes de regresar al

--estado inicial. Eso ha sido implementado como


proteccin contra posibles colisiones

--de BYTES

if TX_INI = '1' then

TX_FIN <= '1' ;

tx_maquina <= 5 ;

else

TX_FIN <= '0' ;

tx_maquina <= 0;

end if;

34
end if;

end if;

end process;

--RELOJ DE BAUDIOS PARA TRANSMISIN

process(CLK)
begin
if rising_edge(CLK) then
if clk_tx_ini = '1' then
if clk_tx_baud < (BAUD_FPGA2-1) then
clk_tx_baud <= clk_tx_baud + 1;
clk_tx_flanco <= '0';
else
clk_tx_baud <= 0;

--Pone clk_tx_flanco en el desborde


clk_tx_flanco <= '1';
end if;
else
clk_tx_flanco <= '0';
clk_tx_baud <= 0;
end if;
end if;
end process;

end Behavioral;

• Componentes U2, U3, U4 y U5: Servo_pos

----------------------------------------------------------------------
------------
-- MEXILOGICS: CONTROL DE SERVOMOTOR SG90 EL CUAL CUENTA CON 90 GRADOS
DE MOVIMIENTO
-- SE COMPARA EN UN TIEMPO DE 20MS PARA DAR LA SEÑAL
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Servo_pos is
port (
clk: in std_logic;
posi: in std_logic_vector (6 downto 0); --POSICIÓN MÁXIMA DE
180
servo: out std_logic
);

35
end Servo_pos;

architecture Behavioral of Servo_pos is

signal cnt: unsigned(11 downto 0);


signal pos_comp: std_logic_vector(6 downto 0);
signal pwmi: unsigned(7 downto 0);

begin

pos_comp <= "1011010" when unsigned(posi) > "1011010" else posi; --SI
EXCEDE LOS 90 GRADOS SE QUEDA EN ESE VALOR
pwmi <= unsigned('0' & pos_comp) + 90; --SI NO EXCEDE 90 GRADOS
ENTONCES MODIFICA LA POSICIÓN

counter: process(clk) begin --CONTROL DEL PWM PARA DAR LOS VALORES QUE
SE COMPARAN EN 2O MS
if rising_edge(clk) then
if cnt = 1799 then --CONTADOR PARA LOS 90 GRADOS
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
end if;
end process;

servo <= '1' when (cnt < pwmi) else '0'; --ASIGNACIÓN DEL PWM A LA
SALIDA

end Behavioral;

• Componente U6: DIV_CLK


----------------------------------------------------------------------
------------
--MEXILOGICS
--DIVISOR DE 2.5ms
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.STD_LOGIC_arith.ALL;

--Declaracin de entidad
entity DIV_CLK is
port(
clk: in std_logic; --reloj de 50MHz
SAL_400Hz: inout std_logic --salida 2.5ms
);
end DIV_CLK;

----------------------------------------------------------------------
------------

36
--Declaracin de la arquitectura
architecture Behavioral of DIV_CLK is
--Declaracin de seales de divisores
signal conta_1250us : integer range 1 to 62_500 := 1; --pulso de 1250
us@400Hz (0.25ms)

begin
--Divisor 2.5ms = 400Hz
--Divisor nodos
process(clk) begin
if rising_edge(clk) then
if(conta_1250us = 62_500) then --cuenta 1250us (50MHz = 62500)
SAL_400Hz <= not(SAL_400Hz); --Genera un barrido de 2.5ms
conta_1250us <= 1;

else conta_1250us <= conta_1250us + 1;


end if;
end if;
end process; --Fin del proceso divisor de nodos

----------------------------------------------------------------------
------------
--fin de la arquitectura
end Behavioral;

• Componente U7: Display Result


----------------------------------------------------------------------
------------
-- MEXILOGICS: CONTROL DE DISPLAYS DE 7 SEGMENTOS
-- SEGÚN EL MOVIMIENTO DEL BRAZO
----------------------------------------------------------------------
------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;

entity Display_result is
Port(

selec: in std_logic_vector (7 downto 0); --U-D-C-M


SAL_400Hz : in std_logic; --Reloj de 400Hz

DISPLAY : out STD_LOGIC_VECTOR(7 downto 0); --segmentos del


display

AN : out std_logic_vector (7 downto 0) --nodos del display

);
end Display_result;

architecture Behavioral of Display_result is

37
-- Declaracin de seales de la multiplexacin y asignacin de U-D-C al
disp

signal SEL: std_logic_vector (1 downto 0):="00"; -- selector de


barrido
signal D: std_logic_vector (3 downto 0); -- almacena los valores del
disp
begin
PROCESS(SAL_400Hz, sel,selec)
BEGIN
IF SAL_400Hz'EVENT and SAL_400Hz='1' THEN SEL <= SEL + '1';
CASE(SEL) IS
when "00" => AN <="11110111"; DIsplay <= x"00";
when "01" => AN <="11111011";
if selec(0) = '1' or selec(2) =
'1' then display <= "11000011"; --SUBIR
elsif selec(1) = '1' or
selec(3)='1' then display <= "10001111"; --BAJAR
elsif selec(4) = '1' or selec(5)
= '1' then display <= "11100001"; --ROTAR
elsif selec(6) = '1' or selec(7)
= '1' then display <= "00110001"; --GRIPPER
end if;
when "10" => AN <="11111101";
if selec(0) = '1' or selec(2) =
'1' then display <= "11000111";
elsif selec(1) = '1' or
selec(3)='1' then display <= "00010001";
elsif selec(4) = '1' or selec(5)
= '1' then display <= "00000011";
elsif selec(6) = '1' or selec(7)
= '1' then display <= "11110101";
end if;
when "11" => AN <="11111110";
if selec(0) = '1' or selec(2) =
'1' then display <= "01001001";
elsif selec(1) = '1' or
selec(3)='1' then display <= "11000011";
elsif selec(4) = '1' or selec(5)
= '1' then display <= "11110101";
elsif selec(6) = '1' or selec(7)
= '1' then display <= "00001001";
end if;
when others =>AN <="11111111"; display <= x"00"; -- signo
END CASE;
end if;
END PROCESS; -- fin del proceso Multiplexor
end Behavioral;

• Archivo de restricciones de usuario (.ucf):


//MEXILOGICS
//Archivo de reestricciones de usuario (UCF)//

38
##Clock signal
Net "clk" LOC = E7 | IOSTANDARD=LVCMOS33;

//DISPLAYS
Net "dsply<7>" LOC = K13 | IOSTANDARD=LVCMOS33;
Net "dsply<6>" LOC = L15 | IOSTANDARD=LVCMOS33;
Net "dsply<5>" LOC = M15 | IOSTANDARD=LVCMOS33;
Net "dsply<4>" LOC = P15 | IOSTANDARD=LVCMOS33;
Net "dsply<3>" LOC = P14 | IOSTANDARD=LVCMOS33;
Net "dsply<2>" LOC = K15 | IOSTANDARD=LVCMOS33;
Net "dsply<1>" LOC = L14 | IOSTANDARD=LVCMOS33;
Net "dsply<0>" LOC = N15 | IOSTANDARD=LVCMOS33;

//ANODOS
Net "anode<7>" LOC = K12 | IOSTANDARD=LVCMOS33;
Net "anode<6>" LOC = J13 | IOSTANDARD=LVCMOS33;
Net "anode<5>" LOC = K11 | IOSTANDARD=LVCMOS33;
Net "anode<4>" LOC = H13 | IOSTANDARD=LVCMOS33;
Net "anode<3>" LOC = G13 | IOSTANDARD=LVCMOS33;
Net "anode<2>" LOC = H12 | IOSTANDARD=LVCMOS33;
Net "anode<1>" LOC = F13 | IOSTANDARD=LVCMOS33;
Net "anode<0>" LOC = G12 | IOSTANDARD=LVCMOS33;

Net "rx" LOC = F15 | IOSTANDARD=LVCMOS33;


Net "limit" LOC = D15 | IOSTANDARD=LVCMOS33;
Net "dof1" LOC = E15 | IOSTANDARD=LVCMOS33;
Net "dof2" LOC = C15 | IOSTANDARD=LVCMOS33;
Net "dof3" LOC = B14 | IOSTANDARD=LVCMOS33;
Net "dof4" LOC = A12 | IOSTANDARD=LVCMOS33;

##LED VERDES
Net "leds<7>" LOC = N1 | IOSTANDARD=LVCMOS33;
Net "leds<6>" LOC = R4 | IOSTANDARD=LVCMOS33;
Net "leds<5>" LOC = P7 | IOSTANDARD=LVCMOS33;
Net "leds<4>" LOC = R9 | IOSTANDARD=LVCMOS33;
Net "leds<3>" LOC = P13 | IOSTANDARD=LVCMOS33;
Net "leds<2>" LOC = M4 | IOSTANDARD=LVCMOS33;
Net "leds<1>" LOC = M6 | IOSTANDARD=LVCMOS33;
Net "leds<0>" LOC = M11 | IOSTANDARD=LVCMOS33;

39
Fotos y video

A continuación, se presentan fotos donde se presentan el control utilizado para el


posicionamiento del brazo robótico (Ver figura 14), así como los elementos físicos que
componen nuestro proyecto (ver figuras 15, 16 y 17). De igual manera se anexa el siguiente
link: https://www.youtube.com/watch?v=eBib8chu30E&ab_channel=BenjaminVarela
donde se explica el funcionamiento de nuestro proyecto.

Figura 14.- Control por pushbutton


en la FPGA master y el grado de
libertad que controla

40
Figura 15.- Módulo transmisor de
433Mhz con antena helicoidal

41
Figura 16.- Brazo robótico de 4
grados de libertad y sus
servomotores

42
Figura 17.- FPGA slave con el
módulo receptor y displays que
indican el movimiento realizado

Conclusiones

Varela Alpizar Benjamin


Se demostró la viabilidad de controlar un sistema robótico utilizando dos tarjetas con FPGA
y comunicación por radiofrecuencia, además este tipo de conexión resulto ser una opción
bastante adecuada para poder crear comunicación entre las dos tarjetas a distancia lo cual es
una gran ventaja, pues elimina la necesidad de usar cables físicos lo que aumenta la movilidad
del sistema, así como su practicidad. Pero hay que tener cuidado con la señal de
radiofrecuencia, pues a veces recibíamos señales de transmisores de otros equipos y a veces
ellos recibían las nuestras.
Mata Prieto Varush
La capacidad de la FPGA para procesar datos en tiempo real y su versatilidad programable
han sido fundamentales en el desarrollo de este sistema. Esto nos ha permitido personalizar

43
y adaptar el control del brazo robótico según nuestras necesidades específicas, brindándonos
una experiencia de usuario optimizada. La integración de módulos de radiofrecuencia ha
eliminado las limitaciones físicas de los cables, permitiendo una libertad de movimiento sin
restricciones. Esto ha abierto nuevas posibilidades en términos de alcance y flexibilidad de
uso del brazo robótico, ya que ahora podemos controlarlo desde una distancia considerable.
Además, el control intuitivo y la retroalimentación en tiempo real que proporciona este
sistema nos han brindado un mayor grado de precisión y seguridad en nuestras operaciones.
La capacidad de controlar el brazo robótico de forma remota nos ha permitido realizar tareas
complejas y delicadas con mayor facilidad y confianza.
Galván Escobar Adrián Raúl
El desarrollo de este sistema me permitió comprender el algoritmo necesario para la
transmisión serial de datos, ya que tanto el receptor como el emisor deben de trabajar a
determinada frecuencia. Asimismo, la implementación del PWM (modulación por ancho de
pulso) nos permitió el control del desplazamiento de los servomotores.
Una de las principales características que resalto del proyecto es que con el uso de los
módulos de radiofrecuencia ya no hubo necesidad del uso de cableado para este sistema. Por
otro lado, para el diseño de sistemas que involucren componentes que tendrán que soportar
cargas o esfuerzos es importante considerar que función realizara cada componente, dado
que, para el caso de este proyecto, se tuvo que tener una mayor consideración en los
servomotores encargados de la rotación y el agarre de las piezas, ya que estos deben de ejercer
más fuerza (para el caso del servomotor de agarre) o deben de soportar más peso (para el
caso del servomotor de la base de nuestro brazo robótico).

Fuentes bibliográficas

[1] Okdiario. (2018, 25 de marzo). Como se calcula la longitud de onda.


https://okdiario.com/howto/como-calcular-longitud-onda-2016766
[2] Admin. (2020, 24 de febrero). FS1000A 433MHZ RF transmitter & XY-MK-5V
Receiver Module Explanation, Pinout. https://www.componentsinfo.com/fs1000a-433mhz-
rf-transmitter-xy-mk-5v-receiver-module-explanation-pinout/
[3] INTESC. (2021). ManualAmiba2RevC. [Archivo PDF]. https://intesc.mx/wp-
content/uploads/2021/08/ManualAmiba2RevC.pdf
[4] UNIT electronics (s.f.). Antena Helicoidal 433 [MHz] de cobre.
https://uelectronics.com/producto/antena-helicoidal-433mhz-de-cobre/
[5] DatasheetsPDF.com. (s.f.). SG90 Datasheet, Equivalent, Micro Servo.
https://datasheetspdf.com/pdf/791970/TowerPro/SG90/1
[6] Unknown. (s.f.). SERVO MOTOR SG90 DATA SHEET. [Archivo PDF].
https://intesc.mx/wp-content/uploads/2021/08/ManualAmiba2RevC.pdf

44
[7] [20:39, 16/6/2023] +52 1 55 3412 6050: INTESC. (2021a, julio 30). Librería RS232 -
INTESC. https://intesc.mx/libreria-rs232/
[8] Del Valle Hernández, L. (2021, 4 mayo). Tutorial RF 433 MHz con Arduino.
Programar fácil con Arduino. https://programarfacil.com/blog/arduino-blog/rf-433-mhz-
arduino-fs1000a/

45

También podría gustarte