Avanxe 7 – Aplicación 2: FTDI

Proyecto demostrativo en donde se realiza comunicación serial RS232 utilizando el FTDI integrado en Avanxe 7.

El demo consiste en dos partes, la primera realiza recepción de datos, los cuales son utilizados para especificar el color que se muestra en un LED RGB con protocolo OneWire, se utiliza una aplicación en C# para enviar la información. Para la la segunda parte que es transmisión, se mandarán datos que genere un contador en el FPGA.

El siguiente esquema representa la estructura del proyecto.

LED RGB WS2812B

El LED WS2812B opera con un protocolo serial unidireccional muy parecido al 1-wire. Consiste en determinar el tiempo que  el pulso permanece en alto y dependiendo de ese tiempo se considera como un ‘0’ o ‘1’ logico.

Los tiempos del WS2812B son los siguientes:

El periodo se mantiene constante de 1.25 microsegundos. Para que el bit sea considerado ‘0’ lógico el tiempo en alto de la señal es de 0.35 microsegundos y para un ‘1’ lógico el tiempo en alto es de 0.9 microsegundos.

El código en VHDL crea la señal de control a partir de contadores generando los tiempos mostrados en la imagen anterior.

Para la comunicación entre la aplicación y el FPGA se utilizó el protocolo RS232 que cuenta con las siguientes características:

  • Velocidad de transferencia a 3 Megabaudios.
  • 1 bit de inicio
  • 8 bits de datos.
  • 1 bit de paro.
  • Sin paridad.

Recepción de datos.

En la recepción, el FPGA cuenta con una máquina de estados de tres estados en donde se reciben los tres bytes de los tres colores.

Se utilizó la librería RS232 la cual cuenta con una bandera llamada RX_IN,  la cual se activa cuando se haya recibido un byte y también indica cuando el dato es válido en el puerto DOUT.

Los datos los manda la aplicación en C# la cual obtiene los colores de una imagen y manda 24 bits en formato RGB (8 bits para cada color), el FPGA recibe la información y la procesa para mandarlos al led WS2812B.

             

El código en C# cuenta con un método para el Picture Box que consiste en realizar una acción en el momento en el que el cursor se posicione encima, es ahí cuando se toma la información de un pixel de la imagen y se envía al FPGA.

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (ok)
            {
                //Obtenemos coordenadas de la imagen
                int x = e.X;
                int y = e.Y;

                // Create a Bitmap object from an image file.
                Bitmap myBitmap = new Bitmap(System.AppDomain.CurrentDomain.BaseDirectory + "color.png");

                // Get the color of a pixel within myBitmap.
                Color pixelColor = myBitmap.GetPixel(x, y);

                //Obtenemos la información de cada color en un rango de 0-255 (0x00-0xFF).
                R = pixelColor.R;
                G = pixelColor.G;
                B = pixelColor.B;

                //Creamos el array de datos y transmitimos los datos.
                byte[] x2 = { (byte)R, (byte)G, (byte)B };
                sp.Write(x2, 0, 3);

                //Mandamos el color seleccionado en pictureBoxColorSel.
                pictureBoxColorSel.BackColor = pixelColor;
            }
        }
    }

 

Transmisión de datos.

Para la transmisión el FPGA genera un contador  y manda un byte con la información del conteo. Para iniciar el conteo se debe recibir un byte sin importar el valor.

En el estado 0 edot = 0 se espera a recibir el byte que iniciará el conteo, en el estado 1 edot = 1 se genera un retardo de medio segundo (el tiempo se puede modificar cambiando el valor de la constante j) incrementando a un contador el cual al llegar al valor de j se hace la transición de estado y se incrementa en 1 el contador principal d. En el estado 2 edot = 2 se envía el valor del contador d.

La aplicación de C# recibe el dato mediante un thread que se ejecuta en segundo plano. El dato recibido se mostrará en la etiqueta lblByte.

public void Metodo()
   {
       //Ciclo infinito, siempre se estarán recibiendo datos
       while (true)
       {
           //Recibimos byte
           int x = main.sp.ReadByte();
           //Mandamos la información recibida en la etiqueta "lblByte"
           main.lblByte.Text = "Byte recibido: " + x.ToString();
       }

   }
Menú