Paper Nature Project (Revised)

My paper nature project consists of a wintery scene featuring a birch tree holding a tree house. Both of these objects are painted with conductive paint and attached to the MaKey MaKey. Each object is connected to a different port on the MaKey MaKey, which has been reprogrammed to produce letters instead of the original up, down, left, and right. Additionally, the MaKey MaKey has been reprogrammed to respond to capacitive touch instead of resistive touch, so the ground does not need to be used. The tree is triggered when the letter “b” is pressed and the tree house is triggered when the letter “c” is pressed. The light inside the tree house is a hacked light that I used inside a Jack-O-Lantern on Halloween. I rewired the light to use an Arduino to power it for a specific amount of time and got rid of the switch and disk battery that the light came with. The tree uses 40 LEDs taken from a digital LED strip that utilize the same Arduino to light a random LED every 150 milliseconds to simulate the sparkling of snow. The silhouette of the girl has copper tape running the back of it, which triggers the MaKey MaKey to type an “a”, which then triggers the Arduino to light the eight Neopixles that are arranged like behind the girl. The Neopixles are animated to look like footsteps to outline the path the girl has taken through the snow. In order to control all three different parts of this project I used the Serial application in Arduino as the interface between the MaKey MaKey and my Arduino Uno board. I ran into a bit of a problem here because I could not send a keyboard input without pressing the “enter” key along with whatever letter I was trying to type. To fix this I wrote a program in the Processing language that took the information from the Arduino Serial output and bypassed the need to press send, while also giving a user friendly interface to control the lights.

Code For Capacitive Touch:

#include <Keyboard.h>

#define NUM_INPUTS 18
#define KEY_ENTER Keyboard.press(

int keys[NUM_INPUTS] = {
'a','b','c','\n','g','m', // top of makey makey board (up, down, left, right, space, click)
'h','w','e','r','t', 'y', // left side of female header
'z','x','c','v','b','n' // right side of female header
};

int capThresholds[NUM_INPUTS] = {
2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
};

int pinNumbers[NUM_INPUTS] = {
12, 8, 13, 15, 7, 6, 
5, 4, 3, 2, 1, 0, 
23, 22, 21, 20, 19, 18 
};

int outputPin = 14;

boolean pressed[NUM_INPUTS];

void setup(){
Keyboard.begin();
for (int i=0; i<NUM_INPUTS; i++) {
pressed[i] = false;
}

pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);

}

void loop() { 
for (int i=0; i<NUM_INPUTS; i++) { // for each pin
if (readCapacitivePin(pinNumbers[i])>capThresholds[i]){ // if we detect a touch on the pin
if (!pressed[i]) { // and if we're not already pressed
Keyboard.press(keys[i]); // send the key press
pressed[i] = true; // remember it was pressed
}
} 
else { // if we don't a detect touch on the pin
if (pressed[i]) { // if this key was pressed before
Keyboard.release(keys[i]); // send the key release
pressed[i] = false; // remember we are not pressed
} 
}
}

boolean anythingIsPressed = false;
for (int i=0; i<NUM_INPUTS; i++) { 
if (pressed[i]) {
anythingIsPressed = true;
}
}

if (anythingIsPressed) {
digitalWrite(outputPin, HIGH);
} 
else {
digitalWrite(outputPin, LOW);
}

}

uint8_t readCapacitivePin(int pinToMeasure) {
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;

uint8_t cycles = 17;
if (*pin & bitmask) { 
cycles = 0;
}
else if (*pin & bitmask) { 
cycles = 1;
}
else if (*pin & bitmask) { 
cycles = 2;
}
else if (*pin & bitmask) { 
cycles = 3;
}
else if (*pin & bitmask) { 
cycles = 4;
}
else if (*pin & bitmask) { 
cycles = 5;
}
else if (*pin & bitmask) { 
cycles = 6;
}
else if (*pin & bitmask) { 
cycles = 7;
}
else if (*pin & bitmask) { 
cycles = 8;
}
else if (*pin & bitmask) { 
cycles = 9;
}
else if (*pin & bitmask) { 
cycles = 10;
}
else if (*pin & bitmask) { 
cycles = 11;
}
else if (*pin & bitmask) { 
cycles = 12;
}
else if (*pin & bitmask) { 
cycles = 13;
}
else if (*pin & bitmask) { 
cycles = 14;
}
else if (*pin & bitmask) { 
cycles = 15;
}
else if (*pin & bitmask) { 
cycles = 16;
}

*port &= ~(bitmask);
*ddr |= bitmask;

return cycles;
}

Code For Lights:

#include <FastLED.h>

int incomingByte;

CRGB treeleds[39];
CRGB footstepleds[8];

void setup() {

  Serial.begin(9600);
  pinMode (12, OUTPUT);
  FastLED.addLeds<WS2812B, A3> (treeleds, 39);
  FastLED.addLeds<NEOPIXEL, A5 > (footstepleds, 8);
  
}

void loop() {
  
  if (Serial.available() > 0) {
    
    incomingByte = Serial.read();

    if (incomingByte == 'c') {

      digitalWrite (12, HIGH);
      delay(6000);
      digitalWrite(12, LOW);
      
    }

    if (incomingByte == 'b') {

      long pixel = random(0, 40);
      
      for (int i = 0; i <= 40; i++) {

        long pixel = random(0, 40);
        treeleds[pixel] = CRGB:: White;
        FastLED.show();
        delay(150);

        treeleds[pixel] = CRGB::Black;
        FastLED.show();
      }
    }

    if (incomingByte == 'a'){

     for (int i = 0; i > 1; i++); {

        footstepleds[0] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[0] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[1] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[1] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[2] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[2] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[3] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[3] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[4] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[4] = CRGB::Black;
        FastLED.show();
        delay(500);
        Serial.println("5");

        footstepleds[5] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[5] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[6] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[6] = CRGB::Black;
        FastLED.show();
        delay(500);

        footstepleds[7] = CRGB::Blue;
        FastLED.show();
        delay(500);

        footstepleds[7] = CRGB::Black;
        FastLED.show();
        delay(500);
      
      }
    }
  }
}

Processing Code:

import processing.serial.*;

Serial port;

void setup() {

size(500, 500);
port = new Serial(this, Serial.list()[0], 9600);

}

void draw() {

fill(62, 191, 237);
rect(0, 0, 600, 600);

}


void keyPressed() {
if (key == 'a') {

port.write('a');

}
if (key == 'b') {

port.write('b');

}

if (key == 'c') {

port.write('c');

}
else {

port.write('L');

}
}

Final Product:

Leave a Reply