domingo, 29 de junio de 2014

Introducción a VHDL

Tutorial sobre reducción de funciones lógicas, introducción a la programación en VHDL, la simulación y la implementación de proyectos en VHDL.

 

 

En este primer video se explica el método Quine McCluskey (Método tabulador)para la reducción de funciones lógicas.

 

  • La segunda parte del método de reducción, donde obtenemos nuestra función minimizada
  • La instalación del software Galaxy (Para la programación en VHDL y simulación)
  • La programación en VHDL de nuestra función lógica.

 

 

  • La simulación del programa en VHDL
  • Análisis de los archivos: .rpt, .jed

 

 

 

 

  • Programación de la GAL (Cargar el archivo .jed)
  • Implementación y comprobación

 

 

En el siguiente link se puede descargar el proyecto que se implemento.

Descarga del Proyecto

domingo, 1 de septiembre de 2013

Introducción a xbee

Este es el primer post de xbee de un total de tres. El cual es sobre una descripción e introducción de los módulos xbee bajo y  el estándar al que pertenecen Zigbee (802.15.4).


FIg. 1.  xbee Serie 1



Introducción 

Zigbee es el nombre de la especificación de un conjunto de protocolos de comunicaciones inalámbricas basado en el estándar de comunicaciones para redes inalámbricas de área personal (Wireless personal área network, WPAN) IEEE 802.15.4 Creado por Zigbee Alliance, una organización, teóricamente sin ánimo de lucro.
 Este protocolo trabaja con tecnología inalámbrica para tasas bajas de envió de datos, utiliza banda libre ISM (Industrial, Scientific and Medical) de 2.4 GHz, con una velocidad de transferencia máxima de 250Kbps y distancias de hasta 100 m. Las topologías de red soportada por el estándar son: la topología en estrella y en malla, cada red soporta en teoría hasta 65535 nodos distribuidos en subredes de 255 nodos, con un consumo de energía bajo, permitiendo que dispositivos electrónicos de bajo consumo puedan realizar sus comunicaciones inalámbricas. Es especialmente útil para sensores de entornos industriales, médicos y, sobre todo, domóticas.

Contenido

Los módulos Xbee’s son dispositivos que integran un transmisor-receptor de Zigbee y un procesador del mismo módulo, lo que permite desarrollar aplicaciones de una manera rápida y sencilla. El módulo de la serie 1 está basado en el chipset Fresscale y está pensado para ser utilizado en redes de punto a punto y punto a multipunto.
Entre las redes multipunto las únicas topologías soportadas por el estándar IEEE 802.15.4 son en estrella y malla, Figura 2.

Figura.2 Topologías soportadas por el estándar IEEE 802.15.4.
En la topología estrella se establece con un módulo central, que es el coordinador de la red, llamado coordinador PAN (Network Area Personal). El coordinador puede tener una aplicación específica, pero además, es empleado para inicializar, terminar o encaminar las tramas alrededor de la red.
Todas las comunicaciones se estableen a través del coordinador, es decir, si algún dispositivo necesita comunicarse con otro, la comunicación se realiza a través del coordinador.
Esta característica permite que no existan colisiones entre los paquetes que envía cada dispositivo.
Los dispositivos de una red IEEE 802.15.4 se pueden clasificar de acuerdo al papel que desempeñen en la red:
Coordinador: Se encarga de inicializar una red (PAN ID) y establecer un canal de comunicaciones, envía los paquetes para sincronización (beacons) y pueden servir de enlace con otras redes, también son conocidos como Full-Function Device (FFD).
Router: Sirve como repetidor ya que se encarga del enrutamiento de los paquetes que requieran saltos multiples, también están dentro de la categoría de los FFD.
End- divives: Son los dispositivos más básicos de la red, son los sensores o actuadores de la red y solo se pueden comunicar con un coordinador o router, también son conocidos como Reduced-Function Device (RFD).
El xbee con estado en router, solamente es posible de configurarse en los xbee´s de la serie 2, por el momento solo se abordara los xbee's de la serie 1. 
La arquitectura de IEE 82.15.4  se define en base al modelo OSI (Open Systems Interconnection). 

Conceptos básicos para establecer una comunicación entre los módulos xbee

Para establecer la comunicación del coordinador con los trabajadores(dispositivos finales) se debe crear una red PAN y un canal de comunicación, el protocolo IEEE 802.15.4 dispone de 16 canales, este estándar indica que entre cada canal, deben existir 5MGZ de diferencia, Partiendo de la frecuencia base 2.405 GHz hasta los 2.480 GHz.

Figura 3. Canales disponibles para el protocolo IEEE 802.15.4 
Los módulos xbee proveen dos formas de comunicación:
·         Modo de Transmisión Serial Transparente (modo AT).
·         Modo API a través de tramas.

El modo transparente (AT): es el más sencillo para la transferencia, la comunicación de una transmisión es a través de un puerto serial, ya que el dispositivo crea la trama y el dato pasa por el pin TX del modulo xbee y se envía de forma inalámbrica.

En el modo API: el microcontrolador externo se encarga de crear una trama específica, se suelen utiliza en redes grandes y evitan perder tiempo en la entrada y salida de datos en el Xbee. Se permite el uso de frames, con cabeceras que aseguran la entrega de datos. Toda la información que entra y sale es empaquetada en frames, que definen operaciones y eventos dentro del módulo.

Un frame de transmisión incluye:
·         Frame de información RF transmitida
·         Frame de comando (equivalentes a comando AT).
Un frame de recepción:
·         Frame de información RF recibida
·         Comandos de respuesta
·         Notificaciones de eventos como Reset, Asssociate, Dissociate, etc.
Entre las opciones que permite la API se tiene:
·         Transmitir información a múltiples destinatarios, sin entrar al modo de comandos
·         Recibir estados de éxito/falla de cada paquete RF transmitido
·         Identificar la dirección de origen de cada paquete recibido.
El formato del frame de la API es el siguiente:

FIG. 4 Estructura del frame. Ocupando Dirección de 16 bits

Direccionamiento de los módulos
Los módulos permiten 2 tipos de direccionamiento. La de 16 bit y la de 64 bits. La principal diferencia es que en la de 64 bit, es posible obtener una mayor cantidad de direcciones y por lo tanto, una mayor cantidad de nodos o equipos funcionando en la misma red. Son a través de estas direcciones que los módulos se comunican entre sí. 

Entre las posibilidades que permite la API, está la posibilidad de cambiar parámetros a través de comandos AT, enviados; también es posible consultar el estado de un parámetro en otro modulo o consultar si un módulo es un coordinador.

Los modos de configuración de los xbee son 4:

FIG. 5 Modos de configuración de xbee

Modo transmitir/recibir
Se encuentra en estos modos cuando el modulo le llega algún RF a través de antena (modo Receive ) o cuando se manda información serial al buffer del pin 3 (UART Data in) que después será transmitido.
La información transmitida pueda ser Directa o Indirecta, en el segundo caso la información es retenida durante un periodo de tiempo y es enviada solo cuando la dirección de destino la solicita.

Modo de bajo consumo (sleep Mode)
El modo de sueño hace posible que el modulo RF entre en un modo de bajo consumo de energía cuando se encuentra en uso.

Modo de comando
Este modo permite ingresar comando AT al modulo Xbee, para configurar, ajustar o modificar parámetros. Permite modificar parámetros como la dirección propia o la de destino, así como la operación entre otras cosas.

Idle
Cuando el xbee no se encuentra en ninguno de los otros modos, se encuentra en este. Es decir no se encuentra transmitiendo ni recibiendo información, ni ahorrando energía o configuración.

Con esto terminamos la introducción de los modulos xbee's, el siguiente post tratara de la configuración básica de los módulos xbee's para una red multipunto.


Bibliografía



IEEE Standard 802.15.4-2003, Part 15.4:  Wireless Medium Access  Control (MAC) and Physical Layer (PHY) Specifications for Low-Rate Wireless Personal Area Networks (LR-WPANs), IEEE, October 2003.
Faludi, Robert (2010) Building wireless sensor Network (1 ed.) United States of America:O’Really Media-
]Xbee / Xbee Pro RF Modulos, Digi International INC. (2009): http:// http://www.xbee.cl





domingo, 4 de agosto de 2013

Juego de Ping Pong (Arduino y Processing)

 
En este post les mostrare como hacer un juego de ping pong con Arduino y processing.

Processing lo utilizaremos para la interfaz grafica del juego y Arduino será el controlador por medio de dos potenciómetros y la comunicación mediante Arduino y processing será serialmente.

portada

 

Clase Jugador

Empezaremos por crear una clase en Processing llamda “Jugador” para dibujar los rectángulos (uno para cada jugador) que serán controlados por los potenciómetros. Aquí definimos las propiedades que va tener (largo, ancho, coordenadas, color, puntuación) y las acciones que va realizar (desplazar hacia arriba y abajo). 

El código de la clase “Jugador” se muestra a continuación:

   1:  /*
   2:  *Clase jugador
   3:  *
   4:  *Para crear los cuadrados que se van a manejar por
   5:  *medio de los controles
   6:  *
   7:  */
   8:   
   9:  class Jugador{
  10:   
  11:    int largo;
  12:    int ancho;
  13:    float x,y;
  14:    color c;
  15:    int marcador;
  16:    float velocidad;
  17:   
  18:   //constructor 
  19:   Jugador(float x, float y,color c){
  20:     this.largo = (height-100)/8;
  21:     this.ancho = width/80;
  22:     this.x = x;
  23:     this.c = c;
  24:     this.y = y;
  25:     this.marcador = 0;
  26:     this.velocidad = 7;
  27:   }
  28:   
  29:   //Dibujar el cuadro del jugador
  30:   void display(){
  31:      rectMode(CENTER);
  32:      stroke(10);
  33:      fill(this.c);
  34:      rect(x,y,ancho,largo); 
  35:   }
  36:   
  37:   void Up(){
  38:     if(this.y  > this.largo/2 )
  39:     this.y -=velocidad;
  40:   }
  41:   
  42:   void Down(){
  43:     if(this.y  < (height-100) - this.largo/2 )
  44:     this.y +=velocidad;
  45:   }
  46:     
  47:  }

 


Clase Bola


Después se necesita otra clase para la pelota  y de igual forma describimos sus propiedades ( radio, coordenadas x y, velocidad de la pelota tanto en x como y la cual va a estar variando y el color) y su única acción que va realizar es moverse. 


Las dimensiones tanto de los cuadros como de la pelota se definen en proporción al tamaño de la pantalla, por eso utilizamos las variables del sistema (width y height ).


El método display solo dibuja la pelota usando la figura de un eclipse donde los parámetros que recibe son las coordenadas donde se va a dibujar y la altura y anchura que la definimos como el doble del radio.


Para el método mover se tiene que recibir como parámetro los dos cuadrados para saber las coordenadas  de estos y poder determinar si la pelota tiene que rebotar en alguno de los dos cuadrados (en donde se tendrá que cambiar la dirección de la velocidad de la pelota en el eje x)  o en las paredes que limitan el juego (donde se cambiara la velocidad de la pelota en el eje y).


Para la comparación tanto con los bordes del juego como de los rectángulos respecto a la pelota, se tiene que tener en consideración que las coordenadas de la pelota se toman a partir del centro de esta, por lo tanto, se tiene que sumar el radio de la pelota a su coordenada en el eje x, positivo si es a la derecha y negativo a la izquierda; y en el eje y, positivo si es hacia arriba y negativo si es hacia abajo.  


El código de la clase “Pelota” se muestra a continuación.


   1:  /*
   2:  *Clase Bola
   3:  *
   4:  *Atributos y funciones de la bola
   5:  *Mover, Cambio de direccion, Velocidad
   6:  *
   7:  */
   8:  class Bola {
   9:    
  10:    float r; // radio
  11:    float x,y;
  12:    float xvelocidad,yvelocidad;
  13:    color c = color(0);
  14:    
  15:    // Constructor
  16:    Bola() {
  17:      r = width/50;
  18:      x = width/2;
  19:      y =(height-100)/4;
  20:      xvelocidad = random( -3,3);
  21:      yvelocidad = random( -3,3);
  22:    }
  23:   
  24:    void mover(Jugador jugador1, Jugador jugador2) {
  25:      x += xvelocidad; // Incrementar x
  26:      y += yvelocidad; // Incrementar y
  27:      
  28:      // Checar bordes horizontales para rebote
  29:      if (x > width-r){
  30:        jugador1.marcador++; this.restar();
  31:      }
  32:      if( x < r) {
  33:         jugador2.marcador++; this.restar();
  34:      }
  35:      
  36:      // Checar los bordes verticales para el rebote
  37:      if (y > (height-100)-r || y < r) {
  38:        yvelocidad *=  -1;
  39:      }
  40:      
  41:     
  42:      if( (( jugador1.x + jugador1.ancho/2 > bola.x - bola.r  && jugador1.y-jugador1.largo/2  < bola.y+bola.r ) &&
  43:      ( (jugador1.x + jugador1.ancho/2 > bola.x-bola.r ) && (jugador1.y+jugador1.largo/2 > bola.y-bola.r ) )) ||
  44:        (( jugador2.x -jugador2.ancho/2 < bola.x + bola.r  && jugador2.y-jugador2.largo/2  < bola.y+bola.r ) &&
  45:      ( (jugador2.x - jugador2.ancho/2 < bola.x+bola.r ) && (jugador2.y+jugador2.largo/2 > bola.y-bola.r ) ))){
  46:        xvelocidad *= -1;
  47:      }
  48:      
  49:    }//fin de mover
  50:   
  51:    // Dibujar la bola
  52:    void display() {
  53:      c = color(0);
  54:      stroke(0);
  55:      fill(c);
  56:      ellipse(x,y,r*2,r*2);
  57:      
  58:    }
  59:    
  60:    void restar(){
  61:      this.x = width/2;
  62:      this.y =(height-100)/4;
  63:      this.xvelocidad = random( -3,3);
  64:      this.yvelocidad = random( -3,3);
  65:    }
  66:      
  67:  }





 


Clase Principal


En cuanto a processing se refiere, solo basta la clase principal donde definiremos la pantalla, la interacción de las dos clases anteriores y la comunicación serial con arduino.


Primero se importa la librería para la comunicación serial. Definimos algunas variables que vamos a usar para la comunicación y después se definen 2 objetos de la clase jugador y 1 de la clase pelota.


En el setup determinamos el tamaño de la pantalla en 500x500 y inicializamos la comunicación serial.


Inicializamos nuestros objetos, recordamos que el constructor de la clase Jugador tiene varios parámetros (anchura, altura y el color).


Utilice un tipo de letra especial (se tiene que tener el archivo .vlw), para esto se uso la variable de tipo “font” y le  asigne un tamaño de letra de 25 (línea 53 y 54).


En el draw modificamos nuestro color de fondo a blanco, y dibujamos los bordes que van a limitar nuestro juego (línea 68),  ya que también habrá una parte para el marcador del juego (línea 70-74). En caso de que se pause, se agregara la leyenda de “pausado”.


En  el serialEvent se realiza la comunicación con Arduino, donde se obtienen los datos de voltaje de los potenciómetros provenientes de la placa arduino y nosotros solo verificamos que esos valores estén en el rango establecido dentro de los bordes del juego. Al final de este método se envía al arduino el caracter “A”   para indicarle que ya terminamos de procesar la información y que solicitamos otra vez los datos actualizados.


En el keyPressed tenemos que al presionar la tecla “p” el juego se pausara y al presionar la tecla “n” el juego se reiniciara.


Y por ultimo tenemos los métodos pausar donde en caso de que se invoque a este método se ponen las variables de velocidad de nuestros objetos en 0 para que no haya movimiento. El método reiniciar solo vuelve a crear nuestros objetos con todas sus variables con valor inicial.   


   1:  /*


   2:  * Clase principal del programa

   3:  *Juego de pingPong

   4:  *

   5:  *Luis Angel Reyes Cruz

   6:  *

   7:  *Version 1.0

   8:  *

   9:  *Ultima modificacion: 03/01/13

  10:  *

  11:  *Ultimas modificaciones:Distintas velocidades en el rebote

  12:  *     

  13:  *

  14:  *Modificaciones pendientes: Revisar problema con la pelota en el centro del cuadro

  15:  *              

  16:  */

  17:   

  18:  import processing.serial.*;

  19:   

  20:  Serial port;

  21:   

  22:  //variables para la comunicacion serial con Arduino

  23:  String buff = "";

  24:  String temp = "";

  25:   

  26:  float valorTemp = 0;

  27:  int val = 0;

  28:  int SALTOLINEA = 10;//para saber cuando hay un salto de linea

  29:   

  30:  Bola bola;

  31:  Jugador jugador1;

  32:  Jugador jugador2;

  33:  PFont f;

  34:  boolean pausado;

  35:   

  36:  void setup() {

  37:    size(500,500);

  38:    //frameRate(25);

  39:    smooth();

  40:    

  41:    //conexion serial con arduino

  42:    println(Serial.list());

  43:    port = new Serial(this, Serial.list()[0], 9600);

  44:    // lee y almacena un byte dentro del buffer hasta que obtiene un salto de linea(ASCII 10)

  45:    //para saber que la comunicacion tiene exito

  46:    port.bufferUntil('\n');

  47:    

  48:    

  49:    // Inicializamos los objetos

  50:    bola = new Bola();

  51:    jugador1 = new Jugador(4,(height-100)/2,color(255,0,0)); 

  52:    jugador2 = new Jugador(width-4,(height-100)/2,color(0,0,255)); 

  53:    f = loadFont( "AngsanaNew-Italic-48.vlw" );

  54:    textFont(f,25);

  55:    pausado = false;

  56:    

  57:  }

  58:   

  59:  void draw() {

  60:    background(255);

  61:    

  62:    jugador1.display();

  63:    jugador2.display();

  64:    // Mover y mostrar los elementos

  65:    bola.mover(jugador1,jugador2);

  66:    bola.display();

  67:   

  68:    line(0,height-100,width,height-100);

  69:    fill(0);

  70:    textFont(f,30);

  71:    text("MARCADOR",width/2-60,height-80);

  72:    textFont(f,25);

  73:    text("Jugador 1: " + jugador1.marcador ,20,height-50);

  74:    text("Jugador 2: "+ jugador2.marcador ,width-100,height-50);

  75:    

  76:    

  77:    if(pausado==true){

  78:      textFont(f,40);

  79:      text("PAUSA",width/2-50,height/2);

  80:    }

  81:    

  82:  }

  83:   

  84:  /*Funcion para capturar cuando pasa un evento

  85:  en una comunicacion serial y pasamos como parametro

  86:  el puerto serial que ya habiamos configurado en el setup*/

  87:  void serialEvent(Serial port){

  88:    

  89:    // lee el buffer del serial hasta que encuentra un salto de linea

  90:    String bString = port.readStringUntil('\n');

  91:    

  92:    // elimmina en caso de que haya espacios en blanco antes de los bytes

  93:      bString = trim(bString);

  94:   

  95:      // separamos el strings por comas

  96:      // y los convertimos a enteros y los almacenamos en un arreglo

  97:      int sensors[] = int(split(bString, ','));

  98:   

  99:      // imprimimos la salida

 100:      for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {

 101:        print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t"); 

 102:      }

 103:      

 104:      // salto de linea

 105:      println();

 106:      

 107:      //comprobamos que el arreglo sea mayor a 1

 108:      if (sensors.length > 1) {

 109:        

 110:        /*asignamos los valores correspondietes a cada rectangulo del juego

 111:        y nos aseguramos que no pasen del limite permitido*/

 112:        

 113:        jugador1.y =constrain(sensors[0]+jugador1.largo/2,jugador1.largo/2,400-jugador1.largo/2);

 114:        jugador1.display();

 115:        jugador2.y = constrain(sensors[1]+jugador1.largo/2,jugador1.largo/2,400-jugador1.largo/2);

 116:        jugador2.display();

 117:       

 118:      }

 119:      

 120:      // enviamos una letra cualquiera para pedir otra vez datos

 121:      port.write("A");

 122:      

 123:      

 124:  }//fin de SerialEvent

 125:   

 126:  void keyPressed() {

 127:          if ( keyCode == UP ) {

 128:            //jugador1.Up();jugador1.display(); 

 129:            jugador2.Up();jugador2.display();

 130:          } else if ( keyCode == DOWN ) {

 131:            //jugador1.Down();jugador1.display(); 

 132:            jugador2.Down();jugador2.display(); 

 133:          }else if(keyCode == 80){

 134:           pausar(); 

 135:          }else if(keyCode == 78){

 136:           reiniciar(); 

 137:          }

 138:        

 139:  }

 140:   

 141:   

 142:  void pausar(){

 143:    if(pausado == false){

 144:      bola.xvelocidad=0;bola.yvelocidad=0;

 145:      jugador1.velocidad=0;

 146:      jugador2.velocidad=0;

 147:      pausado = true;}

 148:    else if(pausado == true){

 149:      bola.xvelocidad=random( -3,3);bola.yvelocidad=random( -3,3);

 150:      jugador1.velocidad=7;

 151:      jugador2.velocidad=7;

 152:      pausado = false;}

 153:  }

 154:   

 155:  void reiniciar(){

 156:    bola = new Bola();

 157:    jugador1 = new Jugador(4,(height-100)/2,color(255,0,0)); 

 158:    jugador2 = new Jugador(width-4,(height-100)/2,color(0,0,255)); 

 159:  }




 


Arduino


Para la parte de arduino, tenemos que definir los pines en los cuales se van a conectar nuestros potenciómetros.


En el setup lo único que tenemos que hacer es inicializar nuestra comunicación serial.


En el loop  vamos a leer un dato desde el puerto serial, el cual nos lo manda processing para solicitar información. Posteriormente leemos los valores de los potenciómetros mediante el método analogRead() el cual regresa un valor comprendido entre 0 y 1023 correspondiente al voltaje entre 0 y 5, nosotros tenemos que hacer que ese valor de entre 0 y 1023 corresponda a el rango de los bordes de nuestro juego, para esto usamos el metodo map() donde le decimos que el valor del potenciómetro esta en un rango de 0-1023 y que nos de su correspondiente en un rango de 0-400 el cual es el rango de nuestro juego.


Por ultimo enviamos serialmente los valores de nuestros potenciómetros separados por una coma para que processing los pueda manipular.


Conectamos dos potenciómetros a la placa arduino en los pines definidos anteriormente.   

/*
*Programa para controlar el juego de pingpong mediate
*2 potenciometros comunicándose serialmente con processing
*
*Luis Angel Reyes Cruz
*03/01/13
*/

// Envío de Entrada analógica 0 al puerto serie
int potPin1 = A2; // Designa el numero de entrada analógica
int potPin2 = A3; // Designa el numero de entrada analógica

//Variables para almacenar el valor del potenciómetro
int val1 = 0;
int val2 = 0;
int valPush = 0;

int Ibyte = 0; //variable para recibir el dato serial

void setup(){
Serial.begin(9600); //Configura la velocidad de transmisión con el puerto

while (!Serial) {
; // esperar mientras comunica el puerto serial
//solo se necesita en Leonardo
}

}


void loop(){

// si recibimos un byte valido
if (Serial.available() > 0) {

Ibyte = Serial.read();

val1 = map(analogRead(potPin1),0,1023,0,400); // Obtenemos el valor del potenciometro
val2 = map(analogRead(potPin2),0,1023,0,400);
//y ajustamos el valor de acuerdo al tamaño de la ventana
//El potenciometro maneja cantidades de 0 a 1023 y lo dividimos entre 4

Serial.print(val1); //enviamos el valor del potenciometro
Serial.print(","); //Enviamos un el carácter de salto de linea en ASCII

Serial.print(val2); //enviamos el valor del potenciometro

// delay(75); // espera 75 ms
}

}
}




Con todo lo anterior debemos de tener el juego funcionando, donde se pusieron varias cosas en practicas, como la creación de figuras en processing y una interfaz sencilla, el uso de teclas para realizar alguna acción y la mas importante, la comunicación serial en processing para la interacción con arduino.  



sábado, 5 de enero de 2013

Inicio


Paciencia. Este va ser un blog dedicado a tutoriales y post dedicados a el desarrollo de android, arduino, processing, electrónica y redes.