Loading...

Learning   Examples | Foundations | Hacking | Links

Controlling a circle of LEDs with a Joystick

The whole circuit:

Detail of the LED wiring

Detail of the arduino wiring

How this works

As you know from the Interfacing a Joystick tutorial, the joystick gives a coordinate (x,y) back to arduino. As you can see looking to the joystick is that the space in which he moves is a circle. This circle will be from now on our 'Pie' (see bottom right of the first image).

The only thing we need now to understand is that we have divided our Pie in 8 pieces. To each piece will correspond an LED. (See figure below). This way, when the joystick gives us a coordinate, it will necesarilly belong to one of the pies. Then, the program always lights up the LED corresponding to the pie in which the joystick is.

Code

 /* Controle_LEDcirle_with_joystik
  * ------------
  * This program controles a cirle of 8 LEDs through a joystick
  *
  * First it reads two analog pins that are connected 
  * to a joystick made of two potentiometers
  *
  * This input is interpreted as a coordinate (x,y)
  *
  * The program then calculates to which of the 8 
  * possible zones belogns the coordinate (x,y)
  * 
  * Finally it ligths up the LED which is placed in the 
  * detected zone
  *
  * @authors: Cristina Hoffmann and Gustavo Jose Valera
  * @hardware: Cristina Hofmann and Gustavo Jose Valera
  * @context: Arduino Workshop at medialamadrid
  */

  // Declaration of Variables

  int ledPins [] = { 2,3,4,5,6,7,8,9 };    // Array of 8 leds mounted in a circle
  int ledVerde = 13;
  int espera = 40;                 // Time you should wait for turning on the leds
  int joyPin1 = 0;                 // slider variable connecetd to analog pin 0
  int joyPin2 = 1;                 // slider variable connecetd to analog pin 1
  int coordX = 0;                  // variable to read the value from the analog pin 0
  int coordY = 0;                  // variable to read the value from the analog pin 1
  int centerX = 500;               // we measured the value for the center of the joystick
  int centerY = 500;
  int actualZone = 0;
  int previousZone = 0;

  // Asignment of the pins
  void setup()
  {
    int i;
    beginSerial(9600);
    pinMode (ledVerde, OUTPUT);
    for (i=0; i< 8; i++)
    {
      pinMode(ledPins[i], OUTPUT);
    } 
  }

  // function that calculates the slope of the line that passes through the points
  // x1, y1 and x2, y2
  int calculateSlope(int x1, int y1, int x2, int y2)
  {
    return ((y1-y2) / (x1-x2));
  }

  // function that calculates in which of the 8 possible zones is the coordinate x y, given the center cx, cy
  int calculateZone (int x, int y, int cx, int cy)
  {
    int alpha = calculateSlope(x,y, cx,cy); // slope of the segment betweent the point and the center

    if (x > cx)
    {
      if (y > cy) // first cuadrant
      {
        if (alpha > 1) // The slope is > 1, thus higher part of the first quadrant
          return 0;
        else
          return 1;    // Otherwise the point is in the lower part of the first quadrant
      }
      else // second cuadrant
      {
        if (alpha > -1)
          return 2;
        else
          return 3;
      }
    }

    else
    {
      if (y < cy) // third cuadrant
      {
        if (alpha > 1)
          return 4;
        else
          return 5;
      }
      else // fourth cuadrant
      {
        if (alpha > -1)
          return 6;
        else
          return 7;
      }
    }
  } 

   void loop() {
    digitalWrite(ledVerde, HIGH); // flag to know we entered the loop, you can erase this if you want

    // reads the value of the variable resistors 
    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);

   // we print int the terminal, the cartesian value of the coordinate, and the zone where it belongs. 
  //This is not necesary for a standalone version
    serialWrite('C');
    serialWrite(32); // print space
    printInteger(coordX);
    serialWrite(32); // print space
    printInteger(coordY);
    serialWrite(10);
    serialWrite(13);

    serialWrite('Z');
    serialWrite(32); // print space
    printInteger(actualZone);
    serialWrite(10);
    serialWrite(13);

  // But this is necesary so, don't delete it!
    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