Digital and Analog Switches: Nicholas

Inspiration

I wanted to create a moving spotlight using a potentiometer that work as if you are pointing at a light bulb and turning it on. I also wanted to create two different modes that would alternate between analog and digital signals using a button.

Implementation

First, I had to create the logic for the analog and digital switches based on the potentiometer value. I did this with the following code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const int LEDpins[] = {3, 5, 6, 10, 11};
double mapf(float value, float fromLow, float fromHigh, float toLow, float toHigh) {
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
double mappedD(float mapValue, int currPin){
double absDist = abs(mapValue - currPin);
return mapf(absDist, 0, PIN_LENGTH-1, 255, 0);
}
//code for analog write
double mapValue = mapf(potValue, 0, 1023.0, 0, PIN_LENGTH-1);
for(int i = 0; i < PIN_LENGTH; i++){
analogWrite(LEDpins[i], max(0,mappedD(mapValue, i)-100));
}
//code for digital write
int intMapVal = map(potValue, 0, 1023, 0, PIN_LENGTH-1);
for(int i = 0; i < PIN_LENGTH; i++){
digitalWrite(LEDpins[i], intMapVal==i);
}
const int LEDpins[] = {3, 5, 6, 10, 11}; double mapf(float value, float fromLow, float fromHigh, float toLow, float toHigh) { return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow; } double mappedD(float mapValue, int currPin){ double absDist = abs(mapValue - currPin); return mapf(absDist, 0, PIN_LENGTH-1, 255, 0); } //code for analog write double mapValue = mapf(potValue, 0, 1023.0, 0, PIN_LENGTH-1); for(int i = 0; i < PIN_LENGTH; i++){ analogWrite(LEDpins[i], max(0,mappedD(mapValue, i)-100)); } //code for digital write int intMapVal = map(potValue, 0, 1023, 0, PIN_LENGTH-1); for(int i = 0; i < PIN_LENGTH; i++){ digitalWrite(LEDpins[i], intMapVal==i); }
const int LEDpins[] = {3, 5, 6, 10, 11};

double mapf(float value, float fromLow, float fromHigh, float toLow, float toHigh) {
  return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
} 

double mappedD(float mapValue, int currPin){
  double absDist = abs(mapValue - currPin);
  return mapf(absDist, 0, PIN_LENGTH-1, 255, 0);
}

//code for analog write
double mapValue = mapf(potValue, 0, 1023.0, 0, PIN_LENGTH-1);
for(int i = 0; i < PIN_LENGTH; i++){
    analogWrite(LEDpins[i], max(0,mappedD(mapValue, i)-100));
}

//code for digital write
int intMapVal = map(potValue, 0, 1023, 0, PIN_LENGTH-1);
for(int i = 0; i < PIN_LENGTH; i++){
    digitalWrite(LEDpins[i], intMapVal==i);
}

By creating my own map functions, I was able to have a floating point value that determined how much each light bulb should light up. For the analog setting, the light was too bright at most values, so I decreased the values by 100 and constrained them to prevent integer underflow.

I also did added some logic for the button handling, and a light show would play while holding the button down, and would switch between analog and digital on release.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if(buttonState == LOW && prevState == HIGH){
toggled = !toggled;
for(int i = 0; i < PIN_LENGTH; i++){
analogWrite(LEDpins[i], false);
}
}
if(buttonState == HIGH && prevState == HIGH){
if(millis() > timer){
timer=millis()+interval;
for(int i = 0; i < PIN_LENGTH; i++){
LEDOn[i] = random(2);
}
}
for(int i = 0; i < PIN_LENGTH; i++){
digitalWrite(LEDpins[i], LEDOn[i]);
}
}
if(buttonState == LOW && prevState == HIGH){ toggled = !toggled; for(int i = 0; i < PIN_LENGTH; i++){ analogWrite(LEDpins[i], false); } } if(buttonState == HIGH && prevState == HIGH){ if(millis() > timer){ timer=millis()+interval; for(int i = 0; i < PIN_LENGTH; i++){ LEDOn[i] = random(2); } } for(int i = 0; i < PIN_LENGTH; i++){ digitalWrite(LEDpins[i], LEDOn[i]); } }
if(buttonState == LOW && prevState == HIGH){
   toggled = !toggled;
   for(int i = 0; i < PIN_LENGTH; i++){
      analogWrite(LEDpins[i], false);
    }
 }
 if(buttonState == HIGH && prevState == HIGH){
  if(millis() > timer){
    timer=millis()+interval;
    for(int i = 0; i < PIN_LENGTH; i++){
      LEDOn[i] = random(2);
    }
   }
   for(int i = 0; i < PIN_LENGTH; i++){
      digitalWrite(LEDpins[i], LEDOn[i]);
    }
 }

In doing this, I was able to create a light show dependent on the switch, which takes in a digital input, and potentiometer, which takes in a continuous input.

Reflection

Moving forwards, I would like to experiment with different mathematical functions for displaying luminosity as a linear scale may not have been best. I would also like to explore different ways to turn the knob as it was very difficult to turn and observe the effects without blocking the view.

Leave a Reply