Go Down

Topic: Arduino Communicating with Processing  (Read 2008 times) previous topic - next topic

Orchid0

Hey,
I'm currently building this spectrum analyzer off of instructables:

http://www.instructables.com/id/Arduino-Processing-Audio-Spectrum-Analyzer/

Im using a different LED panel (mine is from adafruit.) I've changed the code and the
LED screen works with test light ups. So now I'm working on getting the spectrum analyzer to work.
I've been making progress. My arduino code compiles. however when I run processing FFT part of it
I get this error:

WARNING:  RXTX Version mismatch
   Jar version = RXTX-2.2pre1
   native lib Version = RXTX-2.2pre2


From my research I've found its files relating to how the 2 programs communicate with eachother. I read on the instructable's that he was using processing 1 and arduino one. To try and resolve the problem I downloaded arduino 1 and was always using processing 1.5.

Still the same error message.


Any ideas? I found a thread that was dated that recommended I find the 2 RXTX files and copy from one program to the other so that they match up. He said to look in the contents folder of wherever arduino is located on my PC. I can't find a content folder for the life of me...

Im so cloooooose! Thanks in advance!

Orchid0

I tried uploading in processing 3. I still get audio degradation, I had to install minim libraries. They both run but nothing happens.

PaulS

Quote
I get this error:

WARNING:  RXTX Version mismatch
   Jar version = RXTX-2.2pre1
   native lib Version = RXTX-2.2pre2
That's a funny way for Processing to spell ERROR.

Quote
Any ideas?
Keep your code on both ends a deep dark secret. so no one can help. Or not.

Orchid0

Here is my code for both programs.
I find on some forums if you post a couple hundred lines of code
nobody looks at it. and wasn't sure if it was neccesary.

Processing:
Code: [Select]
/**
  * Live Spectrum to Arduino
  *
  * Run an FFT on live line-in input, splits into 16 frequency bands, and send this data to an Arduino in 16 byte packets.
  * Based on http://processing.org/learning/libraries/forwardfft.html by ddf.
  */
 
import ddf.minim.analysis.*;
import ddf.minim.*;
import processing.serial.*; //library for serial communication
 
Serial port; //creates object "port" of serial class
 
Minim minim;
AudioInput in;
FFT fft;
float[] peaks;

int peak_hold_time = 1;  // how long before peak decays
int[] peak_age;  // tracks how long peak has been stable, before decaying

// how wide each 'peak' band is, in fft bins
int binsperband = 5;
int peaksize; // how many individual peak bands we have (dep. binsperband)
float gain = 40; // in dB
float dB_scale = 2.0;  // pixels per dB

int buffer_size = 1024;  // also sets FFT size (frequency resolution)
float sample_rate = 44100;

int spectrum_height = 176; // determines range of dB shown

int[] freq_array = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i,g;
float f;


float[] freq_height = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  //avg amplitude of each freq band

void setup()
{
  size(200, 200);

  minim = new Minim(this);
  port = new Serial(this, Serial.list()[1],9600); //set baud rate
 
  in = minim.getLineIn(Minim.MONO,buffer_size,sample_rate);
 
  // create an FFT object that has a time-domain buffer
  // the same size as line-in's sample buffer
  fft = new FFT(in.bufferSize(), in.sampleRate());
  // Tapered window important for log-domain display
  fft.window(FFT.HAMMING);

  // initialize peak-hold structures
  peaksize = 1+Math.round(fft.specSize()/binsperband);
  peaks = new float[peaksize];
  peak_age = new int[peaksize];
}


void draw()
{
for(int k=0; k<16; k++){
freq_array[k] = 0;
}

  // perform a forward FFT on the samples in input buffer
  fft.forward(in.mix);
  
// Frequency Band Ranges      
  freq_height[0] = fft.calcAvg((float) 0, (float) 50);
  freq_height[1] = fft.calcAvg((float) 51, (float) 69);
  freq_height[2] = fft.calcAvg((float) 70, (float) 94);
  freq_height[3] = fft.calcAvg((float) 95, (float) 129);
  freq_height[4] = fft.calcAvg((float) 130, (float) 176);
  freq_height[5] = fft.calcAvg((float) 177, (float) 241);
  freq_height[6] = fft.calcAvg((float) 242, (float) 331);
  freq_height[7] = fft.calcAvg((float) 332, (float) 453);
  freq_height[8] = fft.calcAvg((float) 454, (float) 620);
  freq_height[9] = fft.calcAvg((float) 621, (float) 850);
  freq_height[10] = fft.calcAvg((float) 851, (float) 1241);
  freq_height[11] = fft.calcAvg((float) 1242, (float) 1600);
  freq_height[12] = fft.calcAvg((float) 1601, (float) 2200);
  freq_height[13] = fft.calcAvg((float) 2201, (float) 3000);
  freq_height[14] = fft.calcAvg((float) 3001, (float) 4100);
  freq_height[15] = fft.calcAvg((float) 4101, (float) 5600);
  

// Amplitude Ranges  if else tree
  for(int j=0; j<16; j++){    
    if (freq_height[j] < 200000 && freq_height[j] > 200){freq_array[j] = 16;}
    else{ if (freq_height[j] <= 300 && freq_height[j] > 150){freq_array[j] = 15;}
    else{ if (freq_height[j] <= 250 && freq_height[j] > 125){freq_array[j] = 14;}
    else{ if (freq_height[j] <= 200 && freq_height[j] > 100){freq_array[j] = 13;}
    else{ if (freq_height[j] <= 160 && freq_height[j] > 90){freq_array[j] = 12;}
    else{ if (freq_height[j] <= 150 && freq_height[j] > 75){freq_array[j] = 11;}
    else{ if (freq_height[j] <= 140 && freq_height[j] > 65){freq_array[j] = 10;}
    else{ if (freq_height[j] <= 120 && freq_height[j] > 50){freq_array[j] = 9;}
    else{ if (freq_height[j] <= 50 && freq_height[j] > 45){freq_array[j] = 8;}
    else{ if (freq_height[j] <= 45 && freq_height[j] > 40){freq_array[j] = 7;}
    else{ if (freq_height[j] <= 40 && freq_height[j] > 35){freq_array[j] = 6;}
    else{ if (freq_height[j] <= 35 && freq_height[j] > 30){freq_array[j] = 5;}
    else{ if (freq_height[j] <= 30 && freq_height[j] > 15){freq_array[j] = 4;}
    else{ if (freq_height[j] <= 15 && freq_height[j] > 10){freq_array[j] = 3;}
    else{ if (freq_height[j] <= 10 && freq_height[j] > 5){freq_array[j] = 2;}
    else{ if (freq_height[j] <= 5 && freq_height[j] >= 1 ){freq_array[j] = 1;}
    else{ if (freq_height[j] < 1 ){freq_array[j] = 0;}
  }}}}}}}}}}}}}}}}}

  //send to serial
  port.write(0xff); //write marker (0xff) for synchronization
  
  for(i=0; i<16; i++){
    port.write((byte)(freq_array[i]));
  }
  //delay(2); //delay for safety
}
 
 
void stop()
{
  // always close Minim audio classes when you finish with them
  in.close();
  minim.stop();
 
  super.stop();
}




PaulS

Code: [Select]
  port = new Serial(this, Serial.list()[1],9600); //set baud rate
Are you positive that the Arduino is connected to the second item in the list?

Code: [Select]
  }}}}}}}}}}}}}}}}}
WTF?

ONE closing curly brace per line. You wouldn't need all that shit if you were using else if instead of else{ if.

Put EVERY { on a new line.

Put ONE statement on a line.

The code on the other end is still a mystery. If it looks as bad as the Processing code, don't bother posting it.

Orchid0

#5
Dec 07, 2015, 06:10 am Last Edit: Dec 07, 2015, 06:41 am by Orchid0
Here's the arduino code.

Code: [Select]
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library

#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
#define LAT A3
#define OE 9
#define A A0
#define B A1
#define C A2


RGBmatrixPanel dotmatrix(A, B, C, CLK, LAT, OE, false);

uint32_t BLACK = dotmatrix.Color333(0,0,1);
uint32_t GREEN = dotmatrix.Color333(0, 7, 0);
uint32_t RED = dotmatrix.Color333(7, 0, 0);
uint32_t YELLOW = dotmatrix.Color333(7, 3, 0);
uint32_t ORANGE = dotmatrix.Color333(7, 3, 3);

int array[16] =    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int arraytemp[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int i, j, k, r;

void setup ()
{
  Serial.begin(9600);
  dotmatrix.fillScreen(BLACK);
}

void loop() {
  delay(15);
  if (Serial.read() != 0xff)  return;
 
  for (int i = 0; i != 16; array[i++] = Serial.read());
 
  for (int j = 0; j != 16; ++j) {
    const int val = array[j];
    if (val < 0 | val > 16 | val == arraytemp[j])  continue;
    arraytemp[j] = val;
 
    if (val < 2)  dotmatrix.drawLine(2 * j, 0, 2 * j, 15, BLACK);
    else          dotmatrix.drawLine(2 * j, 15, 2 * j, 0, BLACK);
 
    dotmatrix.drawLine(2 * j + 1, 0, 2 * j + 1, 15, BLACK);
 
    switch (val) {
    case 1:
      dotmatrix.drawPixel(2 * j, 15, GREEN);
      dotmatrix.drawPixel(2 * j + 1, 15, GREEN);
      break;
    case 2:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 14, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 14, GREEN);
      break;
    case 3:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 13, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 13, GREEN);
      break;
    case 4:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 12, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 12, GREEN);
      break;
    case 5:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 11, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 11, GREEN);
      break;
    case 6:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 10, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 10, GREEN);
      break;
    case 7:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 9, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 9, GREEN);
      break;
    case 8:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 8, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 8, GREEN);
      break;
    case 9:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 7, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 7, GREEN);
      break;
    case 10:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 6, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 6, GREEN);
      break;
    case 11:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
      break;
    case 12:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 4, ORANGE);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 4, ORANGE);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
      break;
    case 13:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 3, ORANGE);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 3, ORANGE);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
      break;
    case 14:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 2, ORANGE);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 2, ORANGE);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
      break;
    case 15:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 1, RED);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 2, ORANGE);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 1, RED);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 2, ORANGE);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
      break;
    case 16:
      dotmatrix.drawLine(2 * j, 15, 2 * j, 0, RED);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 2, ORANGE);
      dotmatrix.drawLine(2 * j, 15, 2 * j, 5, GREEN);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 0, RED);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 2, ORANGE);
      dotmatrix.drawLine(2 * j + 1, 15, 2 * j + 1, 5, GREEN);
    }
  }
}

PaulS

Code: [Select]
  if (Serial.read() != 0xff)  return;
If there is nothing to read, skip the rest of the code. Under what circumstances will the next statement be executed? That is, how many bytes of data will be available when this statement does not cause a return?

Any answer other than 1 is WRONG.

Code: [Select]
  for (int i = 0; i != 16; array[i++] = Serial.read());
Therefore, trying to read 16 of the 1 available bytes is WRONG.

Orchid0

Code: [Select]
void loop() {
  delay(15);
  if(Serial.available() <= 16) return;                                 // old version if (Serial.read() != 0xff)  return;
  for (int i = 0; i != 16; i++)
  {
   array[i] = Serial.read();
  }
 


Does that look better for the beginning of the loop? then it would grab 16 bytes before continuing?

I also made that loop less awkward.

Am I on the right track?

PaulS

Quote
Does that look better for the beginning of the loop? then it would grab 16 bytes before continuing?
Better, yes.

Even better would be to simply put all the serial data stuff in a
Code: [Select]
if(Serial.available() >= 16)
{
}

block.

The for loop should read (in my opinion):
Code: [Select]
  for (int i = 0; i < 16; i++)
  {
     // Do something while i is less than 16

Orchid0

Code: [Select]
if(Serial.available() >= 16)                                                 
{
   for (int i = 0; i < 16; i++)
  {
   array[i] = Serial.read();
  }}


????
I think that's what you mean.

if I put a serial.println() statement in the loop is arduino able to do transfer from processing to arduino to serial monitor?

Thanks for your help BTW.

PaulS

Quote
I think that's what you mean.
All the code that uses array needs to be in the block.

Multiple } do not belong on one line.

Quote
if I put a serial.println() statement in the loop is arduino able to do transfer from processing to arduino to serial monitor?
If you call your Mom, are you able to talk to the pizza joint, too? The serial port has one device/application on each end. If Processing is sending data, only Processing can read data. Fortunately, it can, and can show you what it read, using print() or println().

Orchid0

Hey paul,
I spent a few more hours with that code last night and got it working!
I just wanted to thank you for your help.
cheers.

PaulS

Quote
I spent a few more hours with that code last night and got it working!
Excellent.

Go Up