nov 7
jim aside
aaron
I'm having trouble figuring out why the processing sketch crashes out sometimes and has trouble running other times. There has been a repeated message nested deep within several layers of library calls about a list index out of range. I think what's happening is that sometimes the processing sketch receives only part of the line over serial and crashes out because the list I'm sending it is either too long or too short. I attempted to put in an error checking snippet that would check whether the first item (item 0) was 888 and the last item (item 3) was 999. This seemed to make the sketch run better but it still occasionally crashes.
On the other end of things, it's difficult sometimes to get the sketch to start up, presumably because the processing sketch starts up and reads only part of a line and throws errors until it gets an input that works, that's at least what I'm guessing is happening. I noticed if I hold the reset button on the arduino when the processing sketch starts up nothing is output to the graph while the reset button is held down (obvious) but it crashes a whole lot less than when I don't hold down the reset button.
I'm thinking some sort of call and response between the arduino and the processing sketch would be a good solution. The arduino would only give output once it received a message from processing that told it to start sending values. I thought of kludging my way around this problem by putting in C's equivalent of python's try and except but I wasn't sure if that existed.
arduino sketch:
//multiple_analog_output_11_04_11
int pin_0 = 0;
int pin_1 = 1;
void setup() {
// initialize the serial communication:
Serial.begin(9600);
}
void loop() {
// send the value of analog input 0:
Serial.print("888,")
Serial.print(analogRead(pin_0));
Serial.print(",");
Serial.print(analogRead(pin_1));
Serial.print(",999\n");
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(10);
}
Processing sketch:
//simple_analog_read_sound:
// [Dual] Graphing sketch (modified to graph two inputs and output two sine waves (using Minim)
// This program takes ASCII-encoded strings
// from the serial port at 9600 baud and graphs them. It expects values in the
// range 0 to 1023 [in a comma separated list (example: "10, 20, 30")], followed by a newline, or newline and carriage return
// Created 20 Apr 2005
// Updated 18 Jan 2008
// by Tom Igoe
// This example code is in the public domain.
//MODIFIED BY: Aaron Evan-Browning 11-04-11
import ddf.minim.*;
import ddf.minim.signals.*;
//import controlP5.*;
import processing.serial.*;
Minim minim;
AudioOutput out;
SineWave sine1;
SineWave sine2;
//TriangleWave tri;
//ControlP5 gui;
//public float triAmp = 0.5;
//public float triPan = 0;
//public float triFreq = 880;
//public float triFreq2 = 1;
float sin1Amp = 0.5; //these floats were public. I'm not sure why that was necessary. It was probably for the controlP5 GUI.
float sin1Pan = 0.5;
float sin1Freq = 440;
float sin2Amp = 0.5;
float sin2Pan = 0.5;
float sin2Freq = 330;
int sin1Glide = 10; //ms
int sin2Glide = 10; //ms
Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
int x_size = 1000;
int y_size = 500;
int switcher = 0;
void setup () {
// set the window size:
size (x_size, y_size); // this line also had ", P3D" as a parameter of size. We're just using 2 dimensions right now.
minim = new Minim(this);
// get a stereo line out from Minim with a 2048 sample buffer, default sample rate is 44100, bit depth is 16
out = minim.getLineOut(Minim.STEREO, 2048);
// create a sine wave Oscillator, set to 440 Hz, at 0.5 amplitude, sample rate 44100 to match the line out
sine1 = new SineWave(440, 0.5, out.sampleRate());
sine2 = new SineWave(330, 0.5, out.sampleRate());
// set the portamento speed on the oscillator to 200 milliseconds
sine1.portamento(sin1Glide);
sine2.portamento(sin2Glide);
// add the oscillator to the line out
out.addSignal(sine1);
out.addSignal(sine2);
// create a triangle wave Oscillator
//tri = new TriangleWave(880, 0.5, out.sampleRate());
//tri.portamento(200);
//out.addSignal(tri);
// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// set inital background:
background(0);
}
void draw () {
// everything happens in the serialEvent()
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
int incomingValues[] = int(split(inString, ",")); // convert to an array of ints ***taken from serialEvent.pde line 8 in http://web.media.mit.edu/~plusea/downloads/code/p_rSkin_11x11.zip ***
//float inByte = float(inString);
if ((incomingValues[0] == 888) && (incomingValues[3] == 999)){
//println(int(incomingValues[0]));
//println(int(incomingValues[3]));
sine1.setFreq(incomingValues[1]); //This updates the pitch of the sine wave every time the graph is drawn.
sine2.setFreq(incomingValues[2]);
//scale the output into the bounds of the box.
float graphline1 = map(incomingValues[1], 0, 1023, 0, height);
float graphline2 = map(incomingValues[2], 0, 1023, 0, height);
// draw the line:
switcher += 1;
if(switcher % 2 == 1){
stroke(0,0,255);
line(xPos, height, xPos, (height - graphline1));
}
else{
stroke(0, 255, 0);
line(xPos, height, xPos, (height - graphline2));
}
// at the edge of the screen, go back to the beginning:
if (xPos >= width) {
xPos = 0;
background(0);
}
else {
// increment the horizontal position:
xPos++;
}
}
}
delay(5);
}
void stop()
{
out.close();
minim.stop();
super.stop();
}