Week 4: Light Wand

I was really inspired by Light Art Club last week (Fridays at noon! Everyone should come!), and I wanted to continue working with the LED strip I had been playing with. To connect to some of what we were learning in PComp, I decided I would add dials my LED setup to control their RGB values. In the ideation phase, I thought it would be fun to also add switches to change between a few lighting patterns (but that idea never quite made it to the prototype I built).

I soldered a few potentiometers to use as dials (helping hands are amazing??).


And I plan to use these forever.


It was pretty easy to adjust the code we used in class to the specifications of what the NeoPixel library functions required to change the LED colors (basically, I mapped the raw values off the potentiometers to values between 0 and 255).

I really enjoyed playing with the dials! Turns out, it's way more fun to adjust the value of a variable using a dial, rather than going in and editing your code. And, I liked the level of immediate control I had over the exact color I was seeing.


At this point, I wanted to attach my LED strip to a motor that would spin my strip back and forth. It took me quite a while to figure out how to write the code so that the LED lights and the motor weren't holding each other up, timing-wise. It's not completely perfect, but here's what I came up with:

#include <Servo.h>
#include <Adafruit_NeoPixel.h>

#define LEDPin 6 
#define N_LEDS 10 
#define controlRed A0
#define controlGreen A1
#define controlBlue A2

Servo myservo;  
int pos = 0;
int lastPos = 1; 
bool reverse = false;

int oldRed = 5000; 
int oldGreen = 5000;
int oldBlue = 5000; 

Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, LEDPin);  

void setup() {
  myservo.attach(9);

  pinMode(controlRed, INPUT); 
  pinMode(controlGreen, INPUT);
  pinMode(controlBlue, INPUT); 
  
  strip.begin();
  strip.show();

  Serial.begin(9600);
}

void updateLights() {

    int redPin = analogRead(controlRed);
    int redMapped = map(redPin, 1000, -10, 5, 255);

    int greenPin = analogRead(controlGreen);
    int greenMapped = map(greenPin, 1000, -10, 5, 255);

    int bluePin = analogRead(controlBlue);
    int blueMapped = map(bluePin, 1000, -10, 5, 255);
    
    if (blueMapped != oldBlue || greenMapped != oldGreen || redMapped != oldRed){
      
        for (int i=0; i<N_LEDS; i++) {

            strip.setPixelColor(i, redMapped, greenMapped, blueMapped);
            strip.show();
            
            oldBlue = blueMapped; 
            oldRed = redMapped;
            oldGreen = greenMapped; 

            strip.show();
        }
    }

}

void updateServo(){

  if (reverse) {
    
    lastPos = pos; 
    myservo.write(pos);
    pos -= 10;
    delay(5); 
    
  } else {

    lastPos = pos;     
    myservo.write(pos);
    pos += 10;
    delay(5); 
                  
  }
}

void loop() {

  updateLights();

  if (pos != lastPos) {
      updateServo();    
  }

  if (pos == 180) reverse = true; 
  if (pos == 0) reverse = false;
  
}

It looks like this IRL:

A bit violently wiggly, without the servo being more locked down. Makes me laugh though.

I initially, I had been using Arduino's Sweep code, but it relied too heavily on for-loops to suit my purposes (so slow). This code made the motor move as smoothly as I wanted, and the dial remained responsive (though I thought I saw a bit of flickering in the LEDs).

Though I spent a lot of time fixing the motor + responsive dial setup, I was a bit disappointed in how the "light wand" performed with the servo motor moving the LED trip from 0 to 180 and back. I tried to take a few long exposure photos on my phone, which were only fast enough to capture the following:


When I snuck into the micro studio with a proper DSLR, I discovered that even in the most ideal conditions, the "rendered" light painting looked rather like an wifi symbol. I think this could be improved if I had implemented my pattern switches, and perhaps took more time to play around with timing, but for then, the result was somewhat disappointing. Maybe I do want my code to play around with colors, so that I can free up my hands for movement.

I took a bunch of long exposure photos of just the light wand, no motor, seen below. I tried to adjust the colors on my dials while waving around the wand, to varying degrees of success.