15 septiembre 2015

PinoLed. PINO DE NAVIDAD CON LED. Estudio de multiplexado de leds y sonido con Arduino.

(EN) LedTree. LED CHRISTMAS TREE. Study about sound and leds multiplexing with Arduino.
(FR) ArbreLed. ARBRE DE NOËL AVEC LEDS. Étude de multiplexage de leds et son avec Arduino.
(PT) ÁrvoreLed. ÁRVORE DE NATAL COM LEDS. Estudo de multiplexagem de led e som com Arduino.
------------------------------------------------------------------------------------------------------------------------------------ 


PARA REPASAR E INFORMARSE: Para este montaje usaré un Arduino Uno. Hay un montón de información en la web. Aquí un enlace a su página oficial. 

Básicamente se trata de manejar leds, así que es interesante tener claro como se polariza un led. En este blog ya se ha tratado el tema.

Mi idea ha sido con transistores como conmutadores. Así que es interesante tener una idea simple de como funcionan en corte y en saturación. Hay mucha información en la web. Aquí hay un ejemplo que me ha gustado. Más concretamente uso un array de transistores, el integrado ULN2003.



PLANTEAMIENTO INICIAL  Y MOTIVACIÓN DEL PROYECTO.

Con la proximidad de la navidad, allá por noviembre del 2014, comentamos  entre amiguetes makers, el montar un árbol de navidad con arduino. En principio, la idea de montar unos leds sobre una plaquita pcb en forma de pino, y encender y apagar, me pareció algo demasiado sencillo. Pero al poco tiempo caí en la idea de algo interesante:
Arduino tiene un número relativamente limitado de entradas y salidas (yo tengo un Arduino Uno; 14 digitales y 6 analógicas). Estas no pueden soportar más de 40mA cada una, y mejor no pasar de 20mA. Y en total no más de 300mA, todas juntas. Pensemos, intentando no pasar de 150 o 200mA, por si acaso.
Así que, imposible usar directamente más de 20 leds, y esta cantidad, con mucho cuidado.
¿Cómo hacer, entonces, para manejar más? Pues montarlos en una matriz, y no encenderlos todos al mismo tiempo. Una matriz que habrá que controlar continuamente filas y columnas y que si además sincronizamos con una musiquilla se convierte (para mi nivel al menos) en un ejercicio interesante de sincronismo y programación.
Además el propósito va a ser diseñar y montar yo el circuito. Activar filas y columnas parece una cosa factible con transistores...



MATRIZ. FILAS Y COLUMNAS.

En una red o matriz de leds podemos conectar una serie de filas a unas salidas del arduino, y una serie de columnas a otras. Si ponemos a nivel alto determinada salida alimentaremos positivamente toda una linea de leds (en nuestro dibujito las filas). De esos leds se encederán los que tengan su cátodo también a negativo o nivel bajo (en nuestro caso, la columna apropiada). Solo debemos cuidarnos de no activar más de una linea de leds al mismo tiempo para que no interfieran unas lineas con otras.

leds matrix
Graficamente se entiende mejor la activación o no de los leds en una matriz

En nuestro ejemplo (con lógica positiva), si activáramos a nivel alto dos filas, el activar una columna a nivel bajo encendería los dos leds de las diferentes filas. El truco es activar solo una fila, y las columnas apropiadas un instante y luego hacer lo mismo con otra fila. Todo lo suficientemente rápido como para que nuestro ojo no se de cuenta.



LIMITACIÓN DE LA CORRIENTE. Y USO DE TRANSISTORES.

Cada led debería tener una resistencia que limitase su corriente para que no se queme.
Y para no consumir demasiada corriente de las salidas de nuestro arduino, la primera idea es usar transistores que aislen las salidas del arduino respecto de la intensidad que consuman nuestros leds.
Así mi primera idea ha sido polarizar un par de transistores, que según estén sus bases, a nivel alto conducirán, o a nivel bajo estarán en corte.

Switch on led with transistors
El transistor en corte nos aisla de masa y conecta con tensión a través de la resistencia. En saturacíón conduce y nos conecta directamene a masa.



Una vez, así presentado el esquema,  es fácil caer en la cuenta de que podemos sacar la resistencia inferior y dejar el transistor conectado a colector abierto. Sólo nos interesa que el cátodo del diodo se conecte a masa o no.
Y de esta forma, la única resistencia que queda será la que nos limita la corriente por el diodo, de forma elemental.

Two transistors for a led
Cuando el led conduce e ilumina, el transistor superior "aisla" la masa, y el inferior la "une" por lo que el cirucuito se convierte en un sencillo "resistencia en serie con led".




EL INTEGRADO ULN2003A PARA NUESTRO MONTAJE.

 El integrado ULN2003A es un conjunto de resistencias, transistores y diodos. Se compone de siete circuitos iguales que en las hojas de características suelen venir representados como una puerta lógica NOT. Es básicamente un adaptador de potencia. Por la entrada nosotros introducimos una señal lógica TTL. Unas resistencias polarizan y atacan la base de un transistor tipo darlington (dos conectados para aumentar potencia) y esto nos da una salida negada (a masa si la entrada está a nivel alto, a colector de los transistores si la entrada es a nivel bajo)por la que puede pasar mucha más intensidad que por nuestros pines del arduino. Para simplificar y pensar electrónicamente tenemos nuestro transistor básico (pudiéndonos despreocupar de las adaptaciones de la señal ttl de nuestro arduino): un 0 o nivel bajo de nuestro arduino, nos pone a "nuestro" transistor en corte (o abierto colector-emisor) y por tanto aislado de masa; un 1 o nivel alto provocará a "nuestro" transistor a saturación (o cerrado colector-emisor) y por tanto conectado a masa.
También existen unos diodos, con un contacto en común, que no usaremos aquí, pensados para poner con selenoides, para cortocircuitar los transitorios de desconexión de las bobinas, generalmente de relés. Aquí no hay de eso, así que no los usamos.


PRUEBAS Y DISEÑO. 

Pues con estas ideas hacemos unas pruebas, para ver que nuestras ideas eléctricas funcionan. Y corregir errores y decisiones iniciales como la patilla común de los leds RGB, valores de las resistencias, etc.


LLevando a la práctica la teoría de nuestro PinoLed.


Y todas las conclusiones se han conviertido en el siguiente esquema definitivo

LedTree Diagram
Aquí está como ha quedado el esquema definitivo de mi PinoLed.

VALOR DE LAS RESISTENCIAS.

La corriente que circulará por la carga más importante (leds) la "recojo" por Vin y no por 5V por dos razones: para liberar de trabajo al regulador de tensión; y pensando en poder conectar con baterías diferentes y hacer que los leds alumbren más o menos.
Pensando, además, que hay leds de diferentes colores y tipos (finalmente he optado también por jugar con un par de leds RGB), y que éstos tienen diferentes umbrales de tensión a partir de los cuales conducen, la elección del valor de la resistencia limitadora de corriente ha sido un poco a prueba y error.
Originalmente, en el prototipo sobre protoboard he empezado con resistencias de 1K. Pensaba en una de las opciones menos favorables: 20v de entrada (Vin) y led rojo (tensión umbral aproximada 1,8v según pruebas propias) y curándome un poco en salud con la corriente (I diodo máx.<20ma aria-haspopup="true" class="goog-spellcheck-word" data-blogger-="" id=":1b.167" role="menuitem" span="" style="background: yellow;" tabindex="-1">escaped
-br="">
R=(Vin-Vd)/Idmax=(20-1,8)/0,020=910 ohmios.
Una vez, en fase de programación del Arduino, al multiplexar, el brillo de los leds baja notablemente porque la tensión sólo se aplica a cada linea 1/6 parte del tiempo. Por lógica he bajado el valor de las resistencias 1/6 parte (1000/6=166,66). Por seguridad mejor 180 que 150 ohmios.


DETALLES Y RESULTADOS DE LA CONSTRUCCIÓN.
Con la construcción no quería gastar demasiado dinero. Se trataba de un ejercicio. Así que he optado por cartulina y leds pequeños de 3mm. La circuitería está montada sobre un escudo casero del que ya he hablado en otra entrada. Hubiera sido más vistoso y luminoso usar leds grandes. Seguro que hay ideas mucho más trabajadas, pero esta es la mía...
En mi montaje, en el lugar del potenciometro para el volumen he puesto un puente, optando así por la potencia máxima, pero esto puede ser molesto para algunas personas así que indico la posibilidad de regular el volumen. Como altavoz uso un buzzer pasivo.
En la foto se puede ver, todavía sin acabar, mi idea original, con una pila de 9v. Pero, aunque válida, no ha resultado ser una opción demasiado buena. Esto requiere una interesante explicación que comentaré en los siguientes párrafos. De momento unas fotos para hacerse una idea:
 
LedTree assembly
Idea del proceso de montaje y detalles del PinoLed



PinoLed Photo
Una foto del PinoLed durante las pruebas




Y el video, un poco cutre (también en YouTube), da una pequeña muestra del resultado final de mi ejercicio, bautizado como PinoLed.



APUNTES SOBRE LA PROGRAMACIÓN.

También dejo por aquí a la vista mi programa del arduino. Probablemente muy simple y poco elegante para los muy iniciados. Pero espero que útil para aprender a los que, como yo, no lo son tanto.  Fue desarrollado y probado con un Arduino Uno R3 y con el IDE de programación 1.6.1.
Básicamente se trata de la función "Visualizar()" que está constantemente mostrando el brillo de cada led que la matriz "diodoFilCol[7][7]" guarda en sus índices (0 apagado, 255 brillo máximo).
Estos valores del brillo de cada led se van modificando según una "secuencia()" temporal para que coincida con la música también definida en esta función.
Para que no sea demasiado repetitivo, de forma medio chapucera (en honor al nombre del blog), he creado un par de posibles estados en donde, sin música, las luces hacen un par de efectos aleatorios: uno jugando con encender y apagar leds al azar; otro jugando con subir y bajar el brillo de diferentes colores. De manera más o menos accidental puede volverse al estado inicial de secuencia leds-música, y si no, al cabo de un tiempo mínimo,  de manera forzada (establecido ahora para las pruebas en 60 segundos) .
Otras funciones organizan de forma predefinida efectos simples de luces para simplificar la repetición en la programación.

Por si alguien se anima a probar, dejo aquí una copia del archivo .ino definitivo comprimido en zip.

Y para quien solo quiera curiosear y echar un vistazo rápido, aquí está el código.




////////////////////////////////////////////////
// Para hacer funcionar PinoLed               //
// Matriz de 36 leds y un buzzer              //
// http//:electronicaychapuzas.blogspot.com.es//
// by Sancos v1.1                             //
////////////////////////////////////////////////

byte diodoFilCol[7][7];   //definira estado diodos:0 apagado 255 encendido
// fila y columna define que pines uso.No usamos fila0 ni columna0
byte fila[7]={255,15,14,2,4,7,8};     //No usare fila0. 14=A0, 15=A1
byte columna[7]={255,3,5,6,9,10,11};  //No usare columna0
//Podría usar pwm por comodidad. Por eso utilizo estas salidas.
//Pero para poder usar Tone() sin problemas no usaré PWM
//Ademas, después de montado el circuito, he caido en que hubiera
//sido mas interesante el PWM en las filas.
int v=2; //Velocidad tempo
int i,c,n,f,luz;   //Contadores uso general
int estado; //Que estamos haciendo? 0-inicio; 1-secuencia;
unsigned long tiempo0,tiempo;   //Contadores tiempo
short Do2,Si2,Do3,Re3,Mi3,Fa3,Sol3,La3,Si3,Do4;  //Notas que vamos a usar
void setup()
{
  // Filas. Activas a nivel bajo. Reposo a nivel alto.
  for (f=1; f<7; f=f+1)
  {
    pinMode(fila[f],OUTPUT);
    digitalWrite(fila[f],HIGH);
  }
  
  // Audio implementado por pin 12.
  //señal de audio. Reposo a nivel bajo
  pinMode(12,OUTPUT);
  digitalWrite(12,LOW);
  
  // Notas
    Do2=130.813;
    Si2=246.942;
    Do3=261.626;
    Re3=293.665;
    Mi3=329.628;
    Fa3=349.228;
    Sol3=391.995;
    La3=440;
    Si3=493.883;
    Do4=523.251;
  
  //Columnas. Activas a nivel alto. Reposo a nivel bajo.
  for (c=1; c<7; c=c+1)
  {
    pinMode(columna[c],OUTPUT);
    digitalWrite(columna[c],LOW);
  }
  
  //Inicializamos el estado de cada led a apagado.
  //La matriz diodoFilCol define cada diodo
  // desde 0 (apagado) a 255 (brillo maximo)
  for (f=1; f<7; f=f+1)
  {
    for (c=0; c<7; c=c+1)
    {
      diodoFilCol[f][c]=0;
    }
    
 }
 
  tone(12,440,1000);   //Test al inicio
  delay(5000);  //Esperamos unos segundos antes de arrancar
  tiempo0=millis();   //Tomamos tiempo inicial para temporizaciones
  estado=1;
  
}



void loop()
{
  if (estado==0) Test();  //Test al inicio
  if (estado==1) Secuencia();  //Secuencia programada con musica
  if (estado==2) Luces();  //Luces al azar y silencio
  if (estado==3) Rgb();
  Visualizar();
}

// Visualizar la matriz diodoFilCol.
void Visualizar()
{
  for (c=1; c<7; c=c+1)  //Repetir con las seis columnas
  {
  digitalWrite(columna[c],HIGH);  //Activar columna
    for (n=1; n<255; n=n+4)   //Pasos lo mas cortos posible sin que parpadeen los leds
    {
      for (f=1; f<7; f=f+1)  //Activar  las filas según brillo en matriz
      {
        //Activamos o no más veces según numero en matriz mas alto
        if ((255-n)<(diodoFilCol[f][c])) digitalWrite(fila[f],LOW);   
        else digitalWrite(fila[f],HIGH);     
      }
    }
    digitalWrite(columna[c],LOW);  //Desactivar columna
    
    for (f=1; f<7; f=f+1)    //Desactivar filas
    {
      digitalWrite(fila[f],HIGH);
    } 
  }
}




/********************/
/* Efectos de luces */
/********************/


// Apagar todos los leds (0), o encender(255)
void Todos(int brillo)
{
  
   for (f=0; f<7; f=f+1)
  {
    for (c=0; c<7; c=c+1)
    {
      diodoFilCol[f][c]=brillo;
    }
    
  }
}


// Iluminar un led en concreto.
void Led(int fil,int col,int brillo)
{
  diodoFilCol[fil][col]=brillo;
  
}


// Iluminar una columna en concreto.
void Columna(int col, int brillo)
{
  for (c=0;c<7;c=c+1)
  {
    diodoFilCol[c][col]=brillo;
  }
}


//Iluminar una fila en concreto.
void Fila(int fil, int brillo)
{
  for (c=0;c<7;c=c+1)
  {
    diodoFilCol[fil][c]=brillo;
  }
}



//Iluminar todos rojos
void Rojos(int brillo)
{
  Led(1,1,brillo);
  Led(1,4,brillo);
  Led(2,3,brillo);
  Led(2,6,brillo);
  Led(3,2,brillo);
  Led(3,5,brillo);
  Led(4,2,brillo);
  Led(4,5,brillo);
  Led(5,2,brillo);
  Led(5,5,brillo);
  Led(6,2,brillo);
  Led(6,5,brillo);
}

//Iluminar todos verdes
void Verdes(int brillo)
{
  Led(1,2,brillo);
  Led(1,5,brillo);
  Led(2,2,brillo);
  Led(2,5,brillo);
  Led(3,3,brillo);
  Led(3,6,brillo);
  Led(4,3,brillo);
  Led(4,6,brillo);
  Led(5,3,brillo);
  Led(5,6,brillo);
  Led(6,3,brillo);
  Led(6,6,brillo);
}

//Iluminar todos amarillos
void Amarillos(int brillo)
{
  //Para amarillo 180 de rojo y 255 de verde
  //porque el led rojo alumbra más con menos tension
  int correccionbrillo;
  correccionbrillo=((brillo*180)/255);
  
  Led(1,1,correccionbrillo); Led(1,2,brillo); Led(1,3,0);
  Led(1,4,correccionbrillo); Led(1,5,brillo); Led(1,6,0);
  Led(2,1,brillo);
  Led(2,4,brillo);
  Led(3,1,brillo);
  Led(3,4,brillo);
  Led(4,1,brillo);
  Led(4,4,brillo);
  Led(5,1,brillo);
  Led(5,4,brillo);
  Led(6,1,brillo);
  Led(6,4,brillo);
}


void AzarLed(int cuantas, int pausa)  //Cuantas luces encendemos; cada una  pausa ms
{                                  // tiempo aprox. funcion = cuantas * pausa
  long int filaazar, columnaazar;
  Todos(0);
  randomSeed(analogRead(3)); //El pin A3 está al aire
  for (i=0; i<cuantas; i=i+1);
  {
    filaazar=random(1,7);
    columnaazar=random(1,7);
    Led(filaazar,columnaazar,255);
    delay(pausa);
  }
}

void AzarFila(int cuantas, int pausa) //Cuantas filas encendemos cada pausa ms
{                                     //tiempo aprox.funcion=cuantas*pausa
  long int filaazar;
  Todos(0);
  randomSeed(analogRead(3));  //A3 al aire
  for (i=0; i<cuantas; i=i+1);
  {
    filaazar=random(1,7);
    Fila(filaazar,255);
    delay(pausa);
  }
}

void AzarColumna(int cuantas, int pausa) //Cuantas columnas encendemos cada pausa ms
{                                     //tiempo aprox.funcion=cuantas*pausa
  long int columnaazar;
  Todos(0);
  randomSeed(analogRead(3));  //A3 al aire
  for (i=0; i<cuantas; i=i+1);
  {
    columnaazar=random(1,7);
    Columna(columnaazar,255);
    delay(pausa);
  }
}


/***********************/
/*     Secuencias      */
/***********************/

void Test()
{
  tiempo=(millis()-tiempo0);
  
    if (tiempo<1000)
      {
      Todos(255);
      }
    if ((tiempo>=1000)&&(tiempo<2000))
      {
      Todos(0);  
      Led(1,1,255); Led(1,4,255); //Rojo
      }
    if ((tiempo>=2000)&&(tiempo<3000))
      {
      Todos(0);
      Led(1,1,0); Led(1,4,0);  
      Led(1,2,255); Led(1,5,255);  //Verde
      }
    if ((tiempo>=3000)&&(tiempo<4000))
      {
      Todos(0);  
      Led(1,2,0); Led(1,5,0);  
      Led(1,3,255); Led(1,6,255);  //Azul
      }
    if ((tiempo>=4000)&&(tiempo<4500))
      {
      Todos(0);  
      Led(1,3,200); Led(1,6,200); //Apagando azul
      Led(1,5,5); //Encendiendo verde
      }
    if ((tiempo>=4500)&&(tiempo<5000))
      {
      Todos(0);  
      Led(1,3,100); Led(1,6,100); //Apagando azul
      Led(1,15,5); //Encendiendo verde
      }
    if ((tiempo>=5000)&&(tiempo<5500))
      {
      Todos(0);  
      Led(1,3,50); Led(1,6,50); //Apagando azul
      Led(1,5,50); //Encendiendo verde
      }
    if ((tiempo>=5500)&&(tiempo<6000))
      {
      Todos(0);  
      Led(1,3,25); Led(1,6,25); //Apagando azul
      Led(1,5,100); //Encendiendo verde
      }  
    if ((tiempo>=6000)&&(tiempo<6500))
      {
      Todos(0);  
      Led(1,3,15); Led(1,6,15); //Apagando azul
      Led(1,5,200); //Encendiendo verde
      }
    if ((tiempo>=6500)&&(tiempo<7000))
      {
      Todos(0);  
      Led(1,3,0); Led(1,6,0); //Apagando azul
      Led(1,5,255); //Encendiendo verde
      }
      
    if ((tiempo>=7000))
      {
      estado=1;
      tiempo0=millis();
      }
}


//Luces al azar para reposo
void Luces()
{
  long int quehacer,fil,col;
  randomSeed(analogRead(3));  //A3 al aire
  quehacer=random(1,100);
  fil=random(1,7);
  col=random(1,7);
  if (quehacer<3) Todos(0);
  if ((quehacer>=5)&&(quehacer<45)) Led(fil,col,255); 
  if ((quehacer>=45)&&(quehacer<85)) Led(fil,col,0);
  if (quehacer==85) estado=3; //ejecuta Rgb()
  if ((quehacer>85)&&(estado<89)) Fila(fil,255);
  if ((quehacer>89)&&(estado<94)) Columna(col,255);
  if ((quehacer>99)) { estado=1; tiempo0=millis(); }
  if ((millis()-tiempo0)>60000){ estado=1; tiempo0=millis(); } //aqui aseguro musica cada 60 segundos
}

//Led de colores
void Rgb()
{
  long int quehacer; //luz interesa global
  randomSeed(analogRead(3));  //A3 al aire
  quehacer=random(1,100);
  if (quehacer>60) luz=luz+1;
  if (luz>250) luz=luz-1;
  if ((luz>200)&&(quehacer>95)) luz=0;
  if (quehacer>98) {luz=0; estado=2;} //volver a luces()
  if (quehacer<33) Rojos(luz);
  if ((quehacer>33)&&(quehacer<66)) Verdes(luz);
  if ((quehacer>66)&&(quehacer<98)) Amarillos(luz);
  if ((quehacer>99)&&(luz>200)) { estado=1; tiempo0=millis(); }
}

//Programar secuencia a repetir

void Secuencia()

{
  tiempo=(millis()-tiempo0);
  
  /***************    MUSICA     ******************/
  //Compas1
    if (tiempo<(500/v))
      {
      if (tiempo<(400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(500/v))&&(tiempo<(1000/v)))
      {
      if (tiempo<(900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(1000/v))&&(tiempo<(2000/v)))
      {
      if (tiempo<(1750/v)) tone(12,Mi3,(100/v));
      }
      
      
    if ((tiempo>=(2000/v))&&(tiempo<(2500/v)))
      {
      if (tiempo<(2400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(2500/v))&&(tiempo<(3000/v)))
      {
      if (tiempo<(2900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(3000/v))&&(tiempo<(4000/v)))
      {
      if (tiempo<(3750/v)) tone(12,Mi3,(100/v));
      }
      
      
    //Compas2   
    if ((tiempo>=(4000/v))&&(tiempo<(4500/v)))
      {
      if (tiempo<(4400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(4500/v))&&(tiempo<(5000/v)))
      {
      if (tiempo<(4900/v)) tone(12,Sol3,(100/v));
      }
    if ((tiempo>=(5000/v))&&(tiempo<(5750/v)))
      {
      if (tiempo<(5600/v)) tone(12,Do3,(100/v));
      }
    if ((tiempo>=(5750/v))&&(tiempo<(6000/v)))
      {
      if (tiempo<(5900/v)) tone(12,Re3,(100/v));
      }
    if ((tiempo>=(6000/v))&&(tiempo<(8000/v)))
      {
      if (tiempo<(6500/v)) tone(12,Mi3,(100/v));
      }  
      
      
    //Compas3
    if ((tiempo>=(8000/v))&&(tiempo<(8500/v)))
      {
      if (tiempo<(8400/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(8500/v))&&(tiempo<(9000/v)))
      {
      if (tiempo<(8900/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(9000/v))&&(tiempo<(9750/v)))
      {
      if (tiempo<(9700/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(9750/v))&&(tiempo<(10000/v)))
      {
      if (tiempo<(9900/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(10000/v))&&(tiempo<(10500/v)))
      {
      if (tiempo<(10400/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(10500/v))&&(tiempo<(11000/v)))
      {
      if (tiempo<(10900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(11000/v))&&(tiempo<(11500/v)))
      {
      if (tiempo<(11400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(11500/v))&&(tiempo<(11750/v)))
      {
      if (tiempo<(11700/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(11750/v))&&(tiempo<(12000/v)))
      {
      if (tiempo<(11900/v)) tone(12,Mi3,(100/v));
      } 
     
     
   //Compas4
    if ((tiempo>=(12000/v))&&(tiempo<(12500/v)))
      {
      if (tiempo<(12400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(12500/v))&&(tiempo<(13000/v)))
      {
      if (tiempo<(12900/v)) tone(12,Re3,(100/v));
      }
    if ((tiempo>=(13000/v))&&(tiempo<(13500/v)))
      {
      if (tiempo<(13400/v)) tone(12,Re3,(100/v));
      }
    if ((tiempo>=(13500/v))&&(tiempo<(14000/v)))
      {
      if (tiempo<(13900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(14000/v))&&(tiempo<(15000/v)))
      {
      if (tiempo<(14900/v)) tone(12,Re3,(100/v));
      }
    if ((tiempo>=(15000/v))&&(tiempo<(15750/v)))
      {
      if (tiempo<(15700/v)) tone(12,Sol3,(100/v));
      }
    if ((tiempo>=(15750/v))&&(tiempo<(16000/v)))
      {
      if (tiempo<(15700/v)) tone(12,Do2,(100/v));
      }
     
     
    //Compas5
    if ((tiempo>=(16000/v))&&(tiempo<(16500/v)))
      {
      if (tiempo<(16400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(16500/v))&&(tiempo<(17000/v)))
      {
      if (tiempo<(16900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(17000/v))&&(tiempo<(18000/v)))
      {
      if (tiempo<(17750/v)) tone(12,Mi3,(100/v));
      }
      
      
    if ((tiempo>=(18000/v))&&(tiempo<(18500/v)))
      {
      if (tiempo<(18400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(18500/v))&&(tiempo<(19000/v)))
      {
      if (tiempo<(18900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(19000/v))&&(tiempo<(20000/v)))
      {
      if (tiempo<(19750/v)) tone(12,Mi3,(100/v));
      }
      
     
    
    //Compas6
     if ((tiempo>=(20000/v))&&(tiempo<(20500/v)))
      {
      if (tiempo<(20400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(20500/v))&&(tiempo<(21000/v)))
      {
      if (tiempo<(20900/v)) tone(12,Sol3,(100/v));
      }
    if ((tiempo>=(21000/v))&&(tiempo<(21750/v)))
      {
      if (tiempo<(21700/v)) tone(12,Do3,(100/v));
      }
    if ((tiempo>=(21750/v))&&(tiempo<(22000/v)))
      {
      if (tiempo<(21900/v)) tone(12,Re3,(100/v));
      }
    if ((tiempo>=(22000/v))&&(tiempo<(24000/v)))
      {
      if (tiempo<(22500/v)) tone(12,Mi3,(100/v));
      }  
     
      
    //Compas7
    if ((tiempo>=(24000/v))&&(tiempo<(24500/v)))
      {
      if (tiempo<(24400/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(24500/v))&&(tiempo<(25000/v)))
      {
      if (tiempo<(24900/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(25000/v))&&(tiempo<(25750/v)))
      {
      if (tiempo<(25700/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(25750/v))&&(tiempo<(26000/v)))
      {
      if (tiempo<(25900/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(26000/v))&&(tiempo<(26500/v)))
      {
      if (tiempo<(26400/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(26500/v))&&(tiempo<(27000/v)))
      {
      if (tiempo<(26900/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(27000/v))&&(tiempo<(27500/v)))
      {
      if (tiempo<(27400/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(27500/v))&&(tiempo<(27750/v)))
      {
      if (tiempo<(27700/v)) tone(12,Mi3,(100/v));
      }
    if ((tiempo>=(27750/v))&&(tiempo<(28000/v)))
      {
      if (tiempo<(27900/v)) tone(12,Mi3,(100/v));
      } 
      
      
    //Compas8
    if ((tiempo>=(28000/v))&&(tiempo<(28500/v)))
      {
      if (tiempo<(28400/v)) tone(12,La3,(100/v));
      } 
    if ((tiempo>=(28500/v))&&(tiempo<(29000/v)))
      {
      if (tiempo<(28900/v)) tone(12,Sol3,(100/v));
      }
    if ((tiempo>=(29000/v))&&(tiempo<(29500/v)))
      {
      if (tiempo<(29400/v)) tone(12,Fa3,(100/v));
      }
    if ((tiempo>=(29500/v))&&(tiempo<(30000/v)))
      {
      if (tiempo<(29900/v)) tone(12,Re3,(100/v));
      } 
    if ((tiempo>=(30000/v))&&(tiempo<(30500/v)))
      {
      if (tiempo<(30400/v)) tone(12,Do3,(100/v));
      }  
    if ((tiempo>=(30500/v))&&(tiempo<(32000/v)))
      {
      if (tiempo<(31900/v)) noTone(12);
      }
    
    
    
  /*****************   LUCES    *******************/
  //Compas1
    if (tiempo<(500/v))
      {
        //Mi3
        Todos(0);
        Rojos(255);
      }
    if ((tiempo>=(500/v))&&(tiempo<(1000/v)))
      {
        //Mi3
        Todos(0);
        Amarillos(255);
      }
    if ((tiempo>=(1000/v))&&(tiempo<(2000/v)))
      {
        //Mi3
        Todos(0);
        Verdes(255);
      }
      
      
    if ((tiempo>=(2000/v))&&(tiempo<(2500/v)))
      {
        //Mi3
        Todos(0);
        Rojos(255);
      }
    if ((tiempo>=(2500/v))&&(tiempo<(3000/v)))
      {
        //Mi3
        Amarillos(255);
      }
    if ((tiempo>=(3000/v))&&(tiempo<(4000/v)))
      {
        //Mi3
        Verdes(255);
      }
      
      
  //Compas2   
    if ((tiempo>=(4000/v))&&(tiempo<(4500/v)))
      {
        //Mi3
        Fila(1,0);
        Fila(2,0);
      }
    if ((tiempo>=(4500/v))&&(tiempo<(5000/v)))
      {
        //Sol3
        Fila(3,0);
      }
    if ((tiempo>=(5000/v))&&(tiempo<(5750/v)))
      {
        //Do3
        Fila(4,0);
      }
    if ((tiempo>=(5750/v))&&(tiempo<(6000/v)))
      {
        //Re3
        Fila(5,0);
      }
    if ((tiempo>=(6000/v))&&(tiempo<(6500/v)))
      {
        //Mi3
        Fila(6,0);
      }  
    if ((tiempo>=(6500/v))&&(tiempo<(7000/v)))
      {
        //Silencio
        Led(1,6,255);
      }
    if ((tiempo>=(7000/v))&&(tiempo<(7500/v)))
      {
        //Silencio  
      } 
    if ((tiempo>=(7500/v))&&(tiempo<(8000/v)))
      {
        //Silencio
        Led(1,6,0);
        Led(1,4,180); Led(1,5,255);
      }    
  
      
      
  //Compas3
    if ((tiempo>=(8000/v))&&(tiempo<(8500/v)))
      {
        //Fa3
        Todos(0);
        Columna(1,255); Columna(2,30);Columna(3,0);Columna(4,125);Columna(5,0);Columna(6,30);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(8500/v))&&(tiempo<(9000/v)))
      {
        //Fa3
        Columna(1,30); Columna(2,255);Columna(3,30);Columna(4,0);Columna(5,125);Columna(6,0);
        Fila(1,0);Fila(2,0); 
      }
    if ((tiempo>=(9000/v))&&(tiempo<(9500/v)))  //Varia de nota
      {
        //Fa3
        Columna(1,0); Columna(2,30);Columna(3,255);Columna(4,30);Columna(5,0);Columna(6,125);
        Fila(1,0);Fila(2,0); 
      }
    if ((tiempo>=(9500/v))&&(tiempo<(10000/v)))  //Varia de nota
      {
        //Fa3
        Columna(1,125); Columna(2,0);Columna(3,30);Columna(4,255);Columna(5,30);Columna(6,0);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(10000/v))&&(tiempo<(10500/v)))
      {
        //Fa3
        Columna(1,0); Columna(2,125);Columna(3,0);Columna(4,30);Columna(5,255);Columna(6,30);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(10500/v))&&(tiempo<(11000/v)))
      {
        //Mi3
        Columna(1,30); Columna(2,0);Columna(3,125);Columna(4,0);Columna(5,30);Columna(6,255);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(11000/v))&&(tiempo<(11500/v)))
      {
        //Mi3
        Columna(1,255); Columna(2,30);Columna(3,0);Columna(4,125);Columna(5,0);Columna(6,30);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(11500/v))&&(tiempo<(11750/v)))
      {
        //Mi3
        Columna(1,30); Columna(2,255);Columna(3,30);Columna(4,0);Columna(5,125);Columna(6,0);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(11750/v))&&(tiempo<(12000/v)))
      {
        //Mi3
      
      } 
     
     
 //Compas4
    if ((tiempo>=(12000/v))&&(tiempo<(12500/v)))
      {
        //Mi3
        Columna(1,0); Columna(2,30);Columna(3,255);Columna(4,30);Columna(5,0);Columna(6,125);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(12500/v))&&(tiempo<(13000/v)))
      {
        //Re3
        Columna(1,125); Columna(2,0);Columna(3,30);Columna(4,255);Columna(5,30);Columna(6,0);
        Fila(1,0);Fila(2,0);  
      }
    if ((tiempo>=(13000/v))&&(tiempo<(13500/v)))
      {
        //Re3
        Columna(1,0); Columna(2,125);Columna(3,0);Columna(4,30);Columna(5,255);Columna(6,30);
        Fila(1,0);Fila(2,0); 
      }
    if ((tiempo>=(13500/v))&&(tiempo<(14000/v)))
      {
        //Mi3
        Columna(1,30); Columna(2,0);Columna(3,125);Columna(4,0);Columna(5,30);Columna(6,255);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(14000/v))&&(tiempo<(15000/v)))
      {
        //Re3
        Columna(1,255); Columna(2,30);Columna(3,0);Columna(4,125);Columna(5,0);Columna(6,30);
        Fila(1,0);Fila(2,0);
        
        
      }
    if ((tiempo>=(15000/v))&&(tiempo<(15750/v)))
      {
        //Sol3
        Columna(1,30); Columna(2,255);Columna(3,30);Columna(4,0);Columna(5,125);Columna(6,0);
        Fila(1,0);Fila(2,0);
        Led(1,1,255);
      }
    if ((tiempo>=(15750/v))&&(tiempo<(16000/v)))
      {
        //Do2
        Todos(0);
        Led(1,1,255);
      }
     
     
  //Compas5
    if ((tiempo>=(16000/v))&&(tiempo<(16500/v)))
      {
        //Mi3
        Todos(0);
        Rojos(255);
      }
    if ((tiempo>=(16500/v))&&(tiempo<(17000/v)))
      {
        //Mi3
         Todos(0);
        Amarillos(255);
      }
    if ((tiempo>=(17000/v))&&(tiempo<(18000/v)))
      {
        //Mi3
        Todos(0);
        Verdes(255);
      }
      
      
    if ((tiempo>=(18000/v))&&(tiempo<(18500/v)))
      {
        //Mi3
        Todos(0);
        Rojos(255);
      }
    if ((tiempo>=(18500/v))&&(tiempo<(19000/v)))
      {
        //Mi3
         Amarillos(255);
      }
    if ((tiempo>=(19000/v))&&(tiempo<(20000/v)))
      {
        //Mi3
        Verdes(255);
      }
      
     
    
    //Compas6
     if ((tiempo>=(20000/v))&&(tiempo<(20500/v)))
      {
        //Mi3
        Fila(6,0);
      }
    if ((tiempo>=(20500/v))&&(tiempo<(21000/v)))
      {
        //Sol3
        Fila(5,0);
      }
    if ((tiempo>=(21000/v))&&(tiempo<(21750/v)))
      {
        //Do3
        Fila(4,0);
      }
    if ((tiempo>=(21750/v))&&(tiempo<(22000/v)))
      {
        //Re3
        Fila(3,0);
      }
    if ((tiempo>=(22000/v))&&(tiempo<(24000/v)))
      {
        //Mi3
        Fila(2,0);
        Fila(1,0);
      }  
     
      
    //Compas7
    if ((tiempo>=(24000/v))&&(tiempo<(24500/v)))
      {
        //Fa3
        Todos(0);
        Columna(1,255); Columna(2,30);Columna(3,0);Columna(4,125);Columna(5,0);Columna(6,30);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(24500/v))&&(tiempo<(25000/v)))
      {
        //Fa3
        Columna(1,30); Columna(2,0);Columna(3,125);Columna(4,0);Columna(5,30);Columna(6,255);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(25000/v))&&(tiempo<(25500/v)))  //No coincide con nota
      {
        //Fa3
        Columna(1,0); Columna(2,125);Columna(3,0);Columna(4,30);Columna(5,255);Columna(6,30);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(25500/v))&&(tiempo<(26000/v)))  //No coincide con nota
      {
        //Fa3
        Columna(1,125); Columna(2,0);Columna(3,30);Columna(4,255);Columna(5,30);Columna(6,0);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(26000/v))&&(tiempo<(26500/v)))
      {
        //Fa3
        Columna(1,0); Columna(2,30);Columna(3,255);Columna(4,30);Columna(5,0);Columna(6,125);
        Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(26500/v))&&(tiempo<(27000/v)))
      {
         //Mi3
         Columna(1,30); Columna(2,255);Columna(3,30);Columna(4,0);Columna(5,125);Columna(6,0);
         Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(27000/v))&&(tiempo<(27500/v)))
      {
        //Mi3
        Columna(1,255); Columna(2,30);Columna(3,0);Columna(4,125);Columna(5,0);Columna(6,30);
         Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(27500/v))&&(tiempo<(27750/v)))
      {
        //Mi3
         Columna(1,30); Columna(2,0);Columna(3,125);Columna(4,0);Columna(5,30);Columna(6,255);
         Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(27750/v))&&(tiempo<(28000/v)))
      {
        //Mi3
        Columna(1,0); Columna(2,125);Columna(3,0);Columna(4,30);Columna(5,255);Columna(6,30);
        Fila(1,0);Fila(2,0);
      } 
      
      
    //Compas8
    if ((tiempo>=(28000/v))&&(tiempo<(28500/v)))
      {
        //La3
        Columna(1,125); Columna(2,0);Columna(3,30);Columna(4,255);Columna(5,30);Columna(6,0);
        Fila(1,0);Fila(2,0);
      } 
    if ((tiempo>=(28500/v))&&(tiempo<(29000/v)))
      {
        //Sol3
        Columna(1,0); Columna(2,30);Columna(3,255);Columna(4,30);Columna(5,0);Columna(6,125);
         Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(29000/v))&&(tiempo<(29500/v)))
      {
        //Fa3
        Columna(1,30); Columna(2,255);Columna(3,30);Columna(4,0);Columna(5,125);Columna(6,0);
         Fila(1,0);Fila(2,0);
      }
    if ((tiempo>=(29500/v))&&(tiempo<(30000/v)))
      {
        //Re3
        Todos(0);
      } 
    if ((tiempo>=(30000/v))&&(tiempo<(30500/v)))
      {
        //Do3
        Todos(255);
      }  
    if ((tiempo>=(30500/v))&&(tiempo<(32000/v)))
      {
        //Tres silencios corchea
      if (tiempo<(31900/v)) noTone(12);
      }
    if (tiempo>=(32000/v))
      {
        tiempo0=millis();
        estado=2; //ejecuta Luces()
      }
}



INTERESANTE PROBLEMILLA NO PREVISTO CON PILA DE 9V Y EXCESIVO CONSUMO.

Al final, casi siempre hay algo que podría haber estado mejor pensado. Y aquí he caído en la cuenta, cuando ya todo estaba demasiado montado.
Mi idea original era alimentar todo con una pila de 9v oculta debajo del pino de cartulina. Y en principio todo parece bien pensado, pero haciendo pruebas y test durante la programación me he encontrado con dos detalles:

Con la batería  todo va bien unos minutos, pero enseguida el arduino se apaga y enciende (el regulador de 5v necesita más de 7 en Vin). Cosa que si alimento con el usb (aunque usamos menos tensión), todo parece ir mejor.

Y originalmente las resistencias eran de menos potencia pero se calentaban mucho más de lo deseable. Tuve que montarlas de más watios. Así que tenía que haber exceso de consumo por algún sitio...

Repensando sobre el esquema del circuito ya montado me he dado cuenta que cuando los leds están apagados porque la fila está desactivada, la resistencia limitadora conduce de Vin a masa.  Así que todas las lineas conducen y consumen corriente. Incluso más en reposo.
Esto, aunque no llega a los límites del arduino porque es a través de los transistores, sí que agota la batería demasiado rápido. Las baterías de 9v tampoco son una maravilla en capacidad de carga.
Y si pensamos en una alimentación alta para que los leds alumbren mejor. Más allá de los 15v nos vamos a consumos peligrosos de más de 500mA ((15v/180ohm)*6 resistencias=0,5A).

Así que la idea de alimentarlo con baterías funciona, pero nos saldrá cara. Habrá que fijarse más en esta cuestión para otros proyectos.

Pero en este punto ha quedado éste.


No hay comentarios:

Publicar un comentario

Agradezco comentarios, aportaciones, o críticas...