8x8 LED Spectrum Analyzer - faint threshold value

I've built a spectrum analyzer with an MSGEQ7 chip, which posts to an 8x8 LED Matrix (max7219). I also have (7) potentiometers that also post to the 8x8 LED Matrix.

The potentiometer values are appearing faint/flickering and are difficult to see. See a video of the issue here:
YouTube - LED Display

Is this something that can be corrected with code, or am I asking for something that's impossible to achieve?

Here's a copy of my code:

#include "LedControl.h"

#define msg7RESET 13
#define msg7Strobe 9
#define msg7DCout A7

#define maxDataIn 10
#define maxLoad 11
#define maxCLK 12

#define led0 2
#define led1 3
#define led2 4
#define led3 5
#define led4 6
#define led5 7
#define led6 8

int TRIM_POT_A[7] = {A0,A1,A2,A3,A4,A5,A6};
#define LED_LOW HIGH  //was LOW
#define LED_HIGH LOW  //was HIGH
#define CYCLE_DELAY 50 // set to 100 for mechanical relay, set to 50 for solid state relay


LedControl lc=LedControl(maxDataIn,maxCLK,maxLoad,1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=100;
byte ledPins[7]= {led0,led1,led2,led3,led4,led5,led6};
byte level[8]=   {128,192,224,240,248,252,254,255};
byte setlevel[8]={128,64,32,16,8,4,2,1};
unsigned int valueMSG[7];
unsigned int potValue_A[7] = {0};
byte potSet_A[7] = {0};

void setup() {
  Serial.begin(115200);
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  pinMode(msg7RESET, OUTPUT);
  pinMode(msg7Strobe, OUTPUT);
  
  pinMode(led0, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  
  digitalWrite(msg7Strobe, HIGH);
  digitalWrite(msg7RESET, LOW);
  digitalWrite(led0, LED_LOW);
  digitalWrite(led1, LED_LOW);
  digitalWrite(led2, LED_LOW);
  digitalWrite(led3, LED_LOW);
  digitalWrite(led4, LED_LOW);
  digitalWrite(led5, LED_LOW);
  digitalWrite(led6, LED_LOW);


  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,1);
  /* and clear the display */
  lc.clearDisplay(0); 
}

void loop()
{ 
  digitalWrite(msg7Strobe, HIGH);  
  digitalWrite(msg7RESET, HIGH);
  //delayMicroseconds(0.1); //Reset Pluse Width 100nS Min
  digitalWrite(msg7RESET, LOW);
  delayMicroseconds(72); // Reset to Stobe Delay 72uS min
  
    for (int x = 0 ; x < 7 ; x++)
    {
      
      potValue_A[x] = analogRead(TRIM_POT_A[x]);
      potSet_A[x] = map(potValue_A[x], 0, 1024, 0, 8);  

      lc.setRow(0,x,setlevel[potSet_A[x]]);
      digitalWrite(msg7Strobe, LOW);
      delayMicroseconds(36); //Output settling time 36us Min

      int spectrumRead = analogRead(msg7DCout);
      
      valueMSG[x] = map(spectrumRead, 0, 1024, 0, 8);

      lc.setRow(0,x,level[valueMSG[x]]);
      digitalWrite(msg7Strobe, HIGH);
      delayMicroseconds(72); //Strobe to Strobe 72uS Min 
      
      //Set Lights 
      if(valueMSG[x] >= potSet_A[x])
      {
        digitalWrite(ledPins[x], LED_HIGH);
      }
      else
      {
        digitalWrite(ledPins[x], LED_LOW);
      }

      Serial.print("x = ");
      Serial.println(x);
      Serial.print("spectrumRead = ");
      Serial.println(spectrumRead);
      Serial.print("Potentiometer Value = ");
      Serial.println(potValue_A[x]);
      Serial.print("valueMSG[x] = ");
      Serial.println(valueMSG[x]);
      Serial.print("Potentiometer Setting = ");
      Serial.println(potSet_A[x]); 

      Serial.print('\n');
    }
    delay(CYCLE_DELAY); //Allow them to be on or off for a bit of time 
    
}

CYCLE_DELAY is too short. The human eye will not perceive changes less than about 200ms. Try making this longer and see if it helps.

You may want to consider not showing the immediate value you get from the MSGEQ7 as this will change rapidly. If you dampen the changes (eg, add/subtract a portion of the change from the last value) you may get a more pleasing effect.

1 Like

Thanks for the suggestion. I changed #define CYCLE_DELAY 50 to #define CYCLE_DELAY 500 but the issue still persists. Do you have any other suggestions?

Other suggestion is already in the previous answer.

I had to reread that a few times... but I think I understand what you're saying now... however, I'm satisfied with the way the MSGEQ7 is posting its results. What I'm not pleased with is the individual LED's indicating the threshold value. As you can see in the video I posted above, the individual threshold values are the faint/flickering LED's. Is this correctable, or is it a hardware limitation?

Try to fix the first 2 points,

  1. Analog reading value
    A reading value for the 10-bit analog shall be 0 to 1023.

    BIN:  11 1111 1111
    DEC:  1023
    
  2. Array index
    if the array size is 8, the index range shall be 0 to 7.

    byte level[8] = {128,192,224,240,248,252,254,255};
    
    DATA:  128  192  224  240  248  252  254  255
    INDEX:  0    1    2    3    4    5    6    7
    

Change the mapping of potSet_A[x]:

to:

potSet_A[x] = map(potValue_A[x], 0, 1023, 0, 7);

Change the mapping of valueMSG[x]:

to:

valueMSG[x] = map(spectrumRead, 0, 1023, 0, 7);

Yes, good catch, thanks. Unfortunately, this didn't resolve the issue. The video in my first post shows two things going on. The first row of bright lights are the MSGEQ7 Output which is working great. The the Second set of faint flickering lights show the potentiometer level, and I'd like these to not blink and somehow be bright like the MSGEQ7 values.

Not sure about your pattern/requirement. It depends on your design. The reference below combines setlevel and level.
Click here -> Wokwi Simulator

 byte data = setlevel[potSet_A[x]] | level[valueMSG[x]];
 lc.setRow(0, x, data);

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.