Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Controle um círculo de LEDs com um joystick

Circuito completo

Detalhe do cabeamento dos LEDs

Detalhe do cabeamento ao Arduino

Como funciona

O joystick fornece coordenadas (x,y) ao Arduino de acordo com a sua posição. Como pode se ver, o espaço no qual o joystick se move é um círculo. Esse círculo será o que chamaremos de agora em diante de 'Torta' (veja a parte inferior direita da primeira imagem).

A única coisa que precisamos entender é que a Torta está dividida em 8 fatias. A cada fatia há um LED correspondente. (Veja a figura abaixo). Dessa forma, quando o joystick fornece-nos uma coordenada, ela necessariamente pertencerá a uma dessas fatias. O programa então acende o LED correspondente à fatia.

Código

 /* Controle_CírculodeLED_com_joystick
  * ------------
  * Este esboço control um círculo com 8 LEDs
  * via joystick
  *
  * Primeiro lê-se os dois pinos analógicos conectados
  * ao joystick feito com dois potenciômetros
  *
  * Essa entrada é interpretada como coordenadas (x,y)
  *
  * Em seguida, calcula-se qual das 8 zonas possíveis 
  * faz parte das coordenadas (x,y)
  * 
  * Finalmente acende-se o LED que está na zona detectada
  *
  * @authors: Cristina Hoffmann and Gustavo Jose Valera
  * @hardware: Cristina Hofmann and Gustavo Jose Valera
  * @context: Arduino Workshop at medialamadrid
  */

  // Declaração de variáveis

  int ledPins [] = { 2,3,4,5,6,7,8,9 };    // Matriz com 8 LEDs organizados em círculo
  int ledVerde = 13;
  int espera = 40;                 // Tempo necessário para ligar o LED
  int joyPin1 = 0;                 // variável deslizante conectada ao pino analógico 0
  int joyPin2 = 1;                 // variável deslizante conectada ao pino analógico 1
  int coordX = 0;                  // variável para ler o valor no pino analógico 0
  int coordY = 0;                  // variável para ler o valor no pino analógico 1
  int centerX = 500;               // valor para a posição central do joystick
  int centerY = 500;
  int actualZone = 0;
  int previousZone = 0;

  // delegação dos pinos
  void setup()
  {
    int i;
    beginSerial(9600);
    pinMode (ledVerde, OUTPUT);
    for (i=0; i< 8; i++)
    {
      pinMode(ledPins[i], OUTPUT);
    } 
  }

  // função que calcula a inclinação da linha que passa pelos pontos
  // x1, y1 e x2, y2
  int calculateSlope(int x1, int y1, int x2, int y2)
  {
    return ((y1-y2) / (x1-x2));
  }

  // função que calcula em qual das 8 zonas possíveis
  // estão as coordenadas x, y dado o centro cx, cy
  int calculateZone (int x, int y, int cx, int cy)
  {
    int alpha = calculateSlope(x,y, cx,cy); // inclinação do segmento entre o ponto e o centro

    if (x > cx)
    {
      if (y > cy) // 1o quadrante
      {
        if (alpha > 1) // Inclinação > 1, portanto parte mais alta do 1o quadrante
          return 0;
        else
          return 1;    // Caso contrário, parte mais baixa do 1o quadrante
      }
      else // 2o quadrante
      {
        if (alpha > -1)
          return 2;
        else
          return 3;
      }
    }

    else
    {
      if (y < cy) // 3o quadrante
      {
        if (alpha > 1)
          return 4;
        else
          return 5;
      }
      else // 4o quadrante
      {
        if (alpha > -1)
          return 6;
        else
          return 7;
      }
    }
  } 

   void loop() {
    digitalWrite(ledVerde, HIGH); // flag para sabermos que se entrou em loop(), é opcional

    // leia o valor dos potenciômetros
    coordX = analogRead(joyPin1);   
    coordY = analogRead(joyPin2);   

    // calcule em qual x
    actualZone = calculateZone(coordX, coordY, centerX, centerY); 

    digitalWrite (ledPins[actualZone], HIGH);     

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

   // imprima no terminal o valor cartesiano da coordenada
   // e a zona ao qual faz parte
   //não é necessário caso o Arduino rode em modo autônomo
    serialWrite('C');
    serialWrite(32); // imprima espaço
    printInteger(coordX);
    serialWrite(32); // imprima espaço
    printInteger(coordY);
    serialWrite(10);
    serialWrite(13);

    serialWrite('Z');
    serialWrite(32); // imprima espaço
    printInteger(actualZone);
    serialWrite(10);
    serialWrite(13);

  // Não apague a linha abaixo, ela é necessária!
    previousZone = actualZone;
   // delay (500);

 }