Arduino Forum

Using Arduino => LEDs and Multiplexing => Topic started by: nitinarora on Jul 29, 2017, 07:13 pm

Title: Max72xxPanel library
Post by: nitinarora on Jul 29, 2017, 07:13 pm
Hello kind people,

I have been a silent lurker for a a while and have by and large been able to resolve my issues with the resolutions posted by the experienced folks here. However I have run into an issue that I am unable to resolve. My idea is to build a 16x64 audio spectrum analyzer. I have the code working for an 8x64 matrix, but my problem is that when using a 16x64 matrix things go crazy. Below is a code snippet that i use to test the matrix:

Code: [Select]

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays = 1;


Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);


void setup() {
matrix.setIntensity(15);

// Adjust to your own needs
matrix.setPosition(0, 0, 1); // The first display is at <0, 0>
matrix.setPosition(1, 1, 1); // The second display is at <1, 0>
matrix.setPosition(2, 2, 1); // The third display is at <2, 0>
matrix.setPosition(3, 3, 1); // And the last display is at <3, 0>
matrix.setPosition(4, 4, 1); // And the last display is at <3, 0>
matrix.setPosition(5, 5, 1); // And the last display is at <3, 0>
matrix.setPosition(6, 6, 1); // And the last display is at <3, 0>
matrix.setPosition(7, 7, 1); // And the last display is at <3, 0>

matrix.setPosition(8, 0, 0); // The first display is at <0, 0>
matrix.setPosition(9, 1, 0); // The second display is at <1, 0>
matrix.setPosition(10, 2, 0); // The third display is at <2, 0>
matrix.setPosition(11, 3, 0); // And the last display is at <3, 0>
matrix.setPosition(12, 4, 0); // And the last display is at <3, 0>
matrix.setPosition(13, 5, 0); // And the last display is at <3, 0>
matrix.setPosition(14, 6, 0); // And the last display is at <3, 0>
matrix.setPosition(15, 7, 0); // And the last display is at <3, 0>
//  ...
matrix.setRotation(0, 1);    // The first display is position upside down
matrix.setRotation(1, 1);   
matrix.setRotation(2, 1);   
matrix.setRotation(3, 1);    // The same hold for the last display
matrix.setRotation(4, 1);   
matrix.setRotation(5, 1);   
matrix.setRotation(6, 1);   
matrix.setRotation(7, 1);   
matrix.setRotation(8, 1);    // The first display is position upside down
matrix.setRotation(9, 1);   
matrix.setRotation(10, 1);   
matrix.setRotation(11, 1);    // The same hold for the last display
matrix.setRotation(12, 1);   
matrix.setRotation(13, 1);   
matrix.setRotation(14, 1);   
matrix.setRotation(15, 1);   
}

void loop() {
  // put your main code here, to run repeatedly

matrix.fillScreen(LOW);
for (int x = 0; x<matrix.width(); x++){
       //int temp = amplitude[x];
   for(int y = 0; y<=16;y++){
       matrix.drawLine(x, 16, x, 16 - y, HIGH);
       matrix.write(); // Send bitmap to display
       delay(10);
      }
    }
}


My basic issue is that the arduino-Max72xxPanel seems to refuse to work after 10 modules. I am happy to edit the library source. However I am have no clue where to begin. Can some one one please point me in the correct direction? Appreciate the help.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: INTP on Jul 29, 2017, 07:26 pm
Does the lib mention a limit to number of addresses?
Title: Re: Max72xxPanel library
Post by: nitinarora on Jul 29, 2017, 07:33 pm
Thank you for the reply. I haven't seen an official citation so honestly I am not sure. I was going through the source code but unfortunately I am not very confident from there either.

Thanks
Nitin.
Title: Re: Max72xxPanel library
Post by: nitinarora on Jul 31, 2017, 10:07 am
I spent a considerable amount of time yesterday trying to trouble shoot this. I probably should have been more descriptive in my initial post. My setup is 2 sets of 8 8x8 matrices stacked one on top of the other to make a 16x64 matrix. The first display is the bottom left and this is the one connected to the Arduino. The 8th display is connected to the top left matrix. I had tested the setup with a 8x64 and it would work just fine.

Currently if i edit

Code: [Select]
matrix.drawLine(x, 16, x, 16 - y, HIGH);

to

Code: [Select]
matrix.drawLine(16, 16, 16, 0, HIGH);

the lower half of the display correctly draws a line from the first column of the third display to the top but the top half which I would expect to behave similarly (first column on the 11th display) to be lit up instead has the last column of the 10th display on.

I haven't tried Parola. Does anyone know if it supports simple graphics primitives such as a line?

Again would much appreciate if someone can point me in the correct direction. I am happy to invest time in trying to modify the library, but a pointer to the correct place would help immensely.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Aug 02, 2017, 02:39 pm
Quote
My basic issue is that the arduino-Max72xxPanel seems to refuse to work after 10 modules.
You got decoupling caps on all those modules?
Title: Re: Max72xxPanel library
Post by: nitinarora on Aug 03, 2017, 08:03 am
You got decoupling caps on all those modules?
As fate would have it, I am replying to this from work and all of last night and whatever little time I had in the morning I was kicking myself in the rear reminding myself of the article on your website that has helped me so much in the past about the absolute need for proper decoupling. The modules were the prefabricated type and did have the 0.1uf ceramics but no electrolytics. Added individual 10uf as recommended by the data sheet and viola.

That along with this:

http://forum.arduino.cc/index.php?topic=268670.0


where you highlight the need for proper line termination sorted things out for me. I did order a few buffers because I might scale this up a bit but two lessons learned:

1. Decoupling is not optional.
2. Listen to Mike.


Thank you for all the help. On to the next challenge!! Boy is physics an unforgiving master.

oh! and did I mention - Listen to Mike, he knows what he is talking about!!!!!!!


Thank you
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Aug 03, 2017, 10:39 am
Quote
Boy is physics an unforgiving master.
But at least she is consistent  :)

Glad I could help in getting it sorted.
Title: Re: Max72xxPanel library
Post by: nitinarora on Aug 03, 2017, 11:21 am
But at least she is consistent  :)

Glad I could help in getting it sorted.
True. And as it stands today, I believe consistency is what the world needs more of. A lot more!!

I look forward to learning more here.

Cheers!!
Title: Re: Max72xxPanel library
Post by: nitinarora on Aug 22, 2017, 08:43 am
Hi,

Apologies in advance for a longish post but I want to put in as much details as I can. I was not sure if I should start a new topic since the question relates to the same project but involves the code and I did not want to cross post.

The idea of the project was to make a 16x64 audio spectrum analyzer with the FFT running on a laptop on processing sending data to an HC-05 BT module to a standalone Arduino that drives the Max7219 displays. I have been able to verify that the 8x8 modules work fine. The processing code that I am using is adapted from here:

https://github.com/snskreationz/Real-Time-RGB-Matrix-Spectrum-Analyzer


Code: [Select]
import processing.serial.*;
//import processing.sound.*;
import ddf.minim.analysis.*;
import ddf.minim.*;


Minim minim;
AudioInput in;
FFT fft;
int buffer_size = 4096;
float sample_rate = 200000;
int freq_width = 150;
int bands = 64;
Serial port1;
float[] spectrum = new float[bands];
int [ ]freq_array = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
float[] freq_height = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void settings()
{
 size(512, 360);
}
void setup() {
 
  background(255);
    
  // Create an Input stream which is routed into the Amplitude analyzer
  minim = new Minim(this);
  
  // start the Audio Input
  in = minim.getLineIn(Minim.MONO,buffer_size, sample_rate);
  
  // patch the AudioIn
  // 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);
  port1 = new Serial (this, "COM5", 115200);
}      

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

 fft.forward(in.mix);
 
  freq_height[0] = fft.calcAvg((float) 0, (float) 30);
  freq_height[1] = fft.calcAvg((float) 31, (float) 60);
  freq_height[2] = fft.calcAvg((float) 61, (float) 100);
  freq_height[3] = fft.calcAvg((float) 101, (float) 150);
  freq_height[4] = fft.calcAvg((float) 151, (float) 200);
  freq_height[5] = fft.calcAvg((float) 201, (float) 250);
  freq_height[6] = fft.calcAvg((float) 251, (float) 300);
  freq_height[7] = fft.calcAvg((float) 301, (float) 350);
  freq_height[8] = fft.calcAvg((float) 351, (float) 400);
  
  for(int n = 9; n < 63; n++)
  {
  freq_height[n] = fft.calcAvg((float) (351+(freq_width*(n-9))), (float) (500+(freq_width*(n-9))));
  }
  
  freq_height[63] = (fft.calcAvg((float) 20, (float) 60));
  
  float x = 8;
  float y = 3;
  for(int j=0; j<64; j++){    
    freq_height[j] = freq_height[j]*(log(x)/y);
    x = x + (x);
  }
  
  for(int j=0; j<64; j++){    
    if (freq_height[j] < 2000 && freq_height[j] > 180){freq_array[j] = 16;}
    else{ if (freq_height[j] <= 180 && freq_height[j] > 160){freq_array[j] = 15;}
    else{ if (freq_height[j] <= 160 && freq_height[j] > 130){freq_array[j] = 14;}
    else{ if (freq_height[j] <= 130 && freq_height[j] > 110){freq_array[j] = 13;}
    else{ if (freq_height[j] <= 110 && freq_height[j] > 90){freq_array[j] = 12;}
    else{ if (freq_height[j] <= 90 && freq_height[j] > 70){freq_array[j] = 11;}
    else{ if (freq_height[j] <= 70 && freq_height[j] > 60){freq_array[j] = 10;}
    else{ if (freq_height[j] <= 60 && freq_height[j] > 50){freq_array[j] = 9;}
    else{ if (freq_height[j] <= 50 && freq_height[j] > 40){freq_array[j] = 8;}
    else{ if (freq_height[j] <= 40 && freq_height[j] > 30){freq_array[j] = 7;}
    else{ if (freq_height[j] <= 30 && freq_height[j] > 20){freq_array[j] = 6;}
    else{ if (freq_height[j] <= 20 && freq_height[j] > 15){freq_array[j] = 5;}
    else{ if (freq_height[j] <= 15 && freq_height[j] > 11){freq_array[j] = 4;}
    else{ if (freq_height[j] <= 11 && freq_height[j] > 8){freq_array[j] = 3;}
    else{ if (freq_height[j] <= 8 && freq_height[j] > 5){freq_array[j] = 2;}
    else{ if (freq_height[j] <= 5 && freq_height[j] > 2){freq_array[j] = 1;}
    else{ if (freq_height[j] <= 2 && freq_height[j] > 0){freq_array[j] = 0;}
  }}}}}}}}}}}}}}}}}
  
    String sta = "M";
    String aa = str(freq_array[0]);
    String bb = str(freq_array[1]);
    String cc = str(freq_array[2]);
    String dd = str(freq_array[3]);
    String ee = str(freq_array[4]);
    String ff = str(freq_array[5]);
    String gg = str(freq_array[6]);
    String hh = str(freq_array[7]);
    String ii = str(freq_array[8]);
    String jj = str(freq_array[9]);
    String kk = str(freq_array[10]);
    String ll = str(freq_array[11]);
    String mm = str(freq_array[12]);
    String nn = str(freq_array[13]);
    String oo = str(freq_array[14]);
    String pp = str(freq_array[15]);
    String qq = str(freq_array[16]);
    String rr = str(freq_array[17]);
    String ss = str(freq_array[18]);
    String tt = str(freq_array[19]);
    String uu = str(freq_array[20]);
    String vv = str(freq_array[21]);
    String ww = str(freq_array[22]);
    String xx = str(freq_array[23]);
    String yy = str(freq_array[24]);
    String zz = str(freq_array[25]);
    String aaa = str(freq_array[26]);
    String bbb = str(freq_array[27]);
    String ccc = str(freq_array[28]);
    String ddd = str(freq_array[28]);
    String eee = str(freq_array[30]);
    String fff = str(freq_array[31]);
    String ggg = str(freq_array[32]);
    String hhh = str(freq_array[33]);
    String iii = str(freq_array[34]);
    String jjj = str(freq_array[35]);
    String kkk = str(freq_array[36]);
    String lll = str(freq_array[37]);
    String mmm = str(freq_array[38]);
    String nnn = str(freq_array[39]);
    String ooo = str(freq_array[40]);
    String ppp = str(freq_array[41]);
    String qqq = str(freq_array[42]);
    String rrr = str(freq_array[43]);
    String sss = str(freq_array[44]);
    String ttt = str(freq_array[45]);
    String uuu = str(freq_array[46]);
    String vvv = str(freq_array[47]);
    String www = str(freq_array[48]);
    String xxx = str(freq_array[49]);
    String yyy = str(freq_array[50]);
    String zzz = str(freq_array[51]);
    String aaaa = str(freq_array[52]);
    String bbbb = str(freq_array[53]);
    String cccc = str(freq_array[54]);
    String dddd = str(freq_array[55]);
    String eeee = str(freq_array[56]);
    String ffff = str(freq_array[57]);
    String gggg = str(freq_array[58]);
    String hhhh = str(freq_array[59]);
    String iiii = str(freq_array[60]);
    String jjjj = str(freq_array[61]);
    String kkkk = str(freq_array[62]);
    String llll = str(freq_array[63]);
    String com = ",";
    String newl = "\n";
    String send1 = sta + com + aa + com + bb + com + cc + com + dd + com + ee + com + ff + com + gg + com + hh + com + ii + com + jj + com + kk + com + ll + com + mm + com + nn + com + oo + com + pp + com + qq + com + rr + com + ss + com + tt + com + uu + com + vv + com + ww + com + xx + com + yy + com + zz + com + aaa + com + bbb + com + ccc + com + ddd + com + eee + com + fff + com + ggg + com + hhh + com + iii + com+ jjj + com + kkk + com + lll + com + mmm + com + nnn + com + ooo + com + ppp + com + qqq + com + rrr + com + sss + com + ttt + com + uuu + com + vvv + com + www + com + xxx + com + yyy + com + zzz + com + aaaa + com + bbbb + com + cccc + com + dddd + com + eeee + com + ffff + com + gggg + com + hhhh + com + iiii + com + jjjj + com + kkkk + com + llll + newl;
    port1.write(send1);
    port1.clear();
}

void stop()
{
  in.close();
  minim.stop();
  super.stop();
}


Continued below:
Title: Re: Max72xxPanel library
Post by: nitinarora on Aug 22, 2017, 08:53 am
And the arduino side:

Code: [Select]
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10;
int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays = 2;
int amplitude[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
boolean Cleared = true;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

void setup() {

matrix.fillScreen(LOW);
matrix.write();
matrix.setIntensity(15);

matrix.setRotation(0, 1);  
matrix.setRotation(1, 1);    
matrix.setRotation(2, 1);    
matrix.setRotation(3, 1);    
matrix.setRotation(4, 1);    
matrix.setRotation(5, 1);    
matrix.setRotation(6, 1);    
matrix.setRotation(7, 1);  
matrix.setRotation(8, 1);    
matrix.setRotation(9, 1);
matrix.setRotation(10, 1);
matrix.setRotation(11, 1);
matrix.setRotation(12, 1);
matrix.setRotation(13, 1);
matrix.setRotation(14, 1);
matrix.setRotation(15, 1);
Serial.begin(115200);
delay(1000);
}

void loop() {
  
  if(Serial.read() == ('M')){
    for(int j=0; j<64; j++){
    amplitude[j]=Serial.parseInt();    
    }
   }  
  
  if(Serial.read()=='\n'){
    matrix.fillScreen(LOW);
    for (int x = 0; x<matrix.width(); x++){
       int temp = amplitude[x];
       matrix.drawLine(x, 16, x, 16 - temp, HIGH);
     }      
    matrix.write();
    for (int a = 0; a<64; a++){
      amplitude[a] = 0;
    }
   }
}


I understand that this can be improved by leaps and bounds but I was using this to prototype the system and have run into a problem. If I constraint the freq_height array values to a range of 0 - 8 by reducing the resolution, everything seems to work fine. Alternatively if I reduce the volume on the laptop thereby reducing the overall range of the values in the array things seem to work fine as well.

However as soon as I try to use the full resolution of 16 on max volume such that the freq_array has multiple double digit values the system simply hangs. I can see the last displayed frame on the matrix and that's it. I tried to use the BT module with SoftwareSerial (I do not have a Mega ATM) at a much lower baud rate and can see that the string reaches the Arduino. So I believe that I am parsing the string all wrong. I read through this:

https://forum.arduino.cc/index.php?topic=288234.0

but was unable to adapt the code to parse my incoming data (essentially M followed by 64 comma separated values ending in a new line). Although I can not understand why the above works with relatively small values in the freq_array.

I would really appreciate some help on this since I seem to have reached the end of my intellectual capacity.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Aug 22, 2017, 10:19 am
Yes the code could be very greatly improved it is very turged.

The problem on the Arduino side is that if you read an M from the serial port you then assume that their are 64 values to read and they might not all have arrived.


On the processing side you are being very wasteful sending the data as strings and giving the Arduino a lot more to do in converting that string into an int value.

If you only send int values then you cut down one hell of a lot of work the system has to do. Note your Arduino serial buffer is only 64 bytes anyway.
Title: Re: Max72xxPanel library
Post by: nitinarora on Aug 22, 2017, 11:02 am
Quote
Yes the code could be very greatly improved it is very turged.
Apologies for asking for help on such code but I am trying to get a proof of concept going and will optimize once I can get my head around this.

Quote
On the processing side you are being very wasteful sending the data as strings and giving the Arduino a lot more to do in converting that string into an int value.

If you only send int values then you cut down one hell of a lot of work the system has to do. Note your Arduino serial buffer is only 64 bytes anyway.
Super thanks for this. To get to think of it I need only a byte (?)/channel since I will send values from 0 - 16 only. So 64 bytes in all. Could you please let me know if this line of thought is correct? This would fit nicely within the 64 byte serial buffer?

Also on the processing side if I change the freq_array to byte, is there a way to send the byte array in a single go or would I need to run a loop to send the individual values?

As always much appreciate the help!!

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Aug 22, 2017, 02:26 pm
Quote
Could you please let me know if this line of thought is correct? This would fit nicely within the 64 byte serial buffer?
Yes this is the right lines.

With processing you always need to run through a loop to send an array.
Title: Re: Max72xxPanel library
Post by: nitinarora on Sep 15, 2017, 08:57 am
As an update to this, as suggested by Mike, I updated my Arduino code to the following:

Code: [Select]
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays = 2;

const byte numBytes = 64;
byte receivedBytes[numBytes] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
boolean newData = false;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

void setup() {

matrix.fillScreen(LOW);
matrix.write();
matrix.setIntensity(1);

matrix.setRotation(0, 1);    // The first display is position upside down
matrix.setRotation(1, 1);   
matrix.setRotation(2, 1);   
matrix.setRotation(3, 1);   
matrix.setRotation(4, 1);   
matrix.setRotation(5, 1);   
matrix.setRotation(6, 1);   
matrix.setRotation(7, 1);   
matrix.setRotation(8, 1);   
matrix.setRotation(9, 1);
matrix.setRotation(10, 1);
matrix.setRotation(11, 1);
matrix.setRotation(12, 1);
matrix.setRotation(13, 1);
matrix.setRotation(14, 1);
matrix.setRotation(15, 1);   // The same hold for the last display
Serial.begin(19200);
delay(1000);
 }

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    byte rc;
 
 if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedBytes[ndx] = rc;
                ndx++;
                /*if (ndx >= numBytes) {
                    ndx = numBytes - 1;
                }*/
            }
            else {
                //receivedBytes[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
      else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
  }
}
void showNewData() {
    if (newData == true) {     
        matrix.fillScreen(LOW);
         //matrix.write();
        for (int b = 0; b<matrix.width(); b++){
         int temp = int (receivedBytes[b]);
         int temp1 = min(16, temp);
         matrix.drawLine(b, 16, b, 16 - temp, HIGH);
         }
         matrix.write();
         
         for (int a = 0; a<64; a++){
          receivedBytes[a] = 0;
          }
        newData = false;
   
    }
   
}

void loop() { // run over and over
    recvWithStartEndMarkers();
    showNewData(); 
  }


This is all thanks to:

https://forum.arduino.cc/index.php?topic=288234.0
Title: Re: Max72xxPanel library
Post by: nitinarora on Sep 15, 2017, 09:08 am
In order to simply test the system I used a processing sketch:

Code: [Select]
import processing.serial.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

Minim minim;
AudioInput in;
FFT fft;
int buffer_size = 4096;
float sample_rate = 200000;
int freq_width = 150;
int bands = 64;
Serial port1;
float[] spectrum = new float[bands];
byte []freq_array = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
float[] freq_height = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
char start = '<';
char end = '>';

void settings()
{
 size(512, 360);
}
void setup() {
  background(255);
  port1 = new Serial (this, "COM7", 19200);
}      

void draw() {
  background(255);
  
  for(int j=0; j<64; j++){    
  freq_array[j] = byte(random(0,17));
  }
 port1.write(start);
 port1.write(freq_array);
 port1.write(end);
}

void stop()
{
  in.close();
  minim.stop();
  super.stop();
}


Now, the original idea was to have this working wireless with an HC05 module. But to first validate the system I simply used an FTDI basic board to hook up the standalone arduino to the computer running the processing sketch.

The problem that I am currently facing is that this seems to work just fine at 19200 baud but the display is laggy (essentially out of sync with the music). If I use a higher baud, say 38400, the display simply hangs at random (the arduino side) even when running the above processing test sketch.

However, adding a small delay at the end of port1.write(end) (40ms was the minimum I could go to), the  system seems to work fine. While this solution somewhat works, I am wondering if someone could help me understand this behavior and if there is a way around this.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Sep 15, 2017, 09:31 am
You have nothing to stop the byte data being equal to the stop or start marker. So I would expect it to jam up at any speed.
Title: Re: Max72xxPanel library
Post by: nitinarora on Sep 15, 2017, 09:39 am
You have nothing to stop the byte data being equal to the stop or start marker. So I would expect it to jam up at any speed.
Thanks for the quick reply Mike. I apologize if I did not understand your comment correctly. You are saying that if the data being sent by the processing serial at some point becomes equal to either the start/stop markers unintentionally then the sketch on the arduino would misinterpret this as the start or the end of the data stream?

A quick follow up on this though, if my above understanding is correct then the ASCII value of the start and the stop markers, 60 and 62 respectively would be the cause of the problem? The reason that I ask this is because the data that I send only ever has values between 0 - 16 from this line:


freq_array[j] = byte(random(0,17));


Again I really appreciate you taking the time to guide me.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Sep 15, 2017, 09:50 am
Quote
he reason that I ask this is because the data that I send only ever has values between 0 - 16 from this line:
Sorry I missed that bit, that will prevent the data being confused with the the sart bits.

However note that in Processing the draw function is not quite like the loop function as it only gets called 25 times a second not as fast as possible like the loop function.

Try timing how long it takes your Arduino to read a frame. Sending data faster and it it working does not make sense unless it is taking too long to do the stuff on the Arduino side and the input buffer is overflowing.
Title: Re: Max72xxPanel library
Post by: nitinarora on Sep 15, 2017, 09:57 am
However note that in Processing the draw function is not quite like the loop function as it only gets called 25 times a second not as fast as possible like the loop function.

Try timing how long it takes your Arduino to read a frame. Sending data faster and it it working does not make sense unless it is taking too long to do the stuff on the Arduino side and the input buffer is overflowing.
Ah! I did not know that about processing. Thanks for the pointer. I had a feeling that probably the Arduino is taking longer than the send speed to display the data. Incidentally in the processing sketch if I limit the values to 0 - 8, the sketch seems to run fine even at 115200.

I wish I had access to a scope or a logic analyzer to measure the timing. I am not sure if there is another approach to do this. Thanks for the help though I will try fiddling around with the baud rate and the delay till then.
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Sep 15, 2017, 12:05 pm
Quote
Incidentally in the processing sketch if I limit the values to 0 - 8, the sketch seems to run fine even at 115200.
That points at the display part taking too long before the next lot of data comes along.

You can slow down the rate that Processing kicks out the data by using the frameRate call:-
https://processing.org/reference/frameRate_.html (https://processing.org/reference/frameRate_.html)

Seems like the default rate is now 60 times a second not 25 like it used to be.
Title: Re: Max72xxPanel library
Post by: nitinarora on Sep 15, 2017, 12:14 pm
That points at the display part taking too long before the next lot of data comes along.

You can slow down the rate that Processing kicks out the data by using the frameRate call:-
https://processing.org/reference/frameRate_.html (https://processing.org/reference/frameRate_.html)

Seems like the default rate is now 60 times a second not 25 like it used to be.
Awesome! Thanks Mike.
Title: Re: Max72xxPanel library
Post by: nitinarora on Oct 13, 2017, 01:32 pm
Finally with the fantastic help from Mike I have some semblance of a working prototype in place. Video at (apologies for the bad quality of the video):

https://youtu.be/vx5XEpgvAeY

Look forward to many such projects.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: nitinarora on Dec 01, 2017, 10:20 am
I have been it itching to do more on this, mainly because it looks so cool. I was thinking of expanding this both horizontally and vertically. So probably from 64 to 128 channels and then from 16 rows to 32 rows.

But given the timing issues this naturally can not be done with a single ATMEGA. I am curious to understand if it is possible to use the same HC-05 and have its output physically go to 2 separate stand alone arduinos and then use the appropriate values from the output in software.

So basically in the processing sketch send over 128 values and use one arduino to drive the first 64 columns and the second one to drive the next 64 but with a single blue tooth module.

Would certainly appreciate any thoughts.

Thanks
Nitin
Title: Re: Max72xxPanel library
Post by: Grumpy_Mike on Dec 01, 2017, 08:18 pm
Quote
I am curious to understand if it is possible to use the same HC-05 and have its output physically go to 2 separate stand alone arduinos
If the data is one way only then yes, but I think it would involve some sort of acknowledgment signal and you can't have two Arduinos doing that. It would be better to receive all the data with one Arduino and have it pass on half that to the other Arduino.

However, two Arduinos is seldom the answer. As you have a Max7219 in the mix that is doing the grunt work in regard to multiplexing so their is nothing much holding you back from using just one. Are you chaining the Max7219s?
Title: Re: Max72xxPanel library
Post by: nitinarora on Dec 05, 2017, 12:54 pm
Thanks for the reply Mike. The data would only be one way since the way this is currently set up, the arduino does not send back a confirmation to the processing sketch doing the FFT to indicate the completion of the display of a frame.

I did some initial test to try to send data from the HC 05 to the PC over the weekend but that did not work. I will probably need more time to set it up properly.

I am using Max7219 based modules, but the problem in its current shape and form was that when sending data at >38400 baud with no acknowledgement/delay between transmissions, the arduino just hangs after a while. This happens specifically when the values from the FFT are large (substantial number of values >8). If i limit the values being sent by processing to 0 - 8 things work just fine even without a delay. If the arduino is taking too long to load the values to the 7219 and the new data set arrives before that, I suppose at some point the sketch on the arduino would lock up.

I currently have a delay of 40 milliseconds before transmissions on the processing and that seems to work well. If i increase the delay the display looks "out of sync" with the music, hence the thought of multiple arduinos.

Thanks for all the guidance.