Processing script (Minim example with serial stuff shoved in) displaying 'Null' input from arduino

edited December 2015 in Arduino

I'm trying to control the gain value of a song that's playing by using inputs from an arduino (0 or 1) I tested the arduino code with the general processing serial comm example and it works fine. I also tested my processing script with an arduino code that generates just 0s and 1s and that also works okay

Here's the processing script I'm using:

` /** * This sketch demonstrates how to play a file with Minim using an AudioPlayer.
* It's also a good example of how to draw the waveform of the audio. Full documentation * for AudioPlayer can be found at http://code.compartmental.net/minim/audioplayer_class_audioplayer.html *

* For more information about Minim and additional features, * visit http://code.compartmental.net/minim/ / import processing.serial.; import ddf.minim.*;

Serial myPort;
String val;
int a;

Minim minim;
AudioPlayer player;

void setup()
{

  myPort = new Serial(this, "COM3", 115200);

  size(512, 200, P3D);

  // we pass this to Minim so that it can load files from the data directory
  minim = new Minim(this);

  // loadFile will look in all the same places as loadImage does.
  // this means you can find files that are in the data folder and the 
  // sketch folder. you can also pass an absolute path, or a URL.
  player = minim.loadFile("Highway to Hell.wav");
}

void draw()
{
  if ( myPort.available() > 0) 
  {  // If data is available,
  val =  (myPort.readStringUntil('\n')); 
     if (val != null) {
       val =trim(val);
     a = Integer.parseInt(val);
     }
     }
 if(a==1)
 {
  player.setGain(0); 
 }
 else if(a==0)
 {
   player.setGain(-30);
 }
  //println(val);
   if (mousePressed == true) 
  {                           //if we clicked in the window
   myPort.write('1');         //send a 1
   println("1");   
  } else 
  {                           //otherwise
  myPort.write('0');          //send a 0
  }   


  background(0);
  stroke(255);

  // draw the waveforms
  // the values returned by left.get() and right.get() will be between -1 and 1,
  // so we need to scale them up to see the waveform
  // note that if the file is MONO, left.get() and right.get() will return the same value
  for(int i = 0; i < player.bufferSize() - 1; i++)
  {
    float x1 = map( i, 0, player.bufferSize(), 0, width );
    float x2 = map( i+1, 0, player.bufferSize(), 0, width );
    line( x1, 50 + player.left.get(i)*50, x2, 50 + player.left.get(i+1)*50 );
    line( x1, 150 + player.right.get(i)*50, x2, 150 + player.right.get(i+1)*50 );
  }

  // draw a line to show where in the song playback is currently located
  float posx = map(player.position(), 0, player.length(), 0, width);
  stroke(0,200,0);
  line(posx, 0, posx, height);

  if ( player.isPlaying() )
  {
    text("Press any key to pause playback.", 10, 20 );
  }
  else
  {
    text("Press any key to start playback.", 10, 20 );
  }


if (keyPressed)
{
  {if(key == 'b')
  if ( player.isPlaying() )
  {
    player.pause();

  }

  // if the player is at the end of the file,
  // we have to rewind it before telling it to play again
  else if ( player.position() == player.length() )
  {
    player.rewind();
    player.play();
  }
  else
  {
    player.play();
  }
  }}}`

and the Arduino script I used to generate the 0s and1s:

`Serial.begin(115200);

}

// the loop routine runs over and over again forever:
void loop() {
  if (Serial.available()) 
   { // If data is available to read,
     val = Serial.read(); // read it and store it in val
   }
   if (val == '1') 
   {
  // read the input pin:

  // print out the state of the button:
  Serial.println("0");
  delay(1000);        // delay in between reads for stability
  Serial.println("1");
  delay(1000);
  Serial.println("0");
  delay(1000);        // delay in between reads for stability
  Serial.println("1");
  delay(1000);
  Serial.println("0");
  delay(1000);        // delay in between reads for stability
  Serial.println("1");
  delay(1000);Serial.println("0");
  delay(1000);        // delay in between reads for stability
  Serial.println("1");
  delay(1000);
   }


}
`

I'm using an input from processing ( a mouse click right now) to initialize the arduino code that does the 0s and 1s.

I then tried using the processing script with my actual arduino code:

` #include "eott.h"
  boolean Button1flag= LOW; // these are flags... I don't know why these are here
  boolean Button2flag= LOW;
  boolean Button3flag= LOW;

  int Buttonstate1 ; // these are the button states, read from the arduino
  int Buttonstate2 ;
  int Buttonstate3 ;


  int A=0;
  int B=0;
  int C=0;

  int i=0; // i will drive the array row change


  /* this is the array that would correspond to the song, a poor substitute for a MIDI file but simple. every row is a 25 ms block of the song.
  This is a test , ideally the array would be stored outside the code so I can call different 'songs'*/




  long Delay= 137.6121539054329; //this is the delay, and the duration for which each loop will run
  long t=0; // millis wil keep track of the time

void setup() {

// First define all the inputs and outputs
  pinMode(11,INPUT); // Pins 2,3,4 are the inputs where the buttons will be connected
  pinMode(12,INPUT);
  pinMode(13,INPUT);
  pinMode(2,OUTPUT); // Pins 11,12,13 are the outputs where the vibration motors will be connected (and mounted to the vibrators)
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(8,OUTPUT);
  Serial.begin(115200); // start the serial code at 9600 bpa
}

void loop() {
    if (i<=167)
 {
  i++;
 }
else {i=0;}//{while(1);}
 A= array[i][0];
 B= array[i][1];
 C= array[i][2];
   digitalWrite(2,A);
   digitalWrite(3,B);
   digitalWrite(4,C);
   digitalWrite(8,LOW);


  // put your main code here, to run repeatedly:
while (millis()<=t+Delay) // run the loop while the current value of millis is less than the sum of the previous time and the delay value
{
   Buttonstate1 = digitalRead(11); // these are the button states, read from the arduino
   Buttonstate2 = digitalRead(12);
   Buttonstate3 = digitalRead(13);

  if (Buttonstate1==A) //first condition: is button1 equal to the corresponding array value?
      {if (Buttonstate2==B) // second condition
          {if  (Buttonstate3==C) // basically if all three conditions are not met, the output is false
              {
                Serial.println("1"); // send a signal to processing to increase the volume of the song to signify success
                digitalWrite(8,HIGH);
                }
              }


  }
  else {
        Serial.println("0"); // this will tell processing to reduce the volume of the song, signifying failure.
        digitalWrite(8, LOW);
        }
  }
  t=millis();

/*
Serial.print(A);{0,0,0},

Serial.print("\t");
Serial.print(B);
Serial.print("\t");
Serial.print(C);
Serial.print("\t");
*/
}

`

This code takes an array (stored in eott.h) and outputs the array values to LEDs, while looking for input from buttons corresponding to the LEDs. if all three buttons match with the array value, it prints a "1" to the serial port, else it prints a "0".

but in this case , the code shows me an error NumberFormatException for input string "00" the values inside the quotes keeps changing every time I try to run the program. It then proceeds to crash.

Any help would be greatly appreciated, Thank you!

Answers

  • I think the following line is causing the problem:

    a = Integer.parseInt(val);

    paseInt() can throw an Exception if val is an empty Sring for example.
    You should use a try-catch construct here to handle unexpected input.

      try {      
        a = Integer.parseInt(val);;
      }
      catch(NumberFormatException e) {
        println(e);
      }
    

    If you use serial-data, it is always a good idea to check if the mesages you receive are valid. For more information on Integer.parseInt() have alook at the java-documentation.

  • edited December 2015
Sign In or Register to comment.