Projects – 62-362 Fall 2021 https://courses.ideate.cmu.edu/62-362/f2021 Electronic Logics && Creative Practice Tue, 06 Jun 2023 14:35:54 +0000 en-US hourly 1 https://wordpress.org/?v=5.7.11 90% documentation https://courses.ideate.cmu.edu/62-362/f2021/90-documentation/ Fri, 17 Dec 2021 23:18:28 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=12103 Sorry, but you do not have permission to view this content. ]]> Sorry, but you do not have permission to view this content. ]]> Igneous https://courses.ideate.cmu.edu/62-362/f2021/igneous/ Mon, 13 Dec 2021 13:27:10 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=12041 Description

Inspired by the Giant’s Causeway in Ireland, we arranged 300 white cylindrical candles into a mountain terrain formation that reacts slowly to audience interaction. Users were invited to light candles and add dye chips (choice of 8 colors) to pools of melted wax, shaping and coloring the terrain. The terrain “erodes” and transforms organically throughout the night as a result of the collective contributions. Our piece acts as a memorial of the community experience of creating something. A projection on the ceiling of CFA’s Main Hall streamed live video of the piece and users interacting with it, encouraging those inside the hall to come outside and contribute to it as well. 

Early in the exhibition. Only a few candles have been lit and dyed.

People interacting with the piece. Demonstrates overall scale.

Close up of the lit candles and how the dye flows with the melting wax.

Projection of the piece in the hall.

The piece near the end of the exhibition.

Final results after the entire exhibition.

As the dyed candles melted, the wax built up, creating interesting layers and formations.

Chunks of colored solidified wax and their patterns.

Video

Time lapse of the piece over the course of the event:

Process

We experienced some setbacks while assembling our project, and had a few lucky breaks in our final, public installation. 

Andy testing his hexagonal candle cutter.

Testing the chip dyes.

We initially planned to imitate the shape of the columns in the Giant’s Causeway exactly, filling a 24”x36” rectangle with about 250 pounds of hexagonal wax candles. This initial plan’s footprint downscaled to 18”x24” when our proposed budget went above $300, and the hexagons had to be rethought after we had trouble finding thin candles in that shape.

Since we wanted a large “mountain” terrain, we needed a decently-sized base to build on. Using images from the actual Giant’s Causeway, we calculated that the height couldn’t go over ⅔ of the longest base or else it’d look weird. We did our initial planning using this metric plus the height of the tallest bulk candles we could find. This design turned out to be ~200 pounds of wax, which seemed unwieldy and needlessly expensive. We chose a smaller base, and someone came up with the idea of using platforms on the inside so we could avoid making the entire mountain out of solid wax. The project seemed reasonably priced at this size, and would still look proportional when built. 

At this point we were still planning on creating a bunch of hexagonal candles from circular ones. In initial plans to make the hexagons, we thought about methods like using long, hexagonal PVC tubes as molds (sold only on Alibaba, so shipping took too long), 3D printing or silicone molds (really slow), and cutting candles down to shape (slow, bad quality). Each of the mold approaches would have taken several days of boiling, pouring, casting, and cooling, and cutting each one seemed silly, time-consuming, and dangerous. Not to mention all the inevitable quality problems with manually making all our own candles! We settled on buying circular candles and pushing them through a hexagon cookie cutter. The cheapest site we could find sold 200 candles for $80, and we needed around 350 candles post-cut to fill our platform. 

We placed the order right before everyone left for Thanksgiving and waited with bated breath. When we returned, we found the candles were of the expected size, but did not realize that the quantity was wrong. To make hexagons, we created a prototype cutter using wood, epoxy, and bent sheet metal. This rig could cut warmed candles by simply pushing them through by hand. While testing the candle cutter, we noticed that we were missing around a hundred candles, which meant we would not be able to fill our base with hexagons. Especially since they shrink and pack closer when cut. Our hexagon idea died here, and to everyone’s relief: the hexagon tile cutter took a lot of force! Going with the cylinders saved a lot of time and looked almost equivalent, but we still needed to adjust the heights of every candle. 

Screwing the cement board platforms into the wooden supports.

Gluing the candles into place.

Just started the cutting and gluing, so only the top candles have been worked on. The rest of the candles are arranged into place.

Davine came up with a method using a box cutter and rolling it over an end of the candle until it cracked off. Cut-offs of the base could be glued onto another candle, and allowed us to vary their heights for a more organic look. We used hot glue to put them together, then used it again to glue the entire candle to the platform it was sitting on to secure the mountain. 

While the mountain was being built, some of us prepped the platform and cart for the final installation. The base is a large sheet of plywood with standing segments of two-by-four drilled into it; on top of these lie the platforms. Since the platforms are wick-level with individual candles, we chose to make them out of a non-flammable material. Luckily, Zach had some cement board that was perfect for this. We scored it with a carbide knife, then broke it by bending it. 

Breaking the cement board into the mountainous back of the piece.

Created cardboard separators for the dishes and put the dye chips into them.

We also used cement board later to fill in a large gap when we found out that we didn’t have enough candles to cover one side of the mountain. Once all the platforms and wood bits were screwed in, we co-opted Zach’s rolling cart to carry it to CFA. We put a cloth canvas over it, then another solid sheet of black aluminum foil on top of that to catch any stray wax strips. This turned out to be invaluable later. When we finished assembling the mountain, we carefully carried it on top of the cart and placed it over the aluminum protection layer. Leah and Davine made holders for the dyes, and Zach gifted us these long matches that were in his house for the participants to light candles with. 

Everything is finished, and we’re heading out to place it at our exhibition.

Once every gap was filled and no internal structure poking out, we wheeled it over to CFA. We lit a few candles first just to show people how to interact with our mountain, but most people had no trouble at all figuring it out. Lots of people came by and lit candles, most adding dyes and watching the streams. We did not anticipate the wax “rivers” that would form from flowing dye, but those were very mesmerizing. We also did not expect the wax from 300 candles to begin leaking into the internal structure, and it started leaking out onto the platform. Here’s where the aluminum came into play; we were able to round up the corners and contain the wax without dropping it all over the ground. While it did not save Zach’s pants, we later found that the buildup of wax layers created many beautiful colors arranged across different layers, much like a sedimentary rock. The dyes worked great. Mother nature felt kind that night, and it wasn’t too cold or windy for the most part. It even helped; the inside was so cacophonous that many people preferred to be outside anyway. Davine put together a last-minute project setup, streaming from outside onto the ceiling in the Great Hall to remind everyone inside that we were outside. Overall, everyone who came by had a great time lighting and dying candles and what it created was truly beautiful.

]]>
Project No. 3: Dancing Cloud https://courses.ideate.cmu.edu/62-362/f2021/project-no-3-dancing-clouds/ Sun, 12 Dec 2021 21:31:04 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11994

A group of friends tries to activate all the sections of the balloons at once

In-Progress Media

This image shows us testing colors on our maquette. We decided to get rid of the red and green colors and mostly keep yellow, white, purple and blue to symbolize the colors of a thunderstorm.

Testing out the sensitivity of the force sensitive resistors.

Here we were laser cutting the box to hold our Arduino, breadboard and wires.

Judenique setting up connections inside the laser cut box.

All the wires from the sensors leading to the main box

Olivia working on putting the sensors under the stickers on the steps

The decals on the stairs installed

Here is after we realized that our plan to use velcro to attach the eye hooks to the wall was not going to work and we needed to use aluminum tape to secure the balloons to the walls.

Experimenting with different colors before the event

Dancing Clouds in Action

Close up of the balloons: the leds are controlled by the pressure-sensitive resistors

Balloons are up and installed, currently there is no power running

The aftermath of the project: only the LEDs and string remain

Description

The Dancing Cloud is an installation made up of balloons illuminated by a colored LED strip. The colors of these balloons is controlled by people stepping on force-sensitive resistors placed along the stairs in the CFA Great Hall. When there are no people stepping on these steps, the colors react to sounds in the environment.

The LED strip is wrapped along a 16 feet rope spanning from the Zebra lounge to the other side of the wall along the main entrance of CFA. The balloons are wrapped and tied around this long piece of rope. The rope is held up by hooks screwed into 2 wooden blocks which we attached to the walls around 9 feet high. The force-sensitive resistors are placed on the stairs covered by colorful decals, so that people know where to step to trigger a change in color. We have wires attached along the wall and floors coming from the string of balloons, the force sensitive resistors, the microphone and the power supplies to the laser cut box where everything is connected together with the Arduino and breadboard.

Process Reflection

What worked well?

The waterproof LEDs were blunt and worked well to not cause any balloons to pop throughout the time installation was running. The entire circuit also ran for a long time without running into issues. Furthermore, the balloons retained their size over 2 days allowing us to get started with the installation process before the day of the show.

Selecting specific white balloons that weren’t fully opaque, and testing them with the maquette helped us figure out how well the LED lights shone through the balloons. Our choices were well made because the balloons appropriately replicated the colors of the LEDs. The dark atmosphere in the CFA further helped our balloons stand out.

Our installation also looked mostly clean and very presentable. We were able to restrict the wires from the decals to the stairs to the edges such that it didn’t interfere with people climbing up the steps. We also tied the string of balloons high enough so that people did not crash into it. It ended up being at a good height where it was very noticeable as well.

Challenges faced and what we could have done better?

We encountered issues working with the command strips to attach the blocks to the wall. Specifically, it was an issue trying to get it working high up on the wall where we could not apply enough force in the right way. We had to resort to using aluminum tape. On one hand, this tape was quite strong and held up the blocks well. On the other hand, it did not look very pretty. In hindsight, it would have been a much better idea to test the command strips ahead of time to make sure they worked on the day of installation.

One of the other issues we noticed while the installation was in place was that the force sensitive resistors under the decals did not work as well as we hoped. With shoes like heels and even some regular shoes, the sensors did not always sense something unless stepped on in a certain way. However, when it worked, it did keep people occupied to watch themselves influence the colors of the balloons. We even had groups of people who tried to light up all sections of the balloons by stepping on all of the decals. If we had more time, we could have tried to test several decals and materials used before we installed them.

We also received some feedback suggesting some way to let people know what our installation was. We realized it may have been difficult for people walking downstairs to realize what the decals they stepped on did. People also may not have known that the balloons were reacting to sound from the environment. Since the sound from the environment was random, the balloons changing colors might have also seemed random unless there was a large spike in sound. Furthermore, the presence of so many other installations may have resulted in people not realizing if it was connected to something else like the decals. Having some sort of a sign near the stairs explaining our installation may have resulted in more people interacting with it.

What change could we have made to take our project in a different direction?

We could have decided to implement the LEDs and force sensitive resistors in many different ways to create a similar effect to our project. We could have designed a smaller scale installation that looked more like an object rather than a large mass hanging above our heads. We considered the idea of using fabric for our project so perhaps we could have covered the LEDs in fabric and created a similar glowing effect that the balloons had. The way that people experience our project would have been very different if we had made something as a smaller scale but overall we are happy with the success we had with the Dancing Cloud.

Code

  // Group Judge My Vow
  // Dancing Clouds
  // Creats an instance of the Pololu LED strip
  // Uses 6 force sensitive resistors and 1 Adafruit mic
  // The force sensitive resistors and mic are inputs for the led strip
  // where the sound received is a countinuous change and the 
  // force sensitive resistors change sections of the strip to 


#include <PololuLedStrip.h>

// Create an ledStrip object and specify the pin it will use.
PololuLedStrip<12> ledStrip;

// Create a buffer for holding the colors (3 bytes per color).
#define LED_COUNT 300
rgb_color colors[LED_COUNT];

const int FCR0 = A0; //defining analog sensors
const int FCR1 = A1;
const int FCR2 = A2;
const int FCR3 = A3;
const int FCR4 = A4;
const int MIC = A5;
const int FCR5 = 5;
bool priority = true;

int forceVal0, forceVal1, forceVal2, forceVal3, forceVal4, forceVal5;

const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

void setup() {
  pinMode(FCR0, INPUT);
  pinMode(FCR1, INPUT);
  pinMode(FCR2, INPUT);
  pinMode(FCR3, INPUT);
  pinMode(FCR4, INPUT);
  pinMode(FCR5, INPUT);
  Serial.begin(9600);
}

void loop() {

  // setting all the values of the force sensitive resistors
  forceVal0 = analogRead(FCR0);
  forceVal0 = map(forceVal0, 0, 1023, 0, 255);
  delay(10);

  forceVal1 = analogRead(FCR1);
  forceVal1 = map(forceVal1, 0, 1023, 0, 255);
  delay(10);

  forceVal2 = analogRead(FCR2);
  forceVal2 = map(forceVal2, 0, 1023, 0, 255);
  delay(10);

  forceVal3 = analogRead(FCR3);
  forceVal3 = map(forceVal3, 0, 1023, 0, 255);
  delay(10);

  forceVal4 = analogRead(FCR4);
  forceVal4 = map(forceVal4, 0, 1023, 0, 255);
  delay(10);

  forceVal5 = digitalRead(FCR5);


  // Sensors take priority
  // If they are not pressed, sound input is received
  if (!priority) {
    unsigned long startMillis = millis(); // Start of sample window
    unsigned int peakToPeak = 0;   // peak-to-peak level

    unsigned int signalMax = 0;
    unsigned int signalMin = 1024;

    // collect data for 50 mS
    while (millis() - startMillis < sampleWindow) {
      sample = analogRead(MIC);
      if (sample < 1024) { // toss out spurious readings
        if (sample > signalMax) {
          signalMax = sample;  // save just the max levels
        }
        else if (sample < signalMin) {
          signalMin = sample;  // save just the min levels
        }
      }
    }
    peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
    double volts = ((peakToPeak * 5.0) / 1024) * 10;  // convert to volts

    // map the sound input
    int soundc = map(volts, 0, 20, 0, 255);

    // when the sound input is above a certain threshold, the led string flashes white
    if (soundc > 340) {
      for (int i = 0; i < LED_COUNT; i++) {
        colors[i] = rgb_color(255, 255, 255);
      }
      ledStrip.write(colors, LED_COUNT);
      delay(100);

      for (int i = 0; i < LED_COUNT; i++) {
        colors[i] = rgb_color(0, 0, 0);
      }
      ledStrip.write(colors, LED_COUNT);
      delay(100);
    }

    // the colors are defined by the input sound converted to rgb
    else {
      for (uint16_t i = 0; i < 300; i++) {
        byte x = (soundc >> 1) - (i << 3);
        colors[i] = hsvToRgb(soundc * 5 - (i * 3), 255, 255);
      }
    }

    // Write the colors to the LED strip.
    ledStrip.write(colors, LED_COUNT);
    delay(10);
  }

  // Chack if the pressor sensors are activated
  // Light up sections of the balloon based on a specific resistor
  else {
    //FSR0
    if (forceVal0 > 10) {
      for (uint16_t i = 0; i < 50; i++) {
        colors[i] = rgb_color(255, 255, 255);
      }
      for (uint16_t i = 200; i < 250; i++) {
        colors[i] = rgb_color(255, 218, 0);
      }
    }
    else {
      for (uint16_t i = 0; i < 50; i++) {
        colors[i] = rgb_color(0, 0, 0);
      }
      for (uint16_t i = 200; i < 250; i++) {
        colors[i] = rgb_color(0, 0, 0);
      }
    }

    //FSR1
    for (uint16_t i = 50; i < 100; i++) {
      if (forceVal1 > 10) {
        colors[i] = rgb_color(0, 0, 255);

      } else {
        colors[i] = rgb_color(0, 0, 0);
      }
    }
    for (uint16_t i = 250; i < 300; i++) {
      if (forceVal1) {
        colors[i] = rgb_color(0, 255, 255);

      } else {
        colors[i] = rgb_color(0, 0, 0);
      }
    }

    //FSR2
    for (uint16_t i = 100; i < 150; i++) {
      if (forceVal2 > 10) {
        colors[i] = rgb_color(75, 0, 103);

      } else {
        colors[i] = rgb_color(0, 0, 0);
      }
    }
    for (uint16_t i = 250; i < 300; i++) {
      if (forceVal2) {
        colors[i] = rgb_color(0, 255, 255);
      }
    }

    //FSR3
    for (uint16_t i = 0; i < 50; i++) {
      if (forceVal3 > 10) {
        colors[i] = rgb_color(255, 255, 255);
      }
    }
    for (uint16_t i = 150; i < 200; i++) {
      if (forceVal3 > 10) {
        colors[i] = rgb_color(255, 200, 0);

      } else {
        colors[i] = rgb_color(0, 0, 0);
      }
    }

    //FSR4
    for (uint16_t i = 200; i < 250; i++) {
      if (forceVal4 > 10) {
        colors[i] = rgb_color(255, 140, 0);
      }
    }
    for (uint16_t i = 100; i < 150; i++) {
      if (forceVal4 > 10) {
        colors[i] = rgb_color(255, 0, 255);
      }
    }

    //FSR5
    for (uint16_t i = 250; i < 300; i++) {
      if (forceVal5) {
        colors[i] = rgb_color(0, 255, 255);
      }
    }
    for (uint16_t i = 100; i < 150; i++) {
      if (forceVal5) {
        colors[i] = rgb_color(75, 0, 130);
      }
    }
    for (uint16_t i = 0; i < 50; i++) {
      if (forceVal5) {
        colors[i] = rgb_color(30, 144, 225);
      }
    }

    // Write the colors to the LED strip.
    ledStrip.write(colors, LED_COUNT);

    delay(10);

  }

  // determines which input is currently being received
  bool f0 = (forceVal0 > 10);
  bool f1 = (forceVal1 > 10);
  bool f2 = (forceVal2 > 10);
  bool f3 = (forceVal3 > 10);
  bool f4 = (forceVal4 > 10);
  bool f5 = forceVal5;

  priority = (f0 || f1 || f2 || f3 || f4 || f5);
}

// code from example library for neopixels
rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v)
{
  uint8_t f = (h % 60) * 255 / 60;
  uint8_t p = (255 - s) * (uint16_t)v / 255;
  uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255;
  uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255;
  uint8_t r = 0, g = 0, b = 0;
  switch ((h / 60) % 6) {
    case 0: r = v; g = t; b = p; break;
    case 1: r = q; g = v; b = p; break;
    case 2: r = p; g = v; b = t; break;
    case 3: r = p; g = q; b = v; break;
    case 4: r = t; g = p; b = v; break;
    case 5: r = v; g = p; b = q; break;
  }
  return rgb_color(r, g, b);
}

 

 

]]>
Pipe Dream Final Documentation https://courses.ideate.cmu.edu/62-362/f2021/pipe-dream-final-documentation/ Wed, 08 Dec 2021 18:04:15 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=12032 Pipe Dreams

 

close-up of one of the camera/microphone pipes in the performance space

close-up of the melon

Narrative Description:

A parasitic pipe organism has taken over CFA. The pipes spread through the walls from the Alumni Concert Hall, where they collect and display video and audio information for visiting humans to hear. These ducts emerge from the floor in all of their aluminum glory; some are more bendy and allow the humans to pick them up to listen, others are self-supporting. The pipes allow humans to experience the goings-on of the main hall without all of the busyness, and also allow them to experience performances from various locations all in the same space.

Hints of the CFA pipe infection was first discovered by Henry Hornbostel himself in May of 1923, but it wasn’t tracked until the late 1980s when a group of paranormally-inclined students decided to track and journal the progress of the spreading infection. They called themselves the “Brazil Pipe-Watching Society” or BPWS. At the time, the infection was contained entirely inside the walls themselves and the organism’s data-transfer capabilities were limited to crude acoustics. In the late 2010s, the organism became capable of mimicking CCTV video surveillance systems, and small video-capture pipes burst through the walls into the main hall. Around this time, a government research team from Southern New Zealand happened upon the student journals and decided to investigate for themselves due to fears for the confidentiality of New Zealand’s rich and secretive subterranean avocado industry. In December of 2021, the organism’s heart suddenly burst forth through the floor of the Alumni Concert Hall, where it had been growing dormant for nearly a century. The New-Zealand researchers responded fast, and fully eradicated the organism from CFA, much to the dismay of students of BPWS. Since then, little remains of the ductwork organism, just discarded foil and limbs which will safely remain in Hunt A5 for many years to come, or until Zac gets annoyed.

Process Photos:

we got the stuff !

Mockup of pipe bases, includes both the less flexible and flexible ducts

planning out the final layout

wall pipe mockup

on the way to install everything

Finished making all of the bases and supports for the bendy pipes

testing various ways of supporting bendy pipes. This iteration didn’t work

Process Reflection:

The process was highly reflective, primarily due to the extensive use of aluminum foil and reflective tape.

We ended up being very happy with the design concept for the installation, but struggled a bit with execution. We were able to set up all of the pipes, but a large portion of the installation’s electronics failed. A major issue we faced was just lack of time towards the end, mostly because we changed concepts a few times leading up to the installation week, and didn’t have enough time to properly test everything before the final install.

The installation process itself ended up being far more chaotic than we expected, primarily because we didn’t have room access until the show was actually happening. The scale of the other installations was larger than we thought, so testing the camera/microphone pipes and running wires while the show was happening was really difficult.

The electronics turned out to be very difficult mostly just because of scale. An audio cable is easy, but 300ft of audio cables is not. In the end, a lot of little bits failed because they were rushed and we didn’t test in the actual setting extensively enough. The audio cables were likely shorting occasionally which would kill the microphones, and the thick walls of CFA made the video signal on the melon too weak to work (the vertical/horizontal sync just refused to work if the signal wasn’t really strong). Ideally we would have tested all of these things beforehand, but because of time we could not.

We did however learn that even if your thing doesn’t work you can still show it as long as you have good lighting, which we were lucky enough to bring along with us. Although it definitely would have been even cooler if everything functioned, people still enjoyed looking at the project, which is definitely some form of success. Two of the video feeds worked which was great, but the audio breaking was super unfortunate.

 

]]>
Group Check in: Andy Davine Leah https://courses.ideate.cmu.edu/62-362/f2021/group-check-in-andy-davine-leah/ Mon, 22 Nov 2021 18:10:42 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11953 To solve our problem of having to cast so many candles, we’ve found a two-part alternative:

  • use foam core blocks to create base height variation; we can reduce the max candle height significantly while achieving  great overall height variation for our landscape
  • start with pre-bought cylindrical candles (we can buy them in bulk; don’t need to deal with tedious wick and melt calculations) and cut/shave them down into hexagons– might be a bit messy/imperfect, but that might create a more organic form that reads less religious

Other updates:

  • Because our pre-bought cylindrical candles will be un-dyed, we’ll buy colored wax dye chips for participants to sprinkle into the melted wax pools while the candles are lit– this is now an additional input.
  • If we have to be installed outside, we’ll have a camera streaming video of the installation projected in the space (no particular preference of location as of now) so we have a physical presence inside the event.
  • If we have to be installed outside, we’d like to be inside one of the concave nooks beside the main entrance; we’d likely need some sort of wind screen.

Materials:

 

]]>
Arrows: Group Check In (Judenique, Olivia, Tushhar) https://courses.ideate.cmu.edu/62-362/f2021/arrows-group-check-in-judenique-olivia-tushhar/ Wed, 17 Nov 2021 05:48:07 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11950 Dancing Cloud

Inputs: Pressure and/or Sound

Outputs: LEDs inside balloon arch

This project is an interactive installation consisting of a pressure mat similar to dance dance revolution/twister. When a person steps on this mat, it results in activating lights connected to a balloon arch. The lights activated depend on where the person steps. When there is nobody on the pressure mat, the lights react to the sound from the background or another project. Ideally, this reaction will be based on frequencies. If not, it is likely to be based on volume. The balloon arch will have the lights both inside and around the balloons.

This project is intended to be situated by the stairs near the zebra lounge. Any people passing by can interact with it.

This idea was inspired from brainstorming about balloons and potential ways to detect passerbys. Reacting to sounds through their frequencies and use of force sensitive resistors is inspired from an earlier project of one of the groupmates.

Block Diagram:

List of Materials

  • Force sensitive resistors (ideate)
  • Footprint Decals to put over the resistors (diy)
  • Balloons (amazon or ideate)
  • LED strip/ string lights/ neopixels (ideate)
  • Microphone (ideate)
  • Arduino + Wiring (ideate)

Sketch:

]]>
Arrows: Project Ideation (Judenique, Olivia, Tushhar) https://courses.ideate.cmu.edu/62-362/f2021/arrows-project-ideation/ Mon, 15 Nov 2021 02:17:09 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11890 Sentient Chandelier

Inputs: Motion or Sound

Outputs: Actuation via motor

This project is an installation that responds to the life inside of CFA by creating a wavelike motion in the negative space of the stairwell by actuating strings and hanging objects. The installation will be located inside one of the CFA stairwells. Dozens of strings will be attached to a sort of beam that sits between the railings on either side of the stairs at the mezzanine level. As people walk up and down the stairs, an ultrasonic ranger will detect their motion and a motor will activate and shift/rotate the beam attached to the strings to create the wavelike motion. Another possibility for an input besides using motion could be sound since there will be a huge range of sound levels going on during the night of installation.

The strings would hang all the way down to the main level where the Great Hall is so that people can experience the movement from in front of the stairwell as well. The stairwell is a perfect place for a project to respond to sound/movement since people are constantly passing through it. This project was inspired by the flocking birds video in the way that we hope the strings will move with a sense of cohesion and fluid motion. As the people on the steps notice that their movement is causing the chandelier to move, the sequence through the stairwell becomes more interesting.

Block Diagram:

List of Materials: 

  • Ultrasonic Ranger (ideate)
  • Arduino + Wiring (ideate)
  • Motors (ideate)
  • String and acrylic (ideate)

Sketch:

Dancing Cloud

Inputs: Pressure and/or Sound

Outputs: LEDs inside balloon arch

This project is an interactive installation consisting of a pressure mat similar to dance dance revolution/twister. When a person steps on this mat, it results in activating lights connected to a balloon arch. The lights activated depend on where the person steps. When there is nobody on the pressure mat, the lights react to the sound from the background or another project. Ideally, this reaction will be based on frequencies. If not, it is likely to be based on volume. The balloon arch will have the lights both inside and around the balloons.

This project is intended to be situated by the stairs near the zebra lounge. Any people passing by can interact with it.

This idea was inspired from brainstorming about balloons and potential ways to detect passerbys. Reacting to sounds through their frequencies and use of force sensitive resistors is inspired from an earlier project of one of the groupmates.

Block Diagram:

List of Materials

  • Force sensitive resistors (ideate)
  • Footprint Decals to put over the resistors (diy)
  • Balloons (amazon or ideate)
  • LED strip/ string lights/ neopixels (ideate)
  • Microphone (ideate)
  • Arduino + Wiring (ideate)

Sketch:

]]>
Project No. 2: Success in Their Eyes https://courses.ideate.cmu.edu/62-362/f2021/project-no-2-success-in-their-eyes/ Sat, 13 Nov 2021 00:54:23 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11749

Leah’s hands positioned over color sensor; the box glows green

The four vases made out of plastic and painted matte black and gold

A scan is complete and the waterfall starts

The initial amount of water in each vase; the pump can be seen in the fifth vase

This white box contains the color sensor, the neopixels, and the switch to activate the sensor

This black box located underneath the pillar holds the Arduino and wiring for the pump

Description

There is a small white box with a black switch on a white pillar. The small white box is connected to a black structure with 5 black and gold vases each containing water. The white box glows blue until the user flips the switch. Once the switch is flipped, the white box will flash green and give the user some time to position their hands. The user holds their hand over the white box and waits for the color scan. The waterfall will start running and lighter skin tones will cause the waterfall to run longer. When the water stops flowing, the box will glow blue again.

Project Reflection

First time wiring up the color sensor

The completed base of the waterfall made of styrofoam

Failed attempt of making the waterfall vases with concrete

Plastic vases are chosen as a substitute for the concrete ones

The waterfall base is coated in the first layer of concrete (works better than the original vases!!)

The vases are painted black with a dash of gold, next step is to paint the base

 

Success In Their Eyes is a project that challenges us to think about how colorism impacts our society and many others throughout the world. The idea developed from the past Jim Crow laws, segregated water fountains, as well as the use of skin lightening cream in several cultures. Throughout the creation, I faced several challenges, not only in the physical design but also in the way I wanted it to be perceived. I completed the technological part very early in the process, though calculating the lightness of color was a struggle. The examples from the Adafruit TCS library helped a lot and with some tweaking of the gain, it was functional! I was able to present the pump and scanner for our first checkpoint.

The biggest hurdle was creating the physical waterfall. I hadn’t given much thought to how the waterfall should look which was a mistake in the process. I finally settled on a Youtube video as my tutorial. I also watched other videos that used concrete to construct the vases, and I was inspired to try. Unfortunately, the process was problematic; the concrete mix was the wrong type and consistency which caused the vases not to dry. The backup plan was to use plastic mason jars and restructure them to the style I wanted. Next time I attempt working with concrete, I wouldn’t rush the research so I end up with something useable. The base was made out of styrofoam and creating it was fairly simple. The complication here was the tube. It wasn’t flexible enough to curve and fit in the base but a simple replacement solved that problem.

The pump and vases all were water tested and worked well individually. After putting them all together for the final product and adding water, I found out there was a major leak in the first and last vase. This was extremely disappointing since I spent so long creating the waterfall piece by piece. In the future, I would like to find a way to patch the problem areas, but recreating the whole waterfall might be easier.

The last struggle was thinking of how users would experience this project. Originally, I wanted the users (most likely in a group) to play around with it and discuss why some people saw the waterfall flow longer. They would come to the realization that one of the visible differences in the group was the color of their skin, and the role it plays in how people are viewed. Additionally, I did not solve how to get users to present their hands without the color scanner being obvious. Given additional time, I would test the completed version with others and take into account the thoughts they have. While it would have been ideal to finish without issues, I loved every moment of fabricating this project and seeing it come to life.

Code

// Judenique Auguste
// Success in Their Eyes
// Creates an instances of the Adafruit Neopixels and Adafruit Color Sensor
// The Neopixels are used to give the status of the waterfall through color
// The Color Sensor is used to caluculate the brightness of the user's skin
// A digital signal is sent to the pump which turns it on and off for a period of time

// Use of Neopixel library example code and Color Sensor library example code

#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <Adafruit_NeoPixel.h>

#define pump 4
#define button 7
#define PIN 6
#define NUMPIXELS 8
#define BRIGHTNESS 50
int pumpState = LOW;
int buttonState;

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_614MS , TCS34725_GAIN_16X);

void setup() {
  Serial.begin(9600);
  pinMode(pump, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  pixels.begin();
  buttonState = digitalRead(button);


  if (tcs.begin()) {
    //Serial.println("Found sensor");
    tcs.setInterrupt(true);
    pixels.begin();
    pixels.setBrightness(BRIGHTNESS);
    buttonState = digitalRead(button);
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1);
  }
}

void loop() {
  // fountain is idle
  for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));
    pixels.show();
  }

  float red, green, blue;

  if (buttonState != digitalRead(button)) {
    buttonState = digitalRead(button);
    pixels.clear();
    // the wait period til scan to position
    int position_time = 0;
    while (position_time < 3) {
      for (int i = 0; i < NUMPIXELS; i++) {
        pixels.setPixelColor(i, pixels.Color(0, 255, 0));
        pixels.show();
      }
      delay(1000);

      for (int i = 0; i < NUMPIXELS; i++){
        pixels.setPixelColor(i, pixels.Color(0, 0, 0));
        pixels.show();
      }
      delay(1000);
      position_time++;
    }
    tcs.setInterrupt(false);
    delay(200);
    tcs.getRGB(&red, &green, &blue);
    int colorTemp = tcs.calculateColorTemperature(red, green, blue);
    int lux = tcs.calculateLux(red, green, blue);

    tcs.setInterrupt(true);
    int lightness = 765 - (int(red) + int(green) + int(blue));
    int brightness = map(lightness, 650, 0, 0, 255);
    int seconds_on = map(brightness, 0, 255, 6000, 25000);
    int new_time = seconds_on + 5000;

    Serial.print("bright:\t"); Serial.print(brightness);
    Serial.print("\tR:\t"); Serial.print(int(red));
    Serial.print("\tG:\t"); Serial.print(int(green));
    Serial.print("\tB:\t"); Serial.print(int(blue));
    Serial.print("\n");
    Serial.print("length of time:\t"); Serial.print(new_time);
    Serial.print("\n");
    Serial.print("length of time2:\t"); Serial.print(seconds_on);
    Serial.println("\n");

    pumpState = HIGH;
    digitalWrite(pump, pumpState);
    
    //length of time the pump will be on
    while((seconds_on*seconds_on) > 0) {
      rainbow(20);
      seconds_on -= 5000;
    }

    pumpState = LOW;
    digitalWrite(pump, pumpState);
    delay(10);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < pixels.numPixels(); i ++) {
      pixels.setPixelColor(i, Wheel((i + j) & 255));
    }
    pixels.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Online Resources

MakerCase – Easy Laser Cut Case Design

Overview | Adafruit Color Sensors | Adafruit Learning System

Waterfall guide | Youtube

]]>
project 2: Thoughts of a Plant https://courses.ideate.cmu.edu/62-362/f2021/project-2-thoughts-of-a-plant/ Sat, 13 Nov 2021 00:36:13 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11849 Thoughts of a Plant explores the differences and similarities between plants and people by setting up an opportunity to listen to and interact with the internal electrical signals of a plant.

Normally, plants exist in the background and slowly grow over time, responding primarily to changes in sunlight, moisture, temperature, or wounding. Humans on the other hand respond quickly to changes around them and constantly communicate through speech to get food, socialize, and generally enact agency. This project is intended to give an interactive voice to plants.

The user listens to an ambient acoustic chord whose timbre changes and evolves with the plants electrical biosignals. A microphone provides the opportunity to interact with the biosignals by inducing a complementary signal into the plant based on your speech. This allows the user to create fast-changing effects on the timbre and see how their own speech is transduced through the plant amplification circuit. The intended effect is to contrast our short-term speech patterns against the slower changes of the plant’s own signals.

The plant is set up nondescriptly on a table with visible electrical probes and amplification circuitry. A prominent microphone invites visitors to speak into the plant and listen to the reply.

 

Process

Thoughts of a Plant uses electrical probes attached to the stems of the plant to measure small voltages across the leaves. The signals are sent through an arduino equipped with a custom amplifier circuit to a software synthesizer and modulate parameters such as filter cutoffs, resonance, noise, detuning, overdrive, and a few other parameters. This means that slight changes in the plant’s bioelectrical signals modify the timbre of the ambient tone. The chord itself is a Minor 7th played from through a dual-sawtooth synthesizer to produce a somewhat dark, warm ambient tone. Additional instruments provide relatively static harmonics to build out a larger acoustic atmosphere.

The primary challenge here was actually measuring the plant’s bioelectrical signals. Most of the work for this project went into designing and constructing a very high input-impedence amplifier/filter circuit so that I could measure the small signals on the plant. I ended up using a noninverting op-amp circuit with a first order low-pass filter, with a gain of 10 and cutoff frequency of 100Hz respectively. A virtual ground allows the measurement of negative signals by biasing the output signal to 2.5v. This turned out to be very difficult to implement in practice, and took most of my time. The hardest part is that plant signals evolve very slowly (noticeable change takes a couple minutes, and significant change takes 10-20 minutes), so it takes a long time to verify that the system is working and measuring plant data rather than arbitrary noise.

The synthesis was fairly simple, but interfacing with the arduino was surprisingly buggy and difficult using Max For Live. Max would often cause ableton to freeze and mapping signals (ie, arduino A0 to filter cutoff) was unreliable and lacked customization.

I think I ended up with a good probing setup, but I wish I had used custom sound synthesis instead of Max For Live. I ended up with very little control over the timbre changes, so some effects were far more sensitive than others. The microphone input in practice was fairly rough, since Max For Live’s envelope follower module was very buggy and unreliable, so I couldn’t tweak it easily. I wish I had processed the user audio in a more interesting way, such as with an fft or slowing down the response. I also think that it was generally unclear what role the microphone played in the setup, so a little bit of signage and better introduction could have helped there.

Final Images

Audio of the plant synthesizer in action:

Process Images:

The measured signal evolves slowly over 10-20 minutes:

A video of the synthesizer modulation in ableton using Max For Live:

 

Code:

There was no original “code” for this project. A simple ableton synthesizer was run and arduino code was just the Max For Live client sketch.

]]>
Apply Pressure Flow Documentation – Olivia https://courses.ideate.cmu.edu/62-362/f2021/apply-pressure-flow-documentation-olivia/ Fri, 12 Nov 2021 21:57:53 +0000 https://courses.ideate.cmu.edu/62-362/f2021/?p=11704 Apply Pressure

Final Design of the Touch Pad

Video Demonstration

 

Examples of the Visuals

Narrative description

Apply pressure is an installation that produces visuals and sounds. The physical part of the project is a wooden box, covered in shiny green fabric, with nine force sensors on it that act as buttons. When each button is pressed, colored circles are projected onto a screen and a sound is produced. As the buttons are pressed harder, the nine circles which are projected in a grid on the screen get larger and the sound plays louder.

Progress Images

This photo shows my first prototype where I struggled to find a rigid material to cover the sensors with. The pressure was not transferring to the sensors even through the thinnest sheet material so I decided to just cover the exposed part of the sensors with fabric in the final design. The fabric I chose did not interfere with the touch sensitivity of the resistors.

This photo was taken the day I finally got the serial connection to work between processing and the arduino. I was starting to get the visuals I wanted and experimenting with different fabrics to put over top of the touch pad.

This photo shows me building the final box that would house the touchpad on the top and the breadboard and arduino underneath.  I made the final design about twice the size of the prototype so that it was large enough for multiple people to interact with it at once. The hole at the center of the box was where all of the wires from the resistors in the touchpad would come together.

This photo shows the bottom side of the box where the majority of the electronics would be housed on the wooden piece that bridges the length of the box. This was so that the box  was mobile while the electronics were in place but I could still easily access them.

Process Reflection

This project was my first time using Processing which I used to create the audio-visual aspects of the project. Figuring out how to write code to produce the kind of parametric visuals I wanted was not intuitive for me since I am used to designing in a a more visual programming language like Grasshopper. However, after many experimentations and learning through looking at examples I was able to get the visuals to a point where I was happy. I needed some help working through a few bugs with the serial connection to the arduino but once that was set up, adding in the sound component was pretty simple.  I feel more comfortable using processing now and definitely want to use it to design visuals for my personal website.

Another challenge I had was deciding how to stabilize the sensors in a way that didn’t limit their sensitivity as seen in the process images above. Designing the box wound up being a bit difficult but I figured out I could use two layers of acrylic with misaligned grids of holes to essentially sandwich the sensors and keep them in place. One of the most fun parts of this project was sifting through online music samples and choosing the audio components. I put a lot of thought into how the audios sounded together if multiple people were going to be playing with the buttons at the same time.

If I wanted to push the project in a different direction I could have created a different kind of tactile experience instead of the large touchpad embedded into the box. We had previously talked about possibly building nine separate remotes so that the visuals could be collectively produced by people sitting away from one another. This would have created a more experimental nature in the way the project is experienced since it wouldn’t be as obvious which sensor controlled which part of the visuals and audio. In this case the users would have to figure out who controlled what which could have been fun even though I did enjoy the close collaboration that this project required. Overall I am happy with the way this project came out and it seemed like people were excited about interacting with it during the review.

Code submission

Arduino Code:

//Apply Pressure
//By Olivia Werner
//This code reads analog input data from nine force sensitive
//resistors and maps the values to be in a range of 0 - 255

const int FCR0 = A0; //defining analog sensors
const int FCR1 = A1;
const int FCR2 = A2;
const int FCR3 = A3;
const int FCR4 = A4;
const int FCR5 = A5;
const int FCR6 = A6;
const int FCR7 = A7;
const int FCR8 = A8;

void setup() {
  // put your setup code here, to run once:
  pinMode(FCR0, INPUT);
  pinMode(FCR1, INPUT);
  pinMode(FCR2, INPUT);
  pinMode(FCR3, INPUT);
  pinMode(FCR4, INPUT);
  pinMode(FCR5, INPUT);
  pinMode(FCR6, INPUT);
  pinMode(FCR7, INPUT);
  pinMode(FCR8, INPUT);
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  //if we get a valid byte, read analog ins:
  //if (Serial.available() > 0) {
  // get incoming byte:
  //inByte = Serial.read();

  //read the value of the resistance and store it
  int forceVal0 = analogRead(FCR0);
  //map value to 255
  forceVal0 = map(forceVal0, 0, 1023, 0, 255);
  Serial.print(forceVal0);
  Serial.print(",");
  delay(10);

  int forceVal1 = analogRead(FCR1);
  //map value to 255
  forceVal1 = map(forceVal1, 0, 1023, 0, 255);
  Serial.print(forceVal1);
  Serial.print(",");
  delay(10);

  int forceVal2 = analogRead(FCR2);
  //map value to 255
  forceVal2 = map(forceVal2, 0, 1023, 0, 255);
  Serial.print(forceVal2);
  Serial.print(",");
  delay(10);

  int forceVal3 = analogRead(FCR3);
  //map value to 255
  forceVal3 = map(forceVal3, 0, 1023, 0, 255);
  Serial.print(forceVal3);
  Serial.print(",");
  delay(10);

  int forceVal4 = analogRead(FCR4);
  //map value to 255
  forceVal4 = map(forceVal4, 0, 1023, 0, 255);
  Serial.print(forceVal4);
  Serial.print(",");
  delay(10);

  int forceVal5 = analogRead(FCR5);
  //map value to 255
  forceVal5 = map(forceVal5, 0, 1023, 0, 255);
  Serial.print(forceVal5);
  Serial.print(",");
  delay(10);

  int forceVal6 = analogRead(FCR6);
  //map value to 255
  forceVal6 = map(forceVal6, 0, 1023, 0, 255);
  Serial.print(forceVal6);
  Serial.print(",");
  delay(10);

  int forceVal7 = analogRead(FCR7);
  //map value to 255
  forceVal7 = map(forceVal7, 0, 1023, 0, 255);
  Serial.print(forceVal7);
  Serial.print(",");
  delay(10);

  int forceVal8 = analogRead(FCR8);
  //map value to 255
  forceVal8 = map(forceVal8, 0, 1023, 0, 255);
  Serial.print(forceVal8);
  Serial.print(",");

  Serial.println("0"); //FAKE VALUE TO DEBUG

  delay(10);
}

Processing Code:

//Apply Pressure
//By Olivia Werner
//This code reads serial data from nine force sensitive resistors connected to an arduino mega
//Nine circles are drawn with their size being constantly updated depending on the amount of pressure on the 
//force sensitive resistors. The hue of the circles updates randomly creating a gradient. The code also
//plays nine sound files depending on which sensor is being pressed with the volumes controlled by the analog values.


import processing.serial.*;
import cc.arduino.*;
import org.firmata.*;
import processing.sound.*;

SoundFile[] file;
// Define the number of samples
int numSounds = 10;

Arduino arduino;

int timer;

Serial myPort; //create an object
String val; //data recieved from the serial port

int[] serialInArray = new int[10]; // Where we'll put what we receive
int serialCount = 0;     // A count of how many bytes we receive
String inString;

ArrayList<Circle> circles; //make an array of circles

void setup() {

  size(1500, 1500);
  colorMode(HSB, 100);
  smooth();
  noFill();
  ellipseMode(CENTER);

  // Create an array of empty soundfiles
  file = new SoundFile[numSounds];

  // Load 9 soundfiles from a folder in a for loop. By naming the files 0., 1., 2., n.aif it is easy to iterate
  // through the folder and load all files in one line of code.
  for (int i = 0; i < numSounds; i++) {
    file[i] = new SoundFile(this, (i+1) + ".aif");
  }

  //create an array of circles
  circles = new ArrayList<Circle>();

  // set the background color with the color values:
  background(serialInArray[7], serialInArray[6], serialInArray[3]);

  // Open whatever port is the one you're using.
  String portName = "COM5";
  myPort = new Serial(this, "COM5", 115200);
}

void draw() {

  for (Circle  c : circles) {
    c.draw();
    c.update();
  }
  //stop storing circle data after there are 150 circles
  while (circles.size()>150) {
  circles.remove(0);
  }

  if (millis() - timer > 200)
  {
    //draw nine circles
    circles.add(new Circle(375, 375, serialInArray[0]*3, serialInArray[0]*3));
    circles.add(new Circle(750, 375, serialInArray[1]*4, serialInArray[1]*4));
    circles.add(new Circle(1125, 375, serialInArray[2]*8, serialInArray[2]*8));

    circles.add(new Circle(375, 750, serialInArray[3]*5, serialInArray[3]*5));
    circles.add(new Circle(750, 750, serialInArray[4]*8, serialInArray[4]*8));
    circles.add(new Circle(1125, 750, serialInArray[5]*6, serialInArray[5]*6));

    circles.add(new Circle(375, 1125, serialInArray[6]*6, serialInArray[6]*6));
    circles.add(new Circle(750, 1125, serialInArray[7]*3, serialInArray[7]*3));
    circles.add(new Circle(1125, 1125, serialInArray[8]*4, serialInArray[8]*4));

    timer = millis();
  }

  //play sounds
  for (int i = 0; i< numSounds-1; i++) {
    if (!file[i].isPlaying() && serialInArray[i] >0) {
      float volumeLevel = map(serialInArray[i], 0, 255, 0, 1.0); //volume
      file[i].play(1, volumeLevel);
    }
  }
}

class Circle {
  int hue = 0;
  float x, y, w, h, sw;

  Circle(float x, float y, float w, float h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    sw = random(2, 2);
  };
  
//defining properties of the circles
  void draw() {
    strokeWeight(sw);
    stroke(hue, 100, 100, 100);
    fill(hue, 100, 100, 25);
    ellipse(x, y, w, h);
  }
  
//update gradient
  void update() {
    hue++;
    if (hue == 100) {
      hue = 0;
    }
  }
}

void serialEvent(Serial p) {
  inString = p.readStringUntil('\n');

  if (inString != null) {
    //println(inString);
    
    serialInArray = int(split(inString, ','));
    printArray(serialInArray);
  }
}
]]>