Go Down

### Topic: Using one Potentiometer to Control Multiple LEDs at different rates (Read 2454 times)previous topic - next topic

#### nicodemus

##### Aug 29, 2011, 05:47 am
So I've been doing some preliminary research/testing and can't seem to quite sort out how to take a single potentiometer reading and take the sensor reading and output to, say, three LEDs. My problem lies in trying to understand how I'd be able to output the analog reading to one LED as you normally would with the LED blink programming, while controlling another LED at double that same analog reading, while outputting to a third LED at half speed. I'm using this as my starting point.... but can't seem to get my head around how to sort out the next steps. Any help would be amazing and thank you in advance for any advice as I work through this. I'm excited to see if this is possible.

const int ledPin =  2;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
long interval = sensorValue; // interval at which to blink (milliseconds)

void setup() {
pinMode(ledPin, OUTPUT);
}

void loop()
{
unsigned long currentMillis = millis();

{
if(currentMillis - previousMillis > sensorValue) {
previousMillis = currentMillis;
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);

}
}
}

#### dc42

#1
##### Aug 29, 2011, 10:42 amLast Edit: Aug 29, 2011, 10:52 am by dc42 Reason: 1
Here's a possible scheme for 2 LEDs that is easily extended to any number of LEDs. [WARNING: untested code!]

Code: [Select]
`const int numLeds = 2;const int ledPins[numLeds] = { 2, 3 };       // the number of the LED pinint ledStates[numLeds] = { LOW, LOW };   // ledState used to set the LEDlong previousMillis[numLeds] = { 0, 0 };     // will store last time LED was updatedfloat multipliers[numLeds] = { 0.5, 1.0 };  // the blink ratesint sensorPin = A0;    // select the input pin for the potentiometerint sensorValue = 0;  // variable to store the value coming from the sensorlong interval = sensorValue; // interval at which to blink (milliseconds)void setup() {  unsigned long currentMillis = millis();  for (int i = 0; i < numLeds; ++i) {    pinMode(ledPins[i], OUTPUT);    previousMillis[i] = currentMillis;      }}void loop(){  sensorValue = analogRead(sensorPin);  unsigned long currentMillis = millis();  for (int i = 0; i < numLeds ; ++i)  {    unsigned long target = (unsigned long)(sensorValue * multipliers[i]);    if(currentMillis - previousMillis[i] >= target) {      previousMillis[i] += target;        if (ledStates[i] == LOW)        ledStates[i] = HIGH;      else        ledStates[i] = LOW;      digitalWrite(ledPins[i], ledStates[i]);      }  }}`
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

#### nicodemus

#2
##### Aug 29, 2011, 04:13 pm
Thanks for the response. I posted and then realized I could do something like that... but wasn't quite positive about the proof of concept etc... the snag seems to be though that they aren't quite hitting in sync with one another... so that it's doing the .5 slightly off from the 1.0, which I don't quite understand why that'd be happening. Do you think there's a way to get them to lock together tightly? Or is there always going to be this slippage?

#### greenmeanies

#3
##### Aug 29, 2011, 06:05 pm
If you truly want the LEDs to remain in lock-step (like the Galilean moons of Jupiter), then you should treat them like a binary counter. Use a single counter variable to go from 0 to 7, and then decipher the binary version of that out to the three different LEDs. Notice how the LED "C" turns on and off twice as fast as the LED "B", which is also twice as fast as LED "A". Once the counter gets to 8, it's the exact same state as 0, so we start over again.

Code: [Select]
`A B C Count0 0 0 00 0 1 10 1 0 20 1 1 31 0 0 41 0 1 51 1 0 61 1 1 70 0 0 8`

#### dc42

#4
##### Aug 29, 2011, 09:19 pm
greenmeanies has suggested a good solution for keeping them in step no matter what. The solution I suggested is subject to rounding error because of the use of floating point maths (using integer division would also give rounding error). However, if you change the type of 'multipliers' from 'float' to 'unsigned int' and use values of 1, 2 and 4 for the 3 LEDs, I think they should stay in step.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Go Up