/** * 8x8 image read to serial send * ver. 0.1 * by jacob remin * * automatic rescaling from any image input * output string is assembled: X + 64 average greyscale values in 16 steps (1 hex character) * * for more info, please refer to the 8x8 development blog: www.campingsex.org/8x8 */ import processing.serial.*; import processing.video.*; import krister.Ess.*; Serial port; //the serial port Movie movie160; // the test movie PImage a,b,c; int[] outputString = new int[64]; String data = ""; String transferData = ""; boolean crosshair = false; boolean movieplaying = false; int lf = 10; //ASCII value for line feed float threshold = 124; int bufferSize; int steps; float limitDiff; int numAverages=8; float myDamp=.1f; float maxLimit, minLimit; boolean spectrum = true; boolean inv = false; int xstep, ystep, xpos, ypos; boolean scrolling = false; PFont font; String scrollertxt; FFT myFFT; AudioInput myInput; void setup() { println(Serial.list()); //list avaiable serial ports port = new Serial(this, Serial.list()[0], 9600); frameRate(30); a = loadImage("stripe160wgreys.jpg"); //from data subfolder of program file b = loadImage("yo160.jpg"); c = loadImage("griddy160.jpg"); //image(a, 0, 0); //display the image movie160 = new Movie(this, "8x8_tpoe_remix160.mov"); movie160.loop(); size(160, 160); //dimensions of display window xstep = width/8; ystep = height/8; noStroke(); background(0); //Start up ESS Ess.start(this); // set up our AudioInput bufferSize=512; myInput=new AudioInput(bufferSize); // set up our FFT myFFT=new FFT(bufferSize*2); myFFT.equalizer(true); // set up our FFT normalization/dampening minLimit=.005; maxLimit=.05; myFFT.limits(minLimit,maxLimit); myFFT.damp(myDamp); myFFT.averages(numAverages); // get the number of bins per average steps=bufferSize/numAverages; // get the distance of travel between minimum and maximum limits limitDiff=maxLimit-minLimit; frameRate(25); myInput.start(); // The font must be located in the sketch's // "data" directory to load successfully font = loadFont("DoubleOhOne-160.vlw"); } void draw() { if (scrolling == true) { scrollertxt= "8x8: lo-fi digital delight"; textFont(font, 160); fill(0, 0, 0); text(scrollertxt, xpos, 140); xpos = xpos - xstep; fill(255, 255, 255); text(scrollertxt, xpos, 140); if (xpos < ((scrollertxt.length())*100*-1)) { scrolling = false; } } if (inv == true) { filter(INVERT); } if (spectrum == true){ rectMode(CORNER); spectrumAnalyzer (); } if (crosshair == true) { rectMode(CENTER); background(0); rect(mouseX, 80, 20, 160); rect(80, mouseY, 160, 20); } if (movieplaying == true) { tint(255,255); image(movie160, 0, 0); //filter(THRESHOLD, threshold/1024); } while (port.available() > 0) { char inByte = port.readChar(); if (inByte == 'P') { String potRead = port.readStringUntil(lf); if (potRead != null) { //print("pot says:"+potRead); // interpreting the string int howManyChars = potRead.length(); //since line change is 2 chars, we subtract 2 howManyChars = howManyChars - 2; int composedVal=0; int increment=1; for (int val=1; val<=howManyChars; val=val+1) { int dec = int(potRead.charAt(howManyChars-val)-'0'); composedVal = composedVal+dec*increment; increment = increment*10; } threshold = composedVal ; } } } updateLEDdisplay(); delay(5); } void spectrumAnalyzer() { background(0); for (int i=0; i<8; i++){ rect (i*20,160,20,-1*(myFFT.spectrum[(i*15)+15]*threshold)); } } public void audioInputData(AudioInput theInput) { myFFT.getSpectrum(myInput); } // Called every time a new frame is available to read void movieEvent(Movie m) { m.read(); } void keyPressed() { if (key == ' ') { //stop all scrolling=false; spectrum=false; crosshair=false; movieplaying=false; background(0); } if (key == 't') { //start txtscroller background(0); xpos = 160; scrolling = true; } if (key == 'i' && inv==false) { inv = true; } else if(key =='i' && inv==true) { inv = false; } if (key == 's' || key == 'S') { spectrum = !spectrum; } if (key == 'a' || key == 'A') { background(a); crosshair = false; } if (key == 'b' || key == 'B') { background(b); crosshair = false; } if (key == 'c' || key == 'C') { background(c); crosshair = false; } if (key == 'm' && movieplaying == true) { movieplaying = false; movie160.pause(); } else if (key == 'm' && movieplaying == false) { movieplaying = true; movie160.play(); } if (key == 'x' && crosshair == true) { crosshair = false; background (0); } else if (key == 'x' && crosshair == false) { crosshair = true; } } void mouseReleased() { updateLEDdisplay (); } void updateLEDdisplay () { loadPixels(); // println("new output"); int totalSize = width*height; int xstep = width/8; int ystep = height/8; int count = 0; // println("dimensions: x:"+width+" y:"+height+" step x:"+xstep+" step y:"+ystep+" total no. of pixels:"+totalSize); transferData = "X"; for(int y=0; y<8; y++) { for(int x=0; x<8; x++) { // print("x,y:("+x+","+y+") "); data = hex(color(pixels[y*ystep*width+x*xstep])); // print(data); String R = ""; char R1 = data.charAt(2); char R2 = data.charAt(3); R += R1; R += R2; int Rvalue = unhex(R)/16; // print(" |"+"R:"+hex(Rvalue, 1)); String G = ""; char G1 = data.charAt(4); char G2 = data.charAt(5); G += G1; G += G2; int Gvalue = unhex(G)/16; // print("|"+"G:"+hex(Gvalue, 1)); String B = ""; char B1 = data.charAt(6); char B2 = data.charAt(7); B += B1; B += B2; int Bvalue = unhex(B)/16; // print("|"+"B:"+hex(Bvalue, 1)+"| "); int average = (Rvalue+Gvalue+Bvalue)/3; // print("|average:"+hex(average,1)+"| "); transferData += hex(average,1); /* count ++; if(count==2) { println(""); count=0; } */ } } updatePixels(); // println("transfer: "+transferData); port.write(transferData); transferData = ""; }