Tuesday, November 30, 2004

Processing Code 11/29

There is a problem with the .wav and timing of the color changes. We are wondering if this is a Processing or Sonia issue. This code uses for loops and arrays to cut down on file size.

// CODE
// SONIA V2.5 -- Audio Live Stream.
//http://www.pitaru.com/sonia/
//Goal is to capture audio data and parse into if/then statements
//Note the Sonia code folder goes into the sketch folder

//web site to scrape: http://www.dhs.gov/dhspublic/display?theme=29
//sounds: http://www.findsounds.com/ISAPI/search.dll

int numOfPics = 5; //number of images in image array for colors
BImage[] colors = new BImage[numOfPics]; //new array of up for displaying color photos
int picDislayTime = 100000; //time image is displayed in milliseconds

int whichImage = 0;
int startTime;
Sample thunder;
float previousLevel = 0;
boolean showing = false;

void setup()
{
Sonia.start(this); // Start Sonia engine.
LiveInput.start(256); // Start LiveInput and return 256 FFT frequency bands.

thunder = new Sample("thunder.wav");

size(640,480);

for(int j=0 ; j<5 ; j++)
{
int m = j+1;
colors[j] = loadImage("color" + m + ".gif");
}
startTime = millis();
}

void loop()
{

showImage(); //Show appropriate image based on input from microphone

for(int i = 5 ; i > 0 ; i-=1)
{
int j = i-1;
if (showing)

if (whichImage == i) {
image(colors[j], 0, 0);
}
if ((millis() - startTime > picDislayTime) || (1500 * LiveInput.getLevel(Sonia.LEFT) > previousLevel))
/* || (1000 * LiveInput.getLevel(Sonia.LEFT) < previousLevel)*/{
showing = false;
}
}
}

void showImage()//Show image based on input from microphone
{
float meterDataLeft = 1500 * LiveInput.getLevel(Sonia.LEFT);//avg this w/ serial in

for(int i = 800 ; i > 100 ; i-=160)
{
int j = i/160;

if (!showing)
{
if (meterDataLeft > i)
{
whichImage = j;
println(j);
thunder.play();
showing = true;
startTime = millis();
previousLevel= meterDataLeft;
}
}
}
}
// Safely close the sound engine upon Browser shutdown.
public void stop(){
Sonia.stop();
super.stop();
}

Saturday, November 27, 2004

Thanksgiving Processing Code

This version has a timer for 10 seconds and stays on a level till the user hits it up to the next or until the 10 seconds are up. We will have a legend so they know what the colors mean.

// CODE
// SONIA V2.5 -- Audio Live Stream.
//http://www.pitaru.com/sonia/
//Goal is to capture audio data and parse into if/then statements
//Note the Sonia code folder goes into the sketch folder

BImage color1;
BImage color2;
BImage color3;
BImage color4;
BImage color5;

/*int numOfPics = 150; //number of images in image array for video sequence
BImage[] carlos = new BImage[numOfPics]; //new array of up to 224 photos

int numOfImages = 100; //number of images in image array for background images
BImage[] boxing = new BImage[numOfImages]; //new array of photos*/

int a = 0; // variable for counting through the display of photos
int picDislayTime = 10000; //time image is displayed in milliseconds
int movDisplayTime = 70; //time image is displayed in milliseconds

int whichImage = 0;
int startTime;
int startTimeMov;

float previousLevel = 0;
//float meterLevel = liveinput.getlevel

boolean showing = false;
boolean slowDown = false;

void setup(){

Sonia.start(this); // Start Sonia engine.
LiveInput.start(256); // Start LiveInput and return 256 FFT frequency bands.

size(640,480);
colorMode(RGB, 255, 255 ,255, 100);//need this comment later for tinting, etc

/*for(int j=0; j int m = j + 1;
carlos[j] = loadImage("boxing" + m + ".jpg");
}*/

color1 = loadImage("color1.gif");
color2 = loadImage("color2.gif");
color3 = loadImage("color3.gif");
color4 = loadImage("color4.gif");
color5 = loadImage("color5.gif");

/*for(int i=0; i int n = i + 1;
carlos[i] = loadImage("carlos" + n + ".gif");
}*/

startTime = millis();

}
void loop(){

background(0,0,0);
showImage(); //Show appropriate image based on input from microphone
if (showing) {
if (whichImage == 5) {
image(color5, 0, 0);
}
else if (whichImage == 4) {
image(color4,0,0);
}
else if (whichImage == 3) {
image(color3,0,0);
}
else if (whichImage == 2) {
image(color2,0,0);
}
else if (whichImage == 1) {
image(color1,0,0);
}
if (millis() - startTime > picDislayTime) {
showing = false;
}
if (1000 * LiveInput.getLevel(Sonia.LEFT) > previousLevel) {
showing = false;
}
}
}

// Safely close the sound engine upon Browser shutdown.
public void stop(){
Sonia.stop();
super.stop();
}

void showImage()//Show appropriate background image based on input from microphone
{
float meterDataLeft = 1000 * LiveInput.getLevel(Sonia.LEFT);
println(meterDataLeft);

if (!showing) {
if (meterDataLeft > 740) {
previousLevel= meterDataLeft;
whichImage = 5;
showing = true;
startTime = millis();
}
else if (meterDataLeft > 580) {
previousLevel= meterDataLeft;
whichImage = 4;
showing = true;
startTime = millis();
}
else if (meterDataLeft > 420) {
previousLevel= meterDataLeft;
whichImage = 3;
showing = true;
startTime = millis();
}
else if (meterDataLeft > 260) {
previousLevel= meterDataLeft;
whichImage = 2;
showing = true;
startTime = millis();

}
else if (meterDataLeft > 100) {
whichImage = 1;
showing = true;
startTime = millis();
previousLevel= meterDataLeft;




}
}
}

Wednesday, November 24, 2004

Updated Final Project Code (Processing)

We tested the project and received very positive feedback from users.

To run serial with Sonia at the same time, make sure that win32Comm.dll is in the same folder.

We are using colors to indicate progress


.
.
. . We need a stepped motion and a timer. We discussed using the Piezo for serial input for a meter.

Priorities:

Set up color program
Set up time delay
Set up audio and serial from strip



// CODE
// SONIA V2.5 -- Audio Live Stream.
//http://www.pitaru.com/sonia/
//Goal is to capture audio data and parse into if/then statements
//Note the Sonia code folder goes into the sketch folder

BImage b;
BImage c;

//int numOfPics = 150; //number of images in image array for video sequence
//BImage[] carlos = new BImage[numOfPics]; //new array of up to 224 photos

/*int numOfImages = 100; //number of images in image array for background images
BImage[] boxing = new BImage[numOfImages]; //new array of photos*/

int a = 0; // variable for counting through the display of photos
int picDislayTime = 1000; //time image is displayed in milliseconds
int movDisplayTime = 70; //time image is displayed in milliseconds

int whichImage = 0;
int startTime;
int startTimeMov;

boolean showing = false;
boolean slowDown = false;

void setup(){

Sonia.start(this); // Start Sonia engine.
LiveInput.start(256); // Start LiveInput and return 256 FFT frequency bands.
beginSerial();
size(640,480);
colorMode(RGB, 255, 255 ,255, 100);//need this comment later for tinting, etc

/*for(int j=0; j int m = j + 1;
carlos[j] = loadImage("boxing" + m + ".jpg");
}*/

b = loadImage("boxing1NL.jpg");
c = loadImage("bsuit.gif");

/*for(int i=0; i int n = i + 1;
carlos[i] = loadImage("carlos" + n + ".gif");
}*/

startTime = millis();

}
void loop(){
background(0,0,0);
//showImage(); //Show appropriate image based on input from microphone
if (showing) {
if (whichImage == 1) {
image(b, 0, 0);

} else if (whichImage == 2) {
image(c,0,0);
}
if (millis() - startTime > picDislayTime) {
showing = false;
}
}

/*showMeterLevel(); //Show simulated movie clip - acts like a meter based on volume from mic
if (slowDown) {
image (carlos[a], 0, 0, carlos[0].width, carlos[0].height - mouseY); //display each image in sequence
if (millis() - startTimeMov > movDisplayTime){
slowDown = false;
}
}*/
}

/*void showMeterLevel(){//Show simulated movie clip - acts like a meter based on volume from mic

float meterDataLeft = 1000 * LiveInput.getLevel(Sonia.LEFT);
float meterDataRight = 1000 * LiveInput.getLevel(Sonia.RIGHT);

if (!slowDown) {
image (carlos[a], 0, 0, carlos[0].width, carlos[0].height - mouseY); //display each image in sequence
a = a + 1;
if ( a >= numOfPics ) {
a = 0;
}
slowDown = true;
startTimeMov = millis();
}
}*/
// Safely close the sound engine upon Browser shutdown.
public void stop(){
Sonia.stop();
super.stop();
}

Sunday, November 14, 2004

Bryce Wolkowitz Gallery Visit

I went to the "Sign Language" exhibit by Tatsuo Miyajima and Ben Rubin. Miyajim's pieces centers on numbers in various configurations. "Counter me on No. 3" is made of neon and steel and reflects the viewer on close inspection. The 2 Ben Rubin pieces "Instability" were really cool. I looked for a projector to see how the words reflected on the LED and realized that there's probably something within the tubes which generates these characters.

Here is the gallery web site: http://www.brycewolkowitz.com The building houses other galleries too.

Friday, November 12, 2004

ADC With a BX-24

I am using a BX-24 because I am short on PICs and for my processing final, I am using analgue input.

Here is the schematic from Tom Igoe's site for the BX-24:



This is the first program I tried on the BX-24:

dim potVar as integer

Sub main()
call delay(0.5) ' start program with a half-second delay

do
potVar = getADC(13)
debug.print "potVar = " ; cstr(potVar)
loop

end sub


For some reason,the BX-24 returns really clean values from the potentiometer.

Tuesday, November 09, 2004

Lab 7- Motors Lab

I wired a BX-24 and used the following modified code from Tom Igoe's site. I tested the H-Bridge with the multimeter, but couldn't get a reading of 12V for the motor.

' H-bridge is connected to pins 11 and 12.
' Switch is connected to pin 20
' motor enable pin is connected to pin 8

Const switchPin as byte = 20
Const motor1Pin as byte = 11
Const motor2Pin as byte = 12
Const motorEnablePin as byte = 8

Sub main()
' initialize variables:
call putPin(motor1Pin,1)
call putPin(motor2Pin,0)
call getPin(motoeEnablePin, 1)

do
if motorDirection = 1 then
call putPin(motor1Pin,0)
call putPin(motor2Pin,1)
else
call putPin(motor1Pin,1)
call putPin(motor2Pin,0)
end if
loop
end sub


As a side note, the BX-24 showed errors after faulty programming. I tried resetting the RES pin to ground (didn't work) and eventually pulled the chip out of the breadboard for 10 minutes - the light on the chip lit up and it worked again.


I was able to get circular motion from a stepper motor. To find which wires (mine were black) to send to power, use an Ohmeter to test resistance across the circuit. I used trial-and-error for the other four colored wires. This is the order I used:

Green
Brown
Orange
Yellow

Igoe's book has the following order:

Orange
Yellow
Black
Brown
Red


There has to be a better way to figure where they go, I will try to find out if I update this entry.

Also, I still need to use a switch to reverse direction.

I purchased H-Bridges from Digikey, but ended up using a transistor array from the Computer Store. Here is the documentation for a Darlington Array. Here is the PIC basic code I used to get basic motion from the motor:

start:
High PORTB.0

' set variables:
x VAR BYTE
steps VAR WORD
stepArray VAR BYTE(4)
clear

TRISD = %11110000
PORTD = 255
input portb.4
Pause 1000

stepArray[0] = %00001010
stepArray[1] = %00000110
stepArray[2] =%00000101
stepArray[3] = %00001001


main:
if portb.4 = 1 then
steps = steps + 1
else
steps = steps - 1
endif

portD = stepArray[steps //4]
pause 2

GoTo main


Here are two somewhat out-of-focus photos of the breadboard and motors:


Thursday, November 04, 2004

Interactive Punching Bag Documentation

This is the short description of the project to go where we set it up


Here is the initial proposal and Wlodek's current documentation for the project

PROCESSING CODE

// CODE
// SONIA V2.5 -- Audio Live Stream.
//http://www.pitaru.com/sonia/
//Goal is to capture audio data and parse into if/then statements
//Note the Sonia code folder goes into the sketch folder

BImage b;
BImage c;

int numOfPics = 150; //number of images in image array for video sequence
BImage[] carlos = new BImage[numOfPics]; //new array of up to 224 photos

/*int numOfImages = 100; //number of images in image array for background images
BImage[] boxing = new BImage[numOfImages]; //new array of photos*/

int a = 0; // variable for counting through the display of photos
int picDislayTime = 1000; //time image is displayed in milliseconds
int movDisplayTime = 30; //time image is displayed in milliseconds

int whichImage = 0;
int startTime;
int startTimeMov;

boolean showing = false;
boolean slowDown = false;

void setup(){

Sonia.start(this); // Start Sonia engine.
LiveInput.start(256); // Start LiveInput and return 256 FFT frequency bands.

size(640,480);
colorMode(RGB, 255, 255 ,255, 100);//need this comment later for tinting, etc

/*for(int j=0; j int m = j + 1;
carlos[j] = loadImage("boxing" + m + ".jpg");
}*/

b = loadImage("boxing1NL.jpg");
c = loadImage("bsuit.gif");

for(int i=0; i int n = i + 1;
carlos[i] = loadImage("carlos" + n + ".gif");
}

startTime = millis();

}
void loop(){
background(0,0,0);
showImage(); //Show appropriate image based on input from microphone
if (showing) {
if (whichImage == 1) {
image(b, 0, 0);

} else if (whichImage == 2) {
image(c,0,0);
}
if (millis() - startTime > picDislayTime) {
showing = false;
}
}

showMeterLevel(); //Show simulated movie clip - acts like a meter based on volume from mic
if (slowDown) {
image (carlos[a], 0, 0, carlos[0].width, carlos[0].height - mouseY); //display each image in sequence
if (millis() - startTimeMov > movDisplayTime){
slowDown = false;
}
}
}

void showMeterLevel(){//Show simulated movie clip - acts like a meter based on volume from mic

float meterDataLeft = 1000 * LiveInput.getLevel(Sonia.LEFT);
float meterDataRight = 1000 * LiveInput.getLevel(Sonia.RIGHT);

if (!slowDown) {
image (carlos[a], 0, 0, carlos[0].width, carlos[0].height - mouseY); //display each image in sequence
a = a + 1;
if ( a >= numOfPics ) {
a = 0;
}
slowDown = true;
startTimeMov = millis();
}
}
// Safely close the sound engine upon Browser shutdown.
public void stop(){
Sonia.stop();
super.stop();
}

void showImage()//Show appropriate background image based on input from microphone
{
float meterDataLeft = 1000 * LiveInput.getLevel(Sonia.LEFT);
float meterDataRight = 1000 * LiveInput.getLevel(Sonia.RIGHT);
println(startTimeMov);

if (!showing) {
if (meterDataLeft > 500) {
whichImage = 1;
showing = true;
startTime = millis();
} else if (meterDataLeft > 200){
whichImage = 2;
showing = true;
startTime = millis();
}
}
}

Wednesday, November 03, 2004

Interactive Punching Bag Project - Presentation III

Tonight we present for class. The following hardware is in place:

Wlodek's Crossover for low frequency microphone input
My mic inside the punching bag
Piezo strip motion sensor sewed to the punching bag
PIC chip and bread board with diode array
MIDI synthesizer
MIDI and audio cables
Amplifier
Speaker

The PIC BASIC PRO code for the PIC is as follows

'****************************************************************
'* Name : week7 MIDI with 1 pot *
'* Author : wk372 *
'* Date : 10/23/2004 *
'****************************************************************
' open the file with the definitions that we need:
INCLUDE "modedefs.bas"

DEFINE OSC 20
Define ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 15 ' Set sampling time in uS

'set up serial UART registers:
DEFINE HSER_RCSTA 90h ' enable the receive register
DEFINE HSER_TXSTA 20h ' enable the transmit register
DEFINE HSER_BAUD 31250 ' set the baud rate

TRISA = %11111111 'set PORTA to all input

'setup ADCON1
ADCON1= %10000010

'declare an aarray of 12 word variables
pitch var byte(12)

'declare other variables
note var byte
ADCVar var word

'the 12 elements of the array called pitch are the 12 notes of a scale
pitch (0) =60 ' middle c
pitch (1) =61 ' C#
pitch (2) =62 ' D
pitch (3) =63 ' D#
pitch (4) =64 ' E
pitch (5) =65 ' F
pitch (6) =66 ' F#
pitch (7) =63 ' G
pitch (8) =68 ' G#
pitch (9) =69 ' A
pitch (10) =70 ' A#
pitch (11) =71 ' B


main
'mypot gave a value of 0 to 1023
ADCin 0, ADCVar
'convert to a range from o to 10
Note = ADCVar / 100

if ADCVar>600 then
'play note
hserout [$90, pitch(note),$40]
pause 250
'noteoff:
hserout[$80, pitch(note), $00]

endif

goto main