Learning   Examples | Foundations | Hacking | Links

Controlando un círculo de LEDs con un Joystick

El circuito completo:

Detalle del cableado del LED

Detalle del cableado del Arduino

Como funciona

Como sabes por el tutorial Conectando un Joysrick, el joystick proporciona coordenadas (x,y) de retorno al Arduino. Como puedes ver al contemplar el joystick, el espacio en el que este se mueve es un círculo. Este círculo será desde ahora nuestra 'Tarta' (ver debajo a la derecha de la primera imagen).

L único que tenemos que entender ahora consiste en que tenemos dividida nuestra Tarta en 8 pedazos. A cada pedazo corresponderá un LED. (Mirar el gráfico a continuación). Por esto, cuando el joystick nos da una coordenada, necesariamente tiene que pertenecer a una de las porciones. Por tanto, el programa siempre encenderá el LED correspondiente a la porción en la cual se encuentre el joystick.

Código

 /* Controle_LEDcirle_with_joystik
  * ------------
  * Este programa controla un circulo de 8 LEDS a través de un joystick
  *
  * Primero lee dos pines analógicos que están conectados
  * a un jojoystick hecho con dos potenciómetros
  *
  * Esta entrada es interpretada como una coordenada (x,y)
  *
  * El programa calcula a cual de las 8
  * posibles zonas possible zones corresponde la coordenada(x,y)
  * 
  * Finalmente ilumina el LED que está ubicado en la
  * zona detectada
  *
  * @authors: Cristina Hoffmann and Gustavo Jose Valera
  * @hardware: Cristina Hofmann and Gustavo Jose Valera
  * @context: Arduino Workshop at medialamadrid
  */

  // Declaracion de Variables

  int ledPins [] = { 2,3,4,5,6,7,8,9 };    // Array de 8 leds montados en un circulo
  int ledVerde = 13;
  int espera = 40;                 // Tiempo que espera para poner en encendido los leds
  int joyPin1 = 0;                 // potenciometro conectado al pin 0 analógico
  int joyPin2 = 1;                 // potenciómetro conectado al pin 1 analógico
  int coordX = 0;                  // variable para leer el valor del pin 0 analógico
  int coordY = 0;                  // variable para leer el valor del pin 1 analógico
  int centerX = 500;               // medimos el valos para la posición central del joystick
  int centerY = 500;
  int actualZone = 0;
  int previousZone = 0;

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

  // función que calcula la pendiente de la linea que pasa a través de los puntos
  // x1, y1 and 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 corresponde la cordenada x,y, considerando el centro cx,cy
  int calculateZone (int x, int y, int cx, int cy)
  {
    int alpha = calculateSlope(x,y, cx,cy); // pendiente del segmento entre el punto y el centro

    if (x > cx)
    {
      if (y > cy) // primer cuadrante
      {
        if (alpha > 1) // La pendiente es > 1, por tanto parte mas alta del primer cuadrante
          return 0;
        else
          return 1;    // En otro caso 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); // bandera para conocer si entramos en un bucle, puedes eliminar esto si quieres

    // lectura de los valores de las resistencias variables
    coordX = analogRead(joyPin1);   
    coordY = analogRead(joyPin2);   

    // We calculate in which x
    actualZone = calculateZone(coordX, coordY, centerX, centerY); 

    digitalWrite (ledPins[actualZone], HIGH);     

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

   // visualiza en el terminal, el valor cartesiano de la coordenada y la zona a la que pertenece
  //Esto no es necesario para la versión standalone (independiente)
    serialWrite('C');
    serialWrite(32); // visualiza un espacio
    printInteger(coordX);
    serialWrite(32); // visualiza un espacio
    printInteger(coordY);
    serialWrite(10);
    serialWrite(13);

    serialWrite('Z');
    serialWrite(32); // visualiza un espacio
    printInteger(actualZone);
    serialWrite(10);
    serialWrite(13);

  // Pero esto si 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

Share