Neopixel Lamp

For my final assignment I decided to build a lamp using a neo pixel ring. This builds upon my previous light controller assignment.

Design Challenge

Make a device to control a light with the following features: 

  • A control to turn the light on and off. When it turns on, it should retain the relative red, green, and blue brightness levels from when it was last turned on.
  • The ability to fade each color channel (red, green, and blue) from off to full brightness
    • Fade level should be maintained when you release the fade controller
    • Fade should be interrruptable by other controllers, e.g. on/off or another fade controller
  • The ability to fade the overall brightness of the light

Inspiration

I saw this wall mounted light display and wanted to recreate it. 

Materials

Adafruit Neopixel

2 potentiometers (one to control the color hue and the other to control brightness)

1 button – on/off switch

Arduino

Battery

Plywood

Acrylic

Coding the Light Effects

I need to create code that controlled an on/off button, a potentiometer to control the color switching and another to control the brightness. Since the design of my light inspiration is sleek and simple, I opted to also keep the controls simple. Having never worked with neopixels this proved to be a confusing process. I had lots of examples to reference but was not quite sure what the code was saying until I uploaded each to my arduino and wired breadboard. This gave me some sense of what the commands of the neopixel library meant – but did not end the frustration.

Fabrication

I used plywood for the sconce. I design the back of the sconce with a pocket to house the controls (seen in the images below). I used two frosted plastic containers from Muji for housing the components on the back of the light.

Music Controller

Design Challenge: Make a device to control playback of pre-recorded music.

Parameters:

  • Make a device that sends asynchronous serial messages to another device which will play the music.
  • All serial messages should be terminated by a linefeed.
  • The playback device will echo your message back to you as an acknowledgement message when it executes your command.

The device supports the following features:

  • It is operable by a user who cannot see the device.
  • The user gets an acknowledgement when they activate any control.
  • Start or stop the playback of a track (start plays track from the beginning).
  • Pause or resume playback of a track (resume plays track from last position stopped)
  • Skip ahead one track in the playlist.
  • Skip back one track in the playlist.
  • Fast-forward the current track (double speed of the track).
  • Skip to a random track in the playlist.

Tools used:

  • Arduino IDE
  • Arduino MKR1000
  • Python server
  • P5.js
  • P5 Serial Control App
  • Buttons (momentary and )
  • Vibration Sensor
  • Frosted plastic container
 
Arduino and Physical Components
 

I started this assignment by wiring my components to the breadboard and Arduino. As shown below, I wired the 2 toggle buttons, 4 momentary buttons and the vibration sensor. 

Arduino Code:

This proved to be quite tricky for me initially. My goal was to create the code from scratch and not rely on references. I encountered errors with the switch state where the serial monitor was just writing the value continually. Adding a delay did not help. I eventually discovered that my syntax was wrong (odd that the IDE did not pick up on this when I verified the code.) The culprit was a semi colon.

 
 My code:
 

const int startStop = 11;
const int pausePlay = 10;
const int next = 9;
const int back = 8;
const int randomSong = 7;
const int fast = 6;

int vibeSensor = 5;

int lastStartStopState = LOW;
int lastPausePlayState = HIGH;
int lastNextState = LOW;
int lastBackState = LOW;
int lastRandomState = LOW;
int lastFastState = LOW;

void setup() {
Serial.begin(9600);

pinMode(startStop, INPUT_PULLUP);
pinMode(pausePlay, INPUT_PULLUP);
pinMode(next, INPUT_PULLUP);
pinMode(back, INPUT_PULLUP);
pinMode(randomSong, INPUT_PULLUP);
pinMode(fast, INPUT_PULLUP);
pinMode(vibeSensor, OUTPUT);
}

void loop() {
int buttonState1 = digitalRead(startStop);
int buttonState2 = digitalRead(pausePlay);
int buttonState3 = digitalRead(next);
int buttonState4 = digitalRead(back);
int buttonState5 = digitalRead(randomSong);
int buttonState6 = digitalRead(fast);


// 1. Start Stop Button
// If the button is on, send a message to serial to start playing the song
if (buttonState1 != lastStartStopState) {
if (buttonState1 == HIGH) {
Serial.println(“start”);
Serial.write(49);

analogWrite(vibeSensor, 255); // give feedback
analogWrite(vibeSensor, 0);
delay(100);

// If the button is off, send a message to serial to stop playing the song
} else {
Serial.println(“stop”);
Serial.write(49);
//
analogWrite(vibeSensor, 255); // give feedback
analogWrite(vibeSensor, 0);
delay(100);
}
lastStartStopState = buttonState1;
}

// 2. Pause Play Button
//If the button is on, send a message to serial to pause the song
if (buttonState2 != lastPausePlayState) {
if (buttonState2 == LOW) {

Serial.println(“pause”);
Serial.write(50);
delay(500);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);

// If the button is off, send a message to serial to play the song
} else {
Serial.println(“play”);
Serial.write(50);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);
}
}
lastPausePlayState = buttonState2;

//3. Next Button (skip to the next song)
// If the button is pressed, send a message to serial to skip forward to the next song

if (buttonState3 != lastNextState) {
if (buttonState3 == LOW) {

Serial.println(“next”);
Serial.write(51);
// delay(500);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);
}
lastNextState = buttonState3;
}

// 4. Back Button (go back and play the previous song)
// If the button is on, send a message to serial to skip to the previous song

if (buttonState4 != lastBackState) {
if (buttonState4 == LOW) {

Serial.println(“back”);
Serial.write(52);
// delay(500);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);
}
lastBackState = buttonState4;
}

// 5. Random Button (play a random song)
// If the button is on, send a message to serial to skip to a random song

if (buttonState5 != lastRandomState) {
if (buttonState5 == LOW) {

Serial.println(“random”);
Serial.write(53);
// delay(500);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);
}
lastRandomState = buttonState5;
}


// 6. Fast Button (fast forward through the current song)
// If the button is on, send a message to serial to fast forward through the current song

if (buttonState6 != lastFastState) {
if (buttonState6 == LOW) {

Serial.println(“fast”);
Serial.write(54);
// delay(500);

analogWrite(vibeSensor, 255); // give feedback
delay(100);
analogWrite(vibeSensor, 0);
}
lastFastState = buttonState6;
}

}

 
 
 

 
 

P5.js and Serial Communication

I haven’t touched p5 since ICM. However, setting up the serial communication and updating the sample p5 code was the most straightforward part of this assignment. 

Using this serial input to P5 tutorial, I installed the P5.serialcontrol app and the p5.serialserver. With the arduino connected to the port, I used the serial control app to ensure the port was available. Then using the command line, opened a python server the tested my controller. 

P5 code: 

var serial;
var portName = ‘/dev/cu.usbmodem1411’;
var inData;

var song; // the sound file to be played

// the list of songs:
var songs = [‘FastWine.mp3’, ‘FullExtreme.mp3’, ‘Incredible.mp3’, ‘LeaveMeAlone.mp3’, ‘TurnUp.mp3’];

var songCount = songs.length; // number of songs in the music dir
var currentSong = 0; // current song number

function preload() { // load the first song on preload
song = loadSound(‘music/’ + songs[currentSong]);
}

function setup() {
createCanvas(400, 300);

serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on(‘connected’, serverConnected); // callback for connecting to the server
serial.on(‘open’, portOpen); // callback for the port opening
serial.on(‘data’, serialEvent); // callback for when new data arrives
serial.on(‘error’, serialError); // callback for errors
serial.on(‘close’, portClose); // callback for the port closing

serial.list(); // list the serial ports
serial.open(portName); // open a serial port
}

function serverConnected() {
println(“We are connected!”);
}

function portOpen() {
println(“Serial Port is open!”);
}

function serialEvent() {
inData = Number(serial.read());
controlSound(inData);
console.log(inData)
}

function serialError(err) {
println(‘Something went wrong with the serial port ‘ + err);
}

function portClose() {
println(‘The serial port is closed’);
}

function draw() {
background(30, 20, 180);
fill(255);
text(“sensor value: ” + inData, 30, 30);
// draw the song’s name and current time in seconds:
text(songs[currentSong], 20, 50);
text(song.currentTime().toFixed(3), 20, 100);
}

function controlSound(input) {
switch (input) {
case 49: // start/stop, press 1
if (song.isPlaying()) {
song.stop();
} else {
song.play();
}
break;
case 50: // play/pause, press 2
if (song.isPlaying()) {
song.pause();
} else {
song.play();
}
break;
case 51: // skip ahead, press 3
// make sure the song number is valid, and increment:
if (currentSong < songs.length - 1) {
currentSong++;
} else {
currentSong = 0;
}
// get new song:
getSong(currentSong);
break;
case 52: // skip back, press 4
// in the first second, just rewind the current track:
if (song.currentTime() > 1.0) {
song.jump(0);
// if more than a second has elapsed, then
// make sure the song number is valid, and decrement:
} else {
if (currentSong > 0) {
currentSong–;
} else {
currentSong = songs.length – 1;
}
// get new song:
getSong(currentSong);
}
break;
case 53: // fast forward, press 5
song.rate(2.0); // double the play speed
if (!song.isPlaying()) {
song.play();
}
break;
case 54: // random song, press 6
currentSong = Math.round(random(songCount)); // get a new song number
getSong(currentSong); // play it
break;
}
}

function getSong(songNumber) {
if (songNumber < songs.length) { // if the song number is in range
if (song.isPlaying()) {
song.stop();
}
// load a new song:
song = loadSound(‘music/’ + songs[currentSong], resumePlay);
return true;
} else { // if the song number was out of range, return false
return false;
}
}

function resumePlay() {
// if the song isn’t playing, play it
if (song.isPlaying()) {
song.stop();
} else {
song.play();
}
}

function keyReleased() {
controlSound(keyCode); // send the ASCII number of the key
}

 

Fabrication

I wanted the feel of a walkman so I purchased a small plastic container that could be held with one hand. I drilled holes for my 6 buttons and for the power cable. Then carefully installed my buttons and MKR1000. 

Experience new music

So, that was soca. In case you were wondering what I was playing. Take a listen to the tracks on my playlist, below.

Copper Tape – Sensor Report

Copper foil tape is made from thin pure copper and is sold in different widths and lengths. Just like copper metal, copper tape is extremely flexible and can be formed into shapes and can be soldered to. The tape itself can carry electricity just like a wire. It can be used to carry electricity between a battery and components like LEDs, buzzers, and motors. Copper tape can be used as a switch or wire and works well in paper circuits. We will also see below how it can be used as a speaker!

Copper itself conducts both heat and electricity very well. Perhaps learning more about the metal and how it is used can prompt more inventive uses of the copper tape form of the metal. Learn about the compound itself on wikipedia as well as the common uses of copper.

[photo credit: Adafruit.com]

There are two types of copper tape: with conductive adhesive and with non-conductive adhesive. Copper tape with non-conductive adhesive is more common. This type of tape is practically used as a garden animal repellant and is generally found in the hardware. For physical computing, copper tape with conductive adhesive is used. This is the form that I will explore in this report.

On the back is an electrically conductive adhesive. The adhesive can’t carry significant current but it is very handy for sensing applications where you don’t want to solder the copper tape (see the labs below).

Photo credit: adafruit.com

Conducty.com nicely highlights the features of some commercially available copper tapes. These tapes are also available for purchase through the website.

ATTRIBUTETAPE
Sticky and conductive on both sidesConducti Tape D34 (copper foil)
Sticky on one side, conductive on both sidesConducti Tape Z22 (ripstop nylon)
Sticky on conductive side, blocks electricity on shiny sideX44 (aluminum with polyester coating)

This Makezine article outlines pros and cons of using the above mentioned types of copper tape. The con of tearing at the crease can be solved by using nylon backed copper tape.

Links to sources for purchase

Copper tape can be purchased in different widths and lengths. Here are some hobby stores where it can be purchased.

https://www.adafruit.com/products/1128 – 6mm width
https://www.adafruit.com/products/1127 – 25mm width
https://www.sparkfun.com/products/10561 – 5mm width
https://www.sparkfun.com/products/11081 – 2” width

Datasheet

I found a few different datasheets for copper tape with conductive adhesive from Adafruit, 3M and Sparkfun.

Using Copper Tape

When using copper tape, it is important to ensure solid connections in your circuit. That also means making sure the tape is flat! Bubbles or folds can cause interruption in connectivity and the flow of current. Below, I’ve experimented with addressing connectivity issues with paper circuits. Just like with a wired circuit, make sure ground and power tapes don’t intersect. Using masking tape or scotch tape works well as a barrier. This tutorial provides some tips for using copper tape.

Materials:

  • LED sequins (purchased from Adafruit)
  • 6mm width copper tape with conductive adhesive
  • a 9V battery
  • index cards
  • alligator clips

LED sequins: showing their positive and negative leads

  • Lab 1: Creating a Copper tape circuit

Here, a simple circuit was created to turn on an LED. In this lab, the leads of the LED are connected by placing a strip of copper tape over each lead. This proved to be an unstable connection. In figure 1 you can see that the surface of tape covering each LED lead is not flat or flat enough. In the video below, you will notice that when the LED is pressed, the light turns on. This indicates that there is insufficient contact between the copper tape and LED leads.

figure 1

Creating a larger conductive surface
A base layer of copper tape was added to the index card for both ground and power. The LED was secured to the circuit with additional copper tape strips (added to the surface of each lead). This was done ensuring smooth contact between the two sheets of tape. The LED was pressed firmly to secure contact with both top and bottom layers.

figure 2

Observation: The circuit with copper tape on both the back and front of the LED leads (figure 2) worked better to conduct electricity.

Conclusion: Connectivity matters. While the adhesive back is conductive, it is best to reinforce connectivity by ensuring connection to the copper tape’s surface. Also, it is very important to establish a flat surface of connection. Eliminate any folds or bubbles when laying the tape to establish a flat surface. A smooth flat surface ensures an uninterrupted flow of current.

  • Lab 2: Controlling two LEDs with a copper tape switch

With this experiment, I ensured the copper tape lined the back and front sides of each LED lead (as in the successful lab above). Ensuring the power and ground connections did not cross to create a short circuit was important. I used masking tape to cover intersecting layers.

Photo showing copper tape circuit with 2 LEDs. Masking tape was used to cover areas where ground and voltage connections intersected.

Examples using Copper Tape

  • Here is an example I found where copper tape is used as a speaker. As speaker was created using an analog paper circuit, coiled copper tape and a magnet.
  • This Instructables tutorial explores the technical, design, and aesthetic possibilities of 2-D, flexible audio speaker technology.
  • For my NIME performance (previewed below), I created a pop-up book and used copper tape for my circuitsand as a switch. I used the Makey Makey as my microcontroller and programmed each sound using MAX/MSP and Kontakt Player – essentially creating a MIDI-controller.

The Makey Makey attached to me (as ground) and to items connecting to it as power. In the case of the diagram, when the apple is touched the circuit is closed and the desired reaction occurs. In the case of my MIDI-controller, when I touched respective drums on the pop-up book, corresponding sound played. photo credit: dhmakerbus.com

 

When the drum is touched sound is played. The drum’s surface is made with copper tape (with conductive adhesive)

A closer look at the drum. You can see the surface with layers of copper tape, when touched acting as a switch. The single piece of tape to the right continues the circuit to the Makey Makey connection. Conductive fabric was added at the crease to ensure a steady connection was achieved. Necessary as elements in pop up books are folded.

Lessons learned from using copper tape for this NIME project:

Benefits of using copper tape

  • The flat thin material worked well for this application as I needed a flat seamless circuit.
  • Simple to use once the circuit design was mapped out.

Weaknesses of copper tape

  • It tears easily where the tape is folded. I resorted to enforcing these folds by adding a backing of conductive fabric.
  • Long pieces get tangled quite easily rendering the piece of tape garbage.
  • I experienced some connectivity issues with my switch. I added more lengths of tape but should have also created a weaved pattern to create a wider conductive surface (think how fabric is weaved – the conductive fabric did an excellent job at conducting electricity).

Citations

Makezine.com
Conducty.com
Copper Tape Tutorials
Sparkfun
nikitahuggins.com
thebalance.com
Wikipedia
Instructables

Light Controller

Design Challenge: Make a device to control an RGB light. The features of the device include:

  1. A control to turn the light on and off. When it turns on, it should retain the relative red, green, and blue brightness levels from when it was last turned on.
  2. The ability to fade each color channel (red, green, and blue) from off to full brightness.
  3. Fade level should be maintained when you release the fade controller.
  4. Fade should be interruptible by other controllers, e.g. on/off or another fade controller.
  5. The ability to fade the overall brightness of the light.

Code

Testing: This code explores turning on an LED with a switch. A potentiometer is then used to control the brightness of the LED. I worked with a white LED for this to ensure the code worked before connecting the RGB LED.

RGB LED Code:

 

Schematics

Design and Fabrication 

References
https://itp.nyu.edu/physcomp/labs/labs-arduino-digital-and-analog/analog-in-with-an-arduino/
http://cdn.sparkfun.com/datasheets/Components/LED/YSL-R596AR3G4B5C-C10.pdf
https://learn.adafruit.com/adafruit-arduino-lesson-3-rgb-leds/arduino-sketch

Game Controller

For this assignment, I created a game controller to play Atari’s Lunar Lander game in a browser. Using buttons, the controller sends W(up), S(down), A(left) and D(right) keypresses as a USB keyboard.

I used the MKR1000 board for this assignment. The device uses bluetooth connection but I connected it via USB directly to the computer for power and connection.

Code

#include “Keyboard.h”

const int upButton = 7;
const int downButton = 8;
const int leftButton = 6;
const int rightButton = 9;
//const int reloadButton = 4;
//const int enterButton = 5;
void setup () {
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
pinMode(leftButton, INPUT);
pinMode(rightButton, INPUT);
// pinMode(reloadButton, INPUT);
// pinMode(enterButton, INPUT);

//Serial.begin();
Keyboard.begin();
}

void loop() {

//keyboard button presses
if (digitalRead(upButton) == HIGH) {
Keyboard.press(‘w’); //send UP
delay(100);
}
else if (digitalRead(upButton) == LOW)
Keyboard.release(‘w’);

if (digitalRead(downButton) == HIGH) {
Keyboard.press(‘s’); //send DOWN
delay(100);
}
else if (digitalRead(downButton) == LOW)
Keyboard.release(‘s’);

if (digitalRead(leftButton) == HIGH) {
Keyboard.press(‘a’); //send LEFT
delay(100);
}
else if (digitalRead(leftButton) == LOW)
Keyboard.release(‘a’);

if (digitalRead(rightButton) == HIGH) {
Keyboard.press(‘d’); //send RIGHT
delay(100);
}
else if (digitalRead(rightButton) == LOW)
Keyboard.release(‘d’);

Circuit Design

Fabrication

Materials:

Matboard
Buttons
Wires
Bamboo box
Breadboard

Process:

Solder header pins to the MKR1000
Solder wires to the 4 buttons
Connect the buttons and MRK1000 to breadboard

 

Citations

Arduino mouse and keyboard libraries

Arduino mouse button control