Arduino es el proyecto de hardware de código abierto más exitoso de la historia. Desde su aparición hace ya mas de 10 años, son cientos de miles los aficionados a la electrónica que han puesto en marcha proyectos basados en él.
Arduino es un sistema que basa su éxito en la simplicidad. Todo el entorno de desarrollo está pensado para que gente sin ninguna experiencia en desarrollo con microcontroladores pueda desde el principio crear programas sencillos y hacer que funcionen sin complicaciones.
El éxito de Arduino en ese aspecto es también una de sus debilidades. Cuando se necesitan ejecutar procesos que demandan cierta potencia de calculo Arduino se queda bastante corto. La solución en muchas ocasiones es adquirir sistemas Arduino mas complejos como Arduino Mega o incluso una Rapsberry Pi.
En este tutorial os demostraremos como añadir una potencia de computo mayor a Arduino Uno utilizando para ello una FPGA conectada a través del bus I2C. Nosotros hemos utilizado una FPGA de muy bajo coste de la familia Cyclone II de Altera, pero esto es válido para cualquier otra FPGA de cualquier fabricante.
Con este esquema de conexión podemos utilizar la FPGA para realizar tareas complejas que Arduino no puede ejecutar. Ejemplos de ello pueden ser procesado de video (podemos conectar memorias externas a la FPGA), tareas criptográficas, etc..
En este primer ejemplo utilizaremos una función muy sencilla, ya que el objetivo es simplemente entender el esquema de conexión. La función es tomar la entrada enviada por el bus I2C, sumarle 5 y devolver el resultado para que Arduino lo muestre por el puerto serie.
Diseños más complejos donde se enviar ráfagas de bytes requieren el uso de una infraestructura basada en FIFOs (memorias con estructura de cola de datos), que veremos en próximos tutoriales. En este diseño simplemente almacenaremos el dato enviado en un registro.
Os dejamos el video tutorial donde podéis ver los pasos seguidos y una demostración del sistema funcionando.
El código esclavo del bus I2C que hemos utilizado está tomado de github en el siguiente enlace:
https://github.com/oetr/FPGA-I2C-Slave
El código VHDL que hemos utilizado para conectar el esclavo I2C a los leds de salida y realizar la función deseada (sumar 5 a la entrada) es este que os copiamos a continuación.
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity i2c_leds is port ( scl : inout std_logic; sda : inout std_logic; clk : in std_logic; rst : in std_logic; led_o : out std_logic_vector(7 downto 0) ); end entity; architecture RTL of i2c_leds is signal read_req : std_logic; signal data_to_master : std_logic_vector(7 downto 0); signal data_valid : std_logic; signal data_from_master : std_logic_vector(7 downto 0); signal data_reg : std_logic_vector(7 downto 0); begin i2c_slave0 : entity work.i2cslave(arch) port map(scl,sda,clk,rst, read_req, data_to_master,data_valid,data_from_master); led_o <= data_reg; data_to_master <= data_reg + 5; process(clk) begin if(clk'event and clk='1') then if(data_valid='1') then data_reg <= data_from_master; end if; end if; end process; end architecture;
Este el el código que se ejecuta sobre Arduino, como se puede ver se espera a que se introduzca un número por el puerto serie, se envía por el bus I2C, se espera la respuesta y se muestra por el puerto serie. Podéis verlo en funcionamiento al final del video.
#include <Wire.h> byte in; byte out; void setup(){ Wire.begin(); Serial.begin(9600); } void loop(){ while(!Serial.available()>0){;} in=Serial.read()-'0'; Serial.print("Enviando a la FPGA "); Serial.println(in); Wire.beginTransmission(0x3); Wire.write(in); Wire.endTransmission(); delay(1); Wire.requestFrom(3,1); while(!Wire.available()){;} out=Wire.read(); Serial.print("Recibido de la FPGA "); Serial.println(out,DEC); delay(1000); }
Por último os dejamos una captura de la asignación de los pines de la FPGA. Es muy fácil de seguir ya que en esta placa que utilizamos el número de cada pin esta serigrafiado en la placa. En el video se puede ver como están hechas las conexiones.

Esperamos que os haya gustado este tutorial, si tenéis dudas sobre el funcionamiento del sistema, podéis dejar las dudas en comentarios del blog o en el canal de Youtube.
Hi
I have tryed to reproduce ur experiment from an Arduino due and a FPG Cyclone II, but no communication between them …Nothing happen
Any suggestion ?
Thanks
Hi,
Try to check if Arduino is sending data to the FPGA, can you use an oscilloscope?
Hola que tal estoy tratando de implementar este proyecto en una Zybo Zynq pero el resultado no es exitoso, alguna sugerencia que me pueda dar?
Saludos.
Hola,
El proyecto deberia funcionar solo cambiando la asignacion de pines ya que en la Zybo los pines son diferentes. Lo has cambiado?
porque los archivos de gidhud no son iguales
Porque el que hizo el periferico lo ha cambiado, pero deberia seguir funcionando sin problema.