EJERCICIO Controlando un círculo de LED-s con un Joystick

Descripción del ejercicio

Como se explica en el ejercicio "Manejando un joystick", el joystick proporciona las coordenadas (x,y) a la Arduino. Como se puede ver el joystick se mueve en un espacio circular. Este círculo va a ser por ahora nuestra tarta (ver las imágnes de abajo).

Lo único que hay que tener en cuenta es entender es que hemos dividido la tarta en 8 piezas. A cada parte le corresponde un LED (ver el esquema inferior). De esta forma, cuando el joystick nos devuelve una coordenada, esta coordenada corresponde univocamente a una de las partes de la tarta. Entonces, el código iluminará siempre el LED correspondiente al trozo de la tarta en que se encuentre.

Esquema

El circuito completo

Detalle del cableado de los LED

Detalle del cableado en la Arduino

Elementos necesarios

 * 8 LED-s
 * 8 resistencia de 220 Ohmios
 * Un joystick
 * Una placa protoboard.
 * Cables para realizar las conexiones. 

Código fuente

 /* Controlando un círculo de LED-s con un joystick
  * -----------------------------------------------
  * 
  * Este programa controla un círculo de 8 LED-s mediante un joystick
  *
  * Primero lee las dos entradas analógicas a las que está conectado
  * el joystick, que está compuesto por dos potenciómetros.
  *
  * Esta entrada es interpretada como una coordenada (x,y)
  *
  * El programa calcula entonces a cual de las 8 posibles zonas 
  * pertenece la coordenada (x,y) 
  * 
  * Finalemente enciende el LED que está colocado en la zona
  * detectada
  *
  * @authors: Cristina Hoffmann and Gustavo Jose Valera
  * @hardware: Cristina Hofmann and Gustavo Jose Valera
  * @context: Arduino Workshop at medialamadrid
  */

  // Declaración de variables

  int ledPins [] = { 2,3,4,5,6,7,8,9 };    // Array de 8 LED-s montados en un círculo
  int ledVerde = 13;
  int espera = 40;                 // Tiempo que deberías esperar para encender los LED-s
  int joyPin1 = 0;                 // Variable de deslizamiento conectada al PIN analógico 0
  int joyPin2 = 1;                 // Variable de deslizamiento conectada al PIN analógico 1
  int coordX = 0;                  // Variable a leer del PIN analógico 0
  int coordY = 0;                  // Variable a leer del PIN analógico 1
  int centerX = 500;               // Hemos medido el valor X de la posición central del joystick
  int centerY = 500;               // Hemos medido el valor Y de la posición central del joystick
  int actualZone = 0;
  int previousZone = 0;

  // Asignación de los PIN-es
  void setup()
  {
    int i;
    beginSerial(9600);
    pinMode (ledVerde, OUTPUT);
    for (i=0; i< 8; i++)
    {
      pinMode(ledPins[i], OUTPUT);
    } 
  }

  // Función que calcula la inclinación de la linea que pasa por los puntos
  // x1, y1 y x2, y2

  int calculateSlope(int x1, int y1, int x2, int y2)
  {
    return ((y1-y2) / (x1-x2));
  }

  // Función que calcula en cual de las 8 posibles zonas está la coordenada (x,y),
  // dado el centro (cx,cy)

  int calculateZone (int x, int y, int cx, int cy)
  {
    int alpha = calculateSlope(x,y, cx,cy); // inclinación del segmento entre el punto y el centro

    if (x > cx)
    {
      if (y > cy)      // Primer cuadrante
      {
        if (alpha > 1) // Si la inclinación es > 1,el punto está en la parte alta del primer cuadrante 
          return 0;
        else
          return 1;    // De lo contrario el punto está en la parte baja del primer cuadrante 
      }
      else            // Segundo cuadrante
      {
        if (alpha > -1)
          return 2;
        else
          return 3;
      }
    }

    else
    {
      if (y < cy)      // Tercer cuadrante
      {
        if (alpha > 1)
          return 4;
        else
          return 5;
      }
      else             // Cuarto cuadrante
      {
        if (alpha > -1)
          return 6;
        else
          return 7;
      }
    }
  } 

   void loop() {
    digitalWrite(ledVerde, HIGH); // Flag para saber que estamos en el loop. Se puede eliminar si se quiere

    // Lee los valores de las dos resistencias del joystick

    coordX = analogRead(joyPin1);   
    coordY = analogRead(joyPin2);   

    // Calculamos dónde está X

    actualZone = calculateZone(coordX, coordY, centerX, centerY); 

    digitalWrite (ledPins[actualZone], HIGH);     

    if (actualZone != previousZone)
      digitalWrite (ledPins[previousZone], LOW);

   // Imprimimos en el terminal el número, valor cartesiano 
   // de las coordinadas, y la zona a la que pertenece 

   // Esto no es necesario para una versión autónoma
    serialWrite('C');
    serialWrite(32); // Escribe un espacio
    printInteger(coordX);
    serialWrite(32); // Escribe un espacio
    printInteger(coordY);
    serialWrite(10);
    serialWrite(13);

    serialWrite('Z');
    serialWrite(32); // Escribe un espacio
    printInteger(actualZone);
    serialWrite(10); // Escribe un retorno de carro
    serialWrite(13);

  // Esto es necesario, ¡ No lo borres !
    previousZone = actualZone;
   // delay (500);

 }

@idea: Cristina Hoffmann and Gustavo Jose Valera

@code: Cristina Hoffmann and Gustavo Jose Valera

@pictures and graphics: Cristina Hoffmann

@date: 20051008 - Madrid - Spain