Very Light Tea

Made by rkandala

The design challenge for this project was to find a nonsensical ambient noise and translate that into a digital output (e.g. light, motion, etc.) through signal processing. For my project I chose to listen to tea boiling and translate the noise into patterns on LEDs that was expressive and reflective of the water boiling in a tea kettle.

Created: September 17th, 2015

0
MTI-P1-Very Light Tea-Demo
Rag Kandala (2015) - https://vimeo.com/139578509
0
//***********************
//Audio+Smoothing Stuff
//***********************
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int micPin = A0;
int micVal;
//**************
//NeoPixel Stuff
//**************

#include <Adafruit_NeoPixel.h> //include the neopixel library
//declarations
#define PIXEL_PIN 3
#define NUMPIXELS 12
Adafruit_NeoPixel ring = Adafruit_NeoPixel(NUMPIXELS, PIXEL_PIN, NEO_GRB + NEO_KHZ800); //initialize neopixel object
//colors
uint32_t ringColor;
uint32_t blank = ring.Color(0,0,0);
uint32_t coldBlue = ring.Color(10,10,255);
uint32_t doneGreen = ring.Color(10,255,10);
int r; int g; int b;

//************
//State Logic
//************
int state = 0;
int timer = 0;
#define THRESHOLD 130
int signalTimer =0;
int signalLength = 100;
boolean signalLost = false;

//state 0 - on
int lightState[]={1,0,0,0,0,0,0,0,0,0,0,0};
int minPos=0;
boolean startAnim = false;
int onTimer;
int onDelay=20;
int onEnd = 725; //750-870
//state 1 - build
int buildEnd = 3200;//ends @ 3650; 2850-3200
//int buildEnd = 380;
//state 2 - bubble
int bubbleEnd = 500;//ends @ 4150
//int bubbleEnd = 450;
int bubbleTimer=0;
int bubblePtrn[4][NUMPIXELS] = {  {1,0,1,0,1,0,1,0,1,0,1,0},
                        {0,0,0,1,1,1,1,1,1,0,0,0},
                        {0,1,0,1,0,1,0,1,0,1,0,1},
                        {1,1,1,0,0,0,0,0,0,1,1,1}  };
int ptrnState=0;
//state 3 - off
int offTimer=0;
//int offDelay = 150;
int resetDelay = 150;
int bright;
int showPixel;

void setup(){
  ring.begin();
  ring.setBrightness(50);
  ring.show();
  Serial.begin(9600);
}

void loop(){
  //smoothing
  micVal = smoothing();
  delay(1);        // delay in between reads for stability  

  //state animations
  if(state == 0){state0ON();timer++;}
  else if(state == 1){state1Build();  timer++;}
  else if(state == 2){state2Bubble();  timer++;}
  else if(state == 3){state3OFF();  timer++;}
  else{checkSignal();timer++;}
  debugger();
}

void checkSignal(){ 
  //checking signal frequency
  if(micVal<THRESHOLD){signalTimer++;}
  else if(micVal>=THRESHOLD){signalTimer=0;signalLost = false;}
  if(signalTimer>=signalLength && !signalLost){signalLost=true;}  
}

void state0ON(){

  if(micVal>=THRESHOLD){startAnim = true;} //check if audio has changed
  
  if(startAnim && onTimer<=onDelay){
    minPos = map(onTimer,0,onDelay,0,NUMPIXELS);
    //updatePixels
    for(int i=0;i<NUMPIXELS;i++)
    {
      if(i<=minPos){lightState[i]=1;}
      else{lightState[i]=0;}
    }
    //drawPixels
    for(int i=0;i<NUMPIXELS;i++)
    {
      ring.setPixelColor(i,blank);
      if(lightState[i]>0){
        ring.setPixelColor(i,coldBlue);
      }
    }
    ring.show();
    onTimer++;
  }
  else if(onTimer>onDelay){
  lightState[0]=1;
  minPos=0;
  startAnim=false;
  onTimer=0;
  }
  if(timer>=onEnd){
    state=1; timer=0;
    resetLED();}  
}

void state1Build(){
  checkSignal();  
//  if(timer<=buildEnd){
  if(!signalLost){  
    r = map(timer,0,buildEnd,10,255);
    g = map(timer,0,buildEnd,10,0);
    b = map(timer,0,buildEnd,255,10);
    bright = map(micVal,0,500,10,70);
    ringColor = ring.Color(r,g,b);    
  }
//  else if (timer>buildEnd){
  else if (signalLost){  
    ringColor = ring.Color(255,0,0);
    state=2; timer=0;
    ring.setBrightness(50);    
  }
    for(int i=0;i<NUMPIXELS;i++)
    {
        ring.setPixelColor(i,ringColor);
      }
      ring.setBrightness(bright);      
      ring.show();
}

void state2Bubble(){
  if(timer<=bubbleEnd){
      if(bubbleTimer%150==0){
        ptrnState++;
        ptrnState%=4;
        r = random(255);
        g = random(255);
        b = random(255);    
        ringColor = ring.Color(r,g,b);
      }
  
  for(int i =0;i<NUMPIXELS;i++){
    if(bubblePtrn[ptrnState][i]>0){ring.setPixelColor(i,ringColor);}
    else{ring.setPixelColor(i,blank);}
  }
  ring.show();
}
  else if (timer>bubbleEnd){state=3;bubbleTimer=0;timer=0;}  
}

void state3OFF(){
  bright = map(offTimer, 0, resetDelay,100,0);
  showPixel = map(offTimer, 0, resetDelay,NUMPIXELS,0);
  
  if(offTimer<=resetDelay){
    for(int i =0;i<NUMPIXELS;i++){
      ring.setBrightness(bright);
      if(i<showPixel){ring.setPixelColor(i,doneGreen);}
      else{ring.setPixelColor(i,blank);}
    }
    ring.show();
  }
  else if(offTimer>resetDelay) {state=0;offTimer=0;timer=0;}
  offTimer++;  
}

void resetLED(){
  for(int i=0;i<NUMPIXELS;i++)
    {
      ring.setPixelColor(i,blank);
    }
    ring.show();
}

void debugger(){
  Serial.print("raw: ");
  Serial.print(analogRead(micPin));
  Serial.print("; avg: ");
  Serial.print(micVal);
  if (state == 1 || state == 4){
  Serial.print("; signalT: ");
  Serial.print(signalTimer);  
  Serial.print("; signalS: ");
  Serial.print(signalLost);  
  }
  Serial.print("; State: ");
  Serial.print(state);
  Serial.print("; timer: ");
  Serial.println(timer);
}

int smoothing(){
    // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = analogRead(micPin); 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  return average; 
}
Click to Expand
0

Process: Exploration of Concepts

When I was exploring the problem space I tried to understand the noise pattern for a range of natural and man-made noises. Ultimately I ended up choosing tea boiling for 2 reasons: 

1) Boiling water is a very violent process that is hidden to some degree by the tea kettle but I wanted to make it experienceable somehow.

2) I wanted to create an aesthetic experience that was detached from utility.

0

Process: Exploration of Form and Interaction

Unfortunately for this project I was not able to explore the form language as deeply as I had hoped. My intention for the form was to create a device that appeared to be delicate/petite (to contrast the violent bubbling process) and appeared similar in shape to radios/speakers so that hints that it is sound related.


For the interactions I coded a few of patterns on the NeoPixel ring to see what patterns had fit the qualities of the water boiling at various stages.

0
//Early Exploration of LED Patterns
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

//neopixel
#include <Adafruit_NeoPixel.h> //include the neopixel library
#define PIXEL_PIN 6
#define NUMPIXELS 12

Adafruit_NeoPixel ring = Adafruit_NeoPixel(NUMPIXELS, PIXEL_PIN, NEO_GRB + NEO_KHZ800); //initialize neopixel object
uint32_t ringColor;
uint32_t blank = ring.Color(0,0,0);
int r=25;
int g=0;
int b=25;
int maxLEDS=0;

int lightState[]={1,0,0,0,0,0,0,0,0,0,0,0};
int minPos=0;
int LEDSpeed = 20;
int timer=0;

void setup(){
  // initialize serial communication with computer:
  Serial.begin(9600);                   
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;
    //Initialize Ring
    ring.begin();
    ring.setBrightness(50);
    ring.show();
    Serial.begin(9600);
}
void loop(){
  //Get input signal
  int val = cleanSignal();
  timer++;
  Serial.print("raw: ");
  Serial.print(analogRead(inputPin));
  Serial.print("; avg: ");
  Serial.print(val);
  Serial.print("; timer: ");
  Serial.println(timer);
  delay(1);        // delay in between reads for stability  
  ringPattern(val);
}


void ringPattern(int micVal){
  g = map(micVal,33,1023,0,255);
  maxLEDS = map(micVal,33,1023,0,NUMPIXELS);
  LEDSpeed = map(micVal,33,1023,40,100);
  ringColor = ring.Color(r,g,b);
  
  //updatePixels
  minPos++;
  minPos = minPos%NUMPIXELS;
  for(int i=0;i<NUMPIXELS;i++)
  {
    if(i>=minPos && i<minPos+maxLEDS){lightState[i]=1;}
    else{lightState[i]=0;}
  }
  //drawPixels
  for(int i=0;i<NUMPIXELS;i++)
  {
    ring.setPixelColor(i,blank);
    if(lightState[i]>0){
      ring.setPixelColor(i,ringColor);
    }
  }
  ring.show();
  delay(LEDSpeed);
}

int cleanSignal(){
    // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = analogRead(inputPin); 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  return average; 
}
Click to Expand
x
Share this Project

Found In
Courses

48-739 Making Things Interactive

· 0 members

Making Things Interactive (MTI) is a studio course based on physical prototyping and computing. You will develop novel sensing, interaction and display techniques through projects and short assignm...more


Focused on
About

The design challenge for this project was to find a nonsensical ambient noise and translate that into a digital output (e.g. light, motion, etc.) through signal processing. For my project I chose to listen to tea boiling and translate the noise into patterns on LEDs that was expressive and reflective of the water boiling in a tea kettle.