The idea is to put as many LEDs as possible in something resembling a semi-circle with the servo in the middle of the arc. As you press the sensor, the LEDs start lighting up left-to-right and the servo follows the LEDs lighting up. As you lessen the pressure on the sensor or let go altogether, the lights and servo goes back to the left.
If you're careful of what goes where, you can get 12 LEDs and totally max out the digital pins (leaving one for the servo). The code works fine for odd number of pins, there might be a problem with evens. Anyway, it's something to play with, just make sure the constants at the top match the number of LEDs and the pin numbers are correctly specified.
Code: Select all
#include <Servo.h>
static boolean running = true;
int currentPos = 0;
int lastPos = -1;
static int ledCount = 13;
static int ledPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int *ledOnValue;
int *ledOffValue;
static int sensorPin = 2;
static int servoPin = 13;
static Servo myServo;
/*
Setup the digital pins for the LEDs, the servo, the button, etc. We'll set
the LEDs and servo for the neutral position, 90 degrees.
*/
void setup()
{
// Initialize the pins for the LEDs
for (int i = 0; i < ledCount; i++)
{
pinMode(ledPins[i], OUTPUT);
}
// Initialize the pin for the server
myServo.attach(servoPin);
// Calculate where the LEDs go on and off
calcLedOnOff();
return;
}
/*
Method for doing the actual work.
*/
void loop()
{
switch (readSensor() / 255)
{
case 0:
currentPos -= 3;
break;
case 1:
currentPos -= 1;
break;
case 2:
currentPos += 1;
break;
case 3:
currentPos += 3;
break;
}
// Normalize the position, make sure it stays between 0 and 180.
if (currentPos < 0) currentPos = 0;
else if (currentPos > 180) currentPos = 180;
// Set everything for the new position, if it's changed.
if (currentPos != lastPos)
{
myServo.write(currentPos);
setLeds(currentPos);
lastPos = currentPos;
delay(100);
}
}
int readSensor ()
{
return (analogRead(sensorPin));
}
void calcLedOnOff()
{
// First, calculate the gap size in degrees.
int gap = 180 / (ledCount - 1);
int halfGap = gap/2 + gap/4;
// Determine the on/off value for each LED, essentially centering the
// over the LED with half on either side.
ledOnValue = (int*) malloc (sizeof(int) * ledCount);
ledOffValue = (int*) malloc (sizeof(int) * ledCount);
for (int i = 0; i < ledCount; i++)
{
ledOnValue[i] = (gap * i) - halfGap;
ledOffValue[i] = (gap * i) + halfGap;
}
// Normalize to make sure values are between 0 and 180.
ledOnValue[0] = 0;
ledOffValue[ledCount - 1] = 180;
return;
}
void setLeds(int position)
{
for (int i = 0; i < ledCount; i++)
{
digitalWrite (ledPins[i],
(position >= ledOnValue[i] && position <= ledOffValue[i]) ? HIGH : LOW);
}
}