Analizador espectro LCD 20x4 con MSGEQ7

Hola a todos.
He leido este enlace y he intentado modificar el código para obtener en un LCD 20x4 en toda su pantalla el analizador sin exito.

El montaje usa un integrado filtrador de audio MSGEQ7, es cual en el código veo que lo han interpolado y de 7 bandas de filtro se expone en el LCD a 16, en el que pretendo lo he hecho funcionar a 20 columnas y esto no es problema.
El código original esta escrito para un LCD 16x2 el cual he usado uno por BUS I2C y funciona, pero solamente en estas dimensiones de 16x2 enlace código original,
Para el LCD uso la librería de Malpartida

Pictures;

He modificado ligeramente el código del primer enlace y obviamente no funciona. Este es;

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3f // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7


LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

byte vumetro[8][8];

float vumetros[16];

// The analog pin 0 is used to read value.
int valor_analogico = 0; 
// The 6 & 7 pins are used for control the integrated.
int strobe = 4; 
int reset = 5; 
int valores_frecuencias[7]; 

void setup() {
  
        lcd.begin(20, 4);
        lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
        lcd.setBacklight(HIGH);
  

  
  // Built the characters for bars.
  for (int j=0; j<=7; j++)  
  {
    for (int i=0; i<=7; i++)
    {
       for (int h=0; h<=7; h++)
      {
        for (int z=0; z<=7; z++)
        {
      if (i<=j)
      { vumetro[j][7-i] = B11111;} // B01110
//   { vumetro[j][i][h][7-z] = B11111;}
//      { vumetro[j][7-i] = B01010;}  Uncomment this lines for getting other variants for bars.
//      { vumetro[j][7-i] = B11111;}      
      else
      { vumetro[j][7-i] = 0;} 
//        { vumetro[j][i][h][7-z] = 0;}  
      }
    }
  }  
  for (int i=0; i<=7;i++)
  {
    lcd.createChar(i, vumetro[i]);
  }

  
  for (int j=0; j<=7;j++)
  {
    lcd.setCursor(j, 0);
    lcd.write(j);
    lcd.setCursor(j, 1);
    lcd.write(j);  
    lcd.setCursor(j, 2);
    lcd.write(j);
    lcd.setCursor(j, 3);
    lcd.write(7);   
    
  pinMode(valor_analogico, INPUT);
  pinMode(strobe, OUTPUT);
  pinMode(reset, OUTPUT);
  analogReference(DEFAULT);

  digitalWrite(reset, LOW);
  digitalWrite(strobe, HIGH);
    
  }  
  }
}

void loop() {
  
  digitalWrite(reset, HIGH);
  digitalWrite(reset, LOW);

  // The read of integrated is done by multiplexing.
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobe, LOW);
    delayMicroseconds(5); 
    valores_frecuencias[i] = analogRead(valor_analogico);
    digitalWrite(strobe, HIGH);
  }

// It's necesary to interpolate for calculating 16 bars having only 7 values read.
for (int k=0; k<=15; k++)
  {
  switch (k) 
  {
    case 0:
      vumetros[k]= valores_frecuencias[0]/64;
      break;
    
    case 1:
      vumetros[k]= (valores_frecuencias[0]/64 + valores_frecuencias[1]/64)/2;
      break;

    case 2:
      vumetros[k]= valores_frecuencias[1]/64;
      break;
   
    case 3:
      vumetros[k]= (valores_frecuencias[1]/64 + valores_frecuencias[2]/64)/2;
      break;
 
    case 4:
      vumetros[k]= valores_frecuencias[2]/64;
      break;
    
    case 5:
      vumetros[k]= (valores_frecuencias[1]/64 + valores_frecuencias[2]/64 + valores_frecuencias[3]/64)/3;
      break;
        
    case 6:
      vumetros[k]= (valores_frecuencias[2]/64 + valores_frecuencias[3]/64 + valores_frecuencias[4]/64)/3;
      break;

    case 7:
      vumetros[k]= random(2)+valores_frecuencias[3]/64;
      break;
      

    case 8:
      vumetros[k]= random(2)+valores_frecuencias[3]/64;
      break;

    case 9:
      vumetros[k]= (valores_frecuencias[2]/64 + valores_frecuencias[3]/64 + valores_frecuencias[4]/64)/3;
      break;

    case 10:
      vumetros[k]= (valores_frecuencias[3]/64 + valores_frecuencias[4]/64 + valores_frecuencias[5]/64)/3;
      break;

    case 11:
      vumetros[k]= valores_frecuencias[4]/64;
      break;

    case 12:
      vumetros[k]= (valores_frecuencias[4]/64 + valores_frecuencias[5]/64)/2;
      break;

    case 13:
      vumetros[k]= valores_frecuencias[5]/64;
      break;

    case 14:
      vumetros[k]= (valores_frecuencias[5]/64 + valores_frecuencias[6]/64)/2;
      break;

    case 15:
      vumetros[k]= valores_frecuencias[6]/64;
      break;
  }

  Dibuja_vumetro(k, vumetros[k]);
  delay(2);
  }
  
}


 void Dibuja_vumetro(int posicion, int altura)
{
  if (altura>7)
  {
    if (altura>14)
    {
      if (altura>21)
      {
        lcd.setCursor(posicion, 3);
        lcd.write(7);
        lcd.setCursor(posicion, 2);
        lcd.write(7);
        lcd.setCursor(posicion, 1);
        lcd.write(7);
        lcd.setCursor(posicion, 0);
        lcd.write(altura-8);
      }
      lcd.setCursor(posicion, 3);
      lcd.write(7);
      lcd.setCursor(posicion, 2);
      lcd.write(7);
      lcd.setCursor(posicion, 1);
      lcd.write(altura-8);
      lcd.setCursor(posicion, 0);
      lcd.write(32);
   }
    lcd.setCursor(posicion, 3);
    lcd.write(7);  //tutto acceso
    lcd.setCursor(posicion, 2);
    lcd.write(altura-8);
    lcd.setCursor(posicion, 1);
    lcd.write(32);
    lcd.setCursor(posicion, 0);
    lcd.write(32);   
  }
  else
  {
    lcd.setCursor(posicion, 3);
    lcd.write(altura);
    lcd.setCursor(posicion, 2);
    lcd.write(32);   //tutto spento
    lcd.setCursor(posicion, 1);
    lcd.write(32);
    lcd.setCursor(posicion, 0);
    lcd.write(32);   
  }
}

He visto por la red infinidad de vídeos he incluso usuarios que lograron hacer funcionar con este tipo de LCD (20x4) pero o bien ofrecen el HEX (el cual es diferente LCD, no dan información del conexionado, etc...) o bien simplemente no dan información del código fuente. Respeto totalmente la decisión faltaría mas.

He estado analizando el código de como componer las dos lineas (filas) para que lo represente a toda pantalla pero me he quedado estancado. Pido un poco de ayuda aunque sea alguna pista de como realizar que aumente una fila. si esto es posible, espero sus amables respuestas.

Un saludo

Para comenzar he mirado tu código y tiene muchos errores y repeticiones.
Creo que debiste analizarlo un poco mas.

El código es el mismo del enlace en inglés.
No veo que hayas hecho muchos cambios salvo el lcd_i2c de modo que tu estancamiento es como decir, no hice practicamente nada.

El setup tiene cosas repetidas sin sentido!!!
hay dos ciclos for en h y z que no se usan entonces para que hacerlos?
Pero el mayor error está en la rutina de prensentación y se debe a que se repite por cada paso todos los anteriores.
Si la altura fuera 21 lo que corresonde a las lineas 2 y 3, borran todo lo que corresponde a las lineas 0 y 1
Asi que modifiqué esa parte y el setup

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3f // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

byte vumetro[8][8];
float vumetros[16];

// The analog pin 0 is used to read value.
const byte valor_analogico 	= 0; 
// The 6 & 7 pins are used for control the integrated.
const byte strobe 				= 4; 
const byte reset 				= 5; 
int valores_frecuencias[7]; 

void setup() {
  
    lcd.begin(20, 4);
    lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
    lcd.setBacklight(HIGH);
    
  	// Built the characters for bars.
  	for (int j=0; j<=7; j++)  {
    	for (int i=0; i<=7; i++)    {
			if (i<=j) { 
				vumetro[j][7-i] = B11111;
			} // B01110
			else { 
      			vumetro[j][7-i] = 0;
      		} 
  		}  
	}
	
  	for (int i=0; i<=7;i++) {
    	lcd.createChar(i, vumetro[i]);
  	}  
	
	for (int j=0; j<=7;j++)  {
	    lcd.setCursor(j, 0);
	    lcd.write(j);
	    lcd.setCursor(j, 1);
	    lcd.write(j);  
	    lcd.setCursor(j, 2);
	    lcd.write(j);
	    lcd.setCursor(j, 3);
	    lcd.write(7);   
	}  
	  
	pinMode(valor_analogico, INPUT);
	pinMode(strobe, OUTPUT);
	pinMode(reset, OUTPUT);
	analogReference(DEFAULT);

	digitalWrite(reset, LOW);
	digitalWrite(strobe, HIGH);  
}

void loop() {
  
  digitalWrite(reset, HIGH);
  digitalWrite(reset, LOW);

  // The read of integrated is done by multiplexing.
  for (int i = 0; i < 7; i++)  {
    digitalWrite(strobe, LOW);
    delayMicroseconds(5); 
    valores_frecuencias[i] = analogRead(valor_analogico);
    digitalWrite(strobe, HIGH);
  }

  // It's necesary to interpolate for calculating 16 bars having only 7 values read.
  for (int k=0; k<=15; k++)  {
  	  switch (k)  {
	    case 0:  vumetros[k]= valores_frecuencias[0]/64;  
	      		 break;
        case 1:  vumetros[k]= (valores_frecuencias[0]/64 + valores_frecuencias[1]/64)/2;
      			 break;
	    case 2:  vumetros[k]= valores_frecuencias[1]/64;
      			 break;
 		case 3:  vumetros[k]= (valores_frecuencias[1]/64 + valores_frecuencias[2]/64)/2;
    			 break;
 		case 4:  vumetros[k]= valores_frecuencias[2]/64;
      			 break;
        case 5:  vumetros[k]= (valores_frecuencias[1]/64 + valores_frecuencias[2]/64 + valores_frecuencias[3]/64)/3;
      			 break;
        case 6:  vumetros[k]= (valores_frecuencias[2]/64 + valores_frecuencias[3]/64 + valores_frecuencias[4]/64)/3;
      			 break;
		case 7:  vumetros[k]= random(2)+valores_frecuencias[3]/64;
      			 break;
        case 8:  vumetros[k]= random(2)+valores_frecuencias[3]/64;
      			 break;
		case 9:  vumetros[k]= (valores_frecuencias[2]/64 + valores_frecuencias[3]/64 + valores_frecuencias[4]/64)/3;
      			 break;
		case 10: vumetros[k]= (valores_frecuencias[3]/64 + valores_frecuencias[4]/64 + valores_frecuencias[5]/64)/3;
      			 break;
		case 11: vumetros[k]= valores_frecuencias[4]/64;
      			 break;
	    case 12: vumetros[k]= (valores_frecuencias[4]/64 + valores_frecuencias[5]/64)/2;
      			 break;
		case 13: vumetros[k]= valores_frecuencias[5]/64;
      			 break;
	    case 14: vumetros[k]= (valores_frecuencias[5]/64 + valores_frecuencias[6]/64)/2;
      			 break;
		case 15: vumetros[k]= valores_frecuencias[6]/64;
      			 break;
  	  }
	  Dibuja_vumetro(k, vumetros[k]);
  	  delay(2);
  }
  
}


void Dibuja_vumetro(int posicion, int altura) {
    byte h = altura/8;

    switch (h) {
    	case 0: // caso altura <= 7 ej  7/8 = 0
			    lcd.setCursor(posicion, 3);
			    lcd.write(altura);
			    lcd.setCursor(posicion, 2);
			    lcd.write(32);   /
			    lcd.setCursor(posicion, 1);
			    lcd.write(32);
			    lcd.setCursor(posicion, 0);
			    lcd.write(32);   

    	case 1: // caso altura > 7 ej 10/8 = 1
    			lcd.setCursor(posicion, 3);
			    lcd.write(7);  
			    lcd.setCursor(posicion, 2);
			    lcd.write(altura-8);
			    lcd.setCursor(posicion, 1);
			    lcd.write(32);
			    lcd.setCursor(posicion, 0);
			    lcd.write(32);   
			    break;

    	case 2: // caso altura > 14 ej 18/8 = 2
	    	    lcd.setCursor(posicion, 3);
			    lcd.write(7);
			    lcd.setCursor(posicion, 2);
			    lcd.write(7);
			    lcd.setCursor(posicion, 1);
			    lcd.write(altura-8);
			    lcd.setCursor(posicion, 0);
			    lcd.write(32);
			    break;

    	case 3:	// caso para altura > 21 ej: 24/3=3 en enteros
    			lcd.setCursor(posicion, 3);
	    		lcd.write(7);
			    lcd.setCursor(posicion, 2);
			    lcd.write(7);
			    lcd.setCursor(posicion, 1);
			    lcd.write(7);
			    lcd.setCursor(posicion, 0);
			    lcd.write(altura-8);
			    break;
    }
}

La interpolación que hace no me gusta, en los puntos 7 y 8. No se de donde sacó usar random(2).

Gracias surbyte por responder.

He probado tu código y veo que solo las filas 3 y 2 se activan, ademas en la fila 2 salen caracteres raros. No obstante he subido dos pequeños vídeos.

Este es el resultado con tu código;

Test DOS

A todo ello he modificado nuevamente el código sobre el original y creo que el problema esta en la función; void Dibuja_vumetro

Modificando he obtenido esto;

void Dibuja_vumetro(int posicion, int altura)
{
  if (altura>7)
  {
    
    lcd.setCursor(posicion, 3);
    lcd.write(7);
    lcd.setCursor(posicion, 2);
    lcd.write(7);               //altura-8
    lcd.setCursor(posicion, 1);
    lcd.write(7);        //altura-8
    lcd.setCursor(posicion, 0);
    lcd.write(altura-8);
  }
 else
  {
      lcd.setCursor(posicion, 3);
    lcd.write(altura);
    lcd.setCursor(posicion, 2);
    lcd.write(32);        //32
    lcd.setCursor(posicion, 1);
    lcd.write(32);            // altura
    lcd.setCursor(posicion, 0);
    lcd.write(32);   
  }
  }

Test UNO

A todo ello no entiendo como has utilizado el case / break, y si aumento el contraste ligeramente se ve que quiere verse en las demás filas pero hay como un borrado. Bueno seguiré investigando y a ver si lo trabajo mas.

Saludos

P.S. No encuentro los Tags para los vídeos de Youtube.

Es simple lo que debes hacer.
Prueba con altura entre 0 y 8, entre 8 y 16 y asi..
Debe graficar bien, si no lo hace, modifica el código para que lo haga.
Yo modifiqué como para que grafique según el valor de altura porque ese código repetía las gráficas.
No se que valores da el integrado asi que partir de que todo esta bien no es correcto. No digo que funcione mal.
He visto en otras páginas que demoran mas tiempo para leer entre valor y valor.
Tu código tiene delayMicroseconds(5); pero he visto que usan hasta 100 useg.
Deberías consultar la hoja de datos.

La cuestión aquí es que te has hecho un lío con el código inicial. Debes saber como funciona el analizador MSGEQ7.

Primero:
Creo que el problema mayor se encuentra en el circuito, asegúrate que el circuito del msgeq7 que has instalado funcione, lo mejor es que sigas el diagrama de conexionado de la hoja de datos. La mejor guía que puedes seguir es esta:

http://tronixstuff.com/2013/01/31/tutorial-arduino-and-the-msgeq7-spectrum-analyzer/

Debes verificar el funcionamiento de tu circuito mediante el puerto serie, en la guía te muestran como hacerlo, tiene que existir un cierto nivel de ruido base cuando el circuito funciona correctamente, si no consigues esos valores base, el circuito está mal instalado. Me parece que para 5V el ruido base ronda entre 0 y 110 aprox. en cada una de las bandas.

Segundo:
El delayMicroseconds debe estar entre 25 y 35, un numero mayor hace que el barrido de lectura de las 7 bandas del MSGEQ7 sea muy lento, menor a ese valor hace que el barrido sea demasiado rápido. En ambos casos la imagen se distorsiona y no se aprecian las barras del analizador.

Tercero:
Sugiero convertir el código en estructuras separadas simples, cada una con una función específica, así cuando trates de ubicar un fallo, no tendrás que mirar dentro de un mundo de lineas:

Definición de variables globales:

int strobe = 5; 
int res = 6; 

int left[7]; 
int band;

Dentro del setup solo hay que definir esto:

  pinMode(res, OUTPUT); 
  pinMode(strobe, OUTPUT); 
  digitalWrite(res,LOW); 
  digitalWrite(strobe,HIGH);

Función de lectura de las 7 bandas del analizador, se debe usar todo el tiempo para accesar a los datos del analizador

void readMSGEQ7()
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for(band=0; band <7; band++)
 {
  digitalWrite(strobe,LOW); 
  delayMicroseconds(30);  
  left[band] = analogRead(0);  //La señal de audio va a una entrada analógica, en este caso a A0 del 
  digitalWrite(strobe,HIGH); 
 }
}

La función de presentación depende del medio de salida: TFT, leds, matriz, LCD gráfico, LCD texto, etc, y por lo tanto dependerá de la librería que estes usando. La idea es leer el valor de cada banda y convertirlo en una imagen proporcional.

En mi caso uso un TFT de 4.3", con la librería GD2, este es el código:

void barrasVSegmentadasLF(int segmentos, int xi, int yi, int sepY, int sepX, int largoX, int espesor)
{
  GD.Begin(LINES);
  GD.LineWidth(espesor);
  GD.ColorRGB(0xffffff);   //color de los segmentos

    for (int j = 0; j < band; j++) 
      { 
      int dato = map(left[j], 0, 1023, 0, segmentos);
      for (int i = 0; i < dato; i++) 
        { 
         GD.Vertex2ii(xi+(j*largoX+j*sepX), yi - (i*sepY)); // inicio
         GD.Vertex2ii(xi+((j+1)*largoX+j*sepX), yi - (i*sepY)); //  fin   
        }
      }  
}

Al unir todo en la función de lectura del analizador:

void AnalizadorMP()
{
    readMSGEQ7();    
      barrasVSegmentadasLF(14, 75, 185, 10, 20, 30, 35);
}

Video este es el resultado del código anterior

PD: hace mucho tiempo que pasé de los lcd´s de texto, disculpa que no te pueda orientar con esa parte del código

Muchas gracias a los dos por vuestras ideas y análisis.

Pero discrepo un poco...
Veamos.

La guía que me has dado TFTLCDCyg me ha servido al menos en mejorar mi circuito de hardaware del chip MSGEQ7, pues realice (y esta es la tercera vez que lo realizo) el correcto funcionamiento del chip.

En la primera vez el condensador de 100K (100npF) estaba cruzado, concretamente el que va al pin 6 y esto que era nuevo por lo consiguiente el MSGEQ7 murió. Total que realice otro prototipo pero este ultimo con los consejos me dí cuenta en la entrada del pin 5 va un condensador de 10K (10npF) y lo puse de 100K, consiguiente que solo el multiplexador en la salida solo obtenía frecuencia muy altas y solo las tres ultimas barras obtenía actividad y/o movimiento, es lógico al ser un condensador de factor x 10 sobre 10npF no deja pasar las frecuencias bajas, aunque iré en esta tercera fase del hardware de poner un condensador variable entre 4n7 y 22k.

Ayer hice pruebas con el LCD 20x4 y lo deje por aburrimiento ya que como tengo varias pantallas y leyendo el mensaje anterior me dispuse a conectar todo a un LCD gráfico de 128x64 concretamente concretamente esta pantalla... después de analizar un poco funcionó a la perfección.

Y he aquí con ejemplos que estuve estudiando y volviendo a darle vueltas con me aconsejo TFTLCDCyg en el setup tengo esto;

 // Setup del chip MSGEQ7
  pinMode(ANALOG, INPUT);
  pinMode(STROBE, OUTPUT);
  pinMode(RESET, OUTPUT);
  analogReference(DEFAULT);
  digitalWrite(RESET, LOW);
  digitalWrite(STROBE, HIGH);

y luego en el loop esto;

// Resetear el MSGEQ7
    digitalWrite(RESET, HIGH);
    digitalWrite(RESET, LOW);

    for (int i = 0; i < 7; i++) {
      digitalWrite(STROBE, LOW);
      delayMicroseconds(35); // Retardo de lectura
      valorSalida[i] = analogRead(ANALOG);
      digitalWrite(STROBE, HIGH);

si no pongo esto no hay nada en pantalla, pero ni en una ni en esta he incluso que tengo una pantalla con controlador ILI9481 como esta pero con la librería UTFT no funciona porque o bien no se por donde meterle mano o la librería no da mas de sí, sin embargo con la monocromo del LCD 128x64 con U8glib me voy defendiendo.

Por lo tanto este era mi dilema de discrepar sobre solo que hay que definir en el setuo las condiciones del chip MSGEQ7.
No me doy por vencido (eso lo dejo para otros) y se que me va a costar pero pienso solucionar el LCD 20x4. No es por decir lo bonito que se tiene que ver, el problema es que me regalaron 10 este verano y como cabezón que soy al menos dos van a funcionar como vumeter a pantalla completa (o eso creo)...

Por cierto he visto el vídeo TFTLCDCyg y eso da mucha envidia, pero de la sana. :slight_smile:
Saludos y pondré fotos que tengo hoy el móvil sin batería.

El MSGEQ7 puede trabajar de 2.7 a 5.5V, se puede usar también en el Due, sin necesidad de un conversor de voltaje. Así que construí un shield para arduino Due, con cuatro de estos chips, con la idea de obtener un analizador por cada uno de los parlantes de la PC.

El circuito que decidí usar es este:

Usé componentes de montaje superficial, ya que en el shield también van instalados un lector micro SD, un DS3231 y el cabezal del gameduino 2. Además el shield permite usar los pines libres, para posteriores anexiones de sensores de temperatura por ejemplo.

Te hace falta encontrar la forma de convertir el rango 0-1024 de cada banda del msgeq7 en su equivalente en pixeles en el LCD.

Buenas.
El no decidirme en un principio por un LCD gráfico fue por el "pobre" realismo de las 7 barras representadas en el lcd y como vi vídeos del mismo con eso si interpolación que no es real sino ficticio, esta mañana he realizado este experimento.

Con la ayuda de un generador de señales senoidal en la entrada he puesto la gama de frecuencias que da el MSGEQ7 yaunque ya lo sabia me he quedado decepcionado. Por un lado de los 7 cortes de bandas la mas alta corresponde a 16KHetz y esta frecuencia en el planeta los humanos están contados los que oyen estas frecuencias (posiblemente muy pocos y se podrían contar los los dedos de la mano).

Entonces el equalizador no representará y menos un equipo de audio frecuencias tan altas a "ver" esta es mi percepción. He cogido la DataSheet del chip donde se presenta las 7 bandas de frecuencias;

63, 160, 400, 1000, 2500, 6250 y 16000 Hetz

Vale que frecuencias de 14000Hetz queda anterior al pico mas alto del corte de la banda 7 y he pensado que desde 6250 hasta 16000 van cerca de 10000Hetz y precisamente entre 2500 y 6250 que son frecuencias medias hay un gran agujero que no se van a presentar en LCD.

Si se presentan si como dije se interpolan pero no es real y no voy a realizar una castaña de proyecto, sino que o bien se mejora o ... pero me he dado cuenta de una cosa. En el pin 8 llamado CKIN es donde va la red RC para el funcionamiento del reloj.

donde la frecuencia usada por la RC es 160KHetz, y si variando esta frecuencia osea la red RC se obtendría otras frecuencias de muestreo. Por ejemplo las 7 bandas que usa el chip son multiplos de 2,51 es decir si dividimos 16000Hetz entre 2,51 nos da 6250, si dividimos 6250 entre 2,51 nos da 2500 etc... y puestos a pensar estoy pensando en modificar la frecuencia del reloj por ejemplo la mas alta obtener 12000Hetz si la divido entre 2,51 me da; 4780 Hetz y si me fijo obtendría por ejemplo;

16000, 12000, 6250, 4780 ..... y así el corte de frecuencia medias no es tan elevado y en los 12000Htez frecuencias audibles en según que sonidos creo quedaría bien representado, por lo tanto creo que sería poner 2 MSGEQ7 en cascada. De esta forma se obtendrían 14 bandas visuales reales. El problema viene si el MSGEQ7 se puede "hackear" el reloj. Bueno si no se prueba no se sabe y a lo malo si va mal la cosa se podría estropear por lo tanto me voy a arriesgar al invento. Finalmente no se si el condensador se tiene que aumentar o disminuir la resistencia de 200K no hay problema por que usaré una resistencia de 100K en serie con un potenciómetro de 250K y tendré margen entre 100K - 350K.

Este es el ultimo prototipo del MSGEQ7 que he realizado, ahora tocará por cuarta vez modificar.

Estas capturas son con el LCD ST7920 de 128x64 pixels.

Si me funciona con 14 bandas en el ST7920, entonces ya iré directamente a por el LCD 20x4.
Saludos.

Ya tengo el nuevo módulo para realizar pruebas. No obstante ya les informo que realice un pedido de 15 nuevos MSGEQ7 por ebay. por si las moscas rodean y va mal la cosa.
Pero no es pedir por pedir sino por la fe que tengo en este chip.

Estas son las nuevas capturas para configurar los diferentes módulos cada uno con un MSGEQ7 a diferente frecuencia

En el modulo A;

condensador 33pF / 200KOhm

El el modulo B;

condensador xpF / 100K - 300K

En el modulo C;

Por investigar.

Si funciona modulo B se podría hacer 21 bandas. Oooooh!!!
Si como suena 21 bandas, porque 7 x 3 = 21 , pero con matices ya que estudiando los valores del mensaje anterior puedo obtener hasta 5 muestras reales, sino ya lo explicaré. Como dije en el mensaje anterior es lograr si el chip MSGEQ7 se puede modificar, si es así pues ya veremos las sorpresas. Desde la programación del software al LCD de momento ST7920 es donde puedo lograrlo, si no funciona, pues "amen" y a otra cosa.

Creo en teoría tendría que funcionar, si el chip tiene el oscilador monoestable, es decir como en las viejas basculas de los IC de hace tiempo, como tenga corte de frecuencia, no es viable, todo es probar... Os informo si funciona el invento o no.

Por cierto se me escapa una cosa, verán si la red RC del oscilador, realizando una simple regla de tres, es decir,

33=16000 // 33pF = 16000Hertz
100000=16000 // 100K = 16000Hertz

x=12000 // x = capacidad del condensador para 12000Hertz?
y=12000 // y = resistencia para 12000Hertz?

por lo tanto la RC seria proporcional. Pero se por experiencia en Electrónica a veces y mas tratando con circuitos integrados, donde el fabricante no expone o suelen obviar las características totales
y a lo mismo es inversamente proporcional , es cuestión de probar.

Saludos

Buenas madrugadas chavales.

Pues funciona correctamente con dos chip MSGEQ7 a LCD ST7920 representados en este modo.
Ha costado un poco
He desarrollado una formula donde se obtiene los cálculos del condensador + la resistencia es decir RC del reloj del chip. Es muy sencillo.

Os dejo un vídeo donde tengo las 14 bandas, 7 en diferentes formas.

DOBLE MSGEQ7

Ahora ya tengo donde empezar a proyectar con vuestra ayuda el LCD de caracteres 20x4 que estoy perdido...

P.D. Cada MSGEQ7 tiene en este momento tener cada uno dos pines digitales para [reset y strobe] por lo tanto en este ejemplo anterior dual se ha usado 4 pines digitales de Arduino modelo UNO.

Hola a todos, soy nuevo en arduino y quisiera saber si es posible mostrar una gráfica de temperatura vs tiempo en un lcd 128 x 64. Estoy usando la librería U8glib para mostrar los valores tomados por las termocuplas tipo K y me gustaria obtener una gráfica de la misma. Si alguien ah hecho algo similar , podría compartir el codigo???

Matiash, por favor, abre un hilo nuevo con tu consulta.
Saludos!

:grin: