My lab project this week consists of a squeezable, glowing orb and a fractal generator. The results are a bit kooky. I reused a soft silicon casing we created for a past project and placed the pressure sensor between the soft casing and the hard plastic kernel.
For my visualization, I played around with the Mandelbrot sketch example in Processing, making it into a sequential, frame-by-frame visualization rather than a static image. I accelerated the fractal growth with greater pressure on the orb, but as that was hard to see, I also changed the background color slightly to show when pressure was applied. The next step might be to try out algorithmic visualizations that are not fractals, as later evolution is hard to see as the fractals get smaller.
Arduino Code:
/* * Andrew Chong * Alternating RGB Fade with Potentiometers * Modified from Clay Shirky <clay.shirky@nyu.edu> */ // Output int redPin = 9; // Red LED, connected to digital pin 9 int greenPin = 10; // Green LED, connected to digital pin 10 int bluePin = 11; // Blue LED, connected to digital pin 11 float red_direction = 1; float blue_direction = 1; float green_direction = 1; float pressure; // brightness float blue_brightness = 0; float red_brightness = 0; float green_brightness = 0; // Program variables float redVal = 255; // Variables to store the values to send to the pins float greenVal = 255; float blueVal = 0; int i = 0; // Loop counter int j = 0; // display counter int wait = 500; // 50ms (.05 second) delay; shorten for faster fades int DEBUG = 1; // DEBUG counter; if set to 1, will write values back via serial void setup() { pinMode(redPin, OUTPUT); // sets the pins as output pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); // If we want to see the pin values for debugging... Serial.begin(9600); // ...set up the serial ouput on 0004 style } // Main program void loop() { //blue_brightness = analogRead(A0)*3/(float)1023; //red_brightness = analogRead(A5)*3/(float)1023; //green_brightness = analogRead(A1)*3/(float)1023; i += 5; // Increment counter j += 1; delay(wait); Serial.println(int(analogRead(A0)/100)); pressure = analogRead(A0); greenVal = (pressure/1000)*255; //Serial.println("red:"); //Serial.println("red:"); //Serial.println(greenVal); analogWrite(greenPin, greenVal); /* if (DEBUG) { // If we want to read the output DEBUG += 1; // Increment the DEBUG counter if (DEBUG > 20) // Print every 10 loops { DEBUG = 1; // Reset the counter Serial.print(i); // Serial commands in 0004 style Serial.print("\t"); // Print a tab Serial.print("R:"); // Indicate that output is red value Serial.print(redVal); // Print red value Serial.print("\t"); // Print a tab Serial.print("G:"); // Repeat for green and blue... Serial.print(greenVal); Serial.print("\t"); Serial.print("B:"); Serial.println(blueVal); // println, to end with a carriage return } } */ //delay(wait); // Pause for 'wait' milliseconds before resuming the loop } Processing code:
/** * The Mandelbrot Set * by Daniel Shiffman. * * Simple rendering of the Mandelbrot set. */ import processing.serial.*; // Change this to the portname your Arduino board String portname = "/dev/cu.usbmodem1421"; // or "COM5" Serial port; String buf=""; int cr = 13; // ASCII return == 13 int lf = 10; // ASCII linefeed == 10 int serialVal = 0; int currentVal = 10; int r = 106; int g = 0; int b = 209; void setup() { size(1200,800); frameRate(2); // Animate slowly port = new Serial(this, portname, 9600); } void draw() { // Establish a range of values on the complex plane // A different range will allow us to "zoom" in or out on the fractal // It all starts with the width, try higher or lower values float w = 4; float h = (w * height) / width; // Start at negative half the width and height float xmin = -w/2; float ymin = -h/2; // Make sure we can write to the pixels[] array. // Only need to do this once since we don't do any other drawing. loadPixels(); currentVal = currentVal + 1 + serialVal; // Maximum number of iterations for each point on the complex plane int maxiterations = currentVal ; // x goes from xmin to xmax float xmax = xmin + w; // y goes from ymin to ymax float ymax = ymin + h; // Calculate amount we increment x,y for each pixel float dx = (xmax - xmin)/(width); float dy = (ymax - ymin)/(height); // Start y float y = ymin; for (int j = 0; j < height; j++) { // Start x float x = xmin; for (int i = 0; i < width; i++) { // Now we test, as we iterate z = z^2 + cm does z tend towards infinity? float a = x; float b = y; int n = 0; while (n < currentVal) { float aa = a * a; float bb = b * b; float twoab = 2.0 * a * b; a = aa - bb + x; b = twoab + y; // Infinty in our finite world is simple, let's just consider it 16 if (dist(aa, bb, 0, 0) > 16) { break; // Bail } n++; } // We color each pixel based on how long it takes to get to infinity // If we never got there, let's pick the color black if (n == maxiterations) { pixels[i+j*width] = color(0); } else { // Gosh, we could make fancy colors here if we wanted float norm = map(n, 0, maxiterations, 0, 1); /* if (r>254) { r = 0; } if (g>254) { g = 0; } if (b>254) { b = 0; } */ //r = r + 1; //b = b + 1; //g = g +1; pixels[i+j*width] = color(0,g,b); } x += dx; } y += dy; } updatePixels(); } // called whenever serial data arrives void serialEvent(Serial p) { int c = port.read(); if (c != lf && c != cr) { buf += char(c); } if (c == lf) { serialVal = int(buf); println("val="+serialVal); buf = ""; } if (serialVal>5){ //r = int(random(255)); if (g==0) { g = 20; } else if (g==20){ g = 0; } print(g); //b = int(random(255)); //print(b); } }