Órgano de luces con Arduino (III)



ATENCIÓN: En este parte se utiliza la tensión de red, lo cual puede llevar sus riesgos. Si no tienes suficiente experiencia o no te crees capacitado, mejor utiliza unos cuantos leds a baja tensión y evítate un susto. El autor no se hace responsable de cualquier posible daño producido por no tomar las debidas medidas de seguridad.
Para la etapa de potencia he utilizado unos triacs del tipo BT137 controlados por optoacopladores del tipo MOC3041. Dependiendo de la potencia que queráis controlar, es posible cambiar el tipo de TRIAC por uno de menor potencia (o mayor ...).
Los optoacopladores MOC3041 contienen internamente un circuito de control para el disparo al paso por cero, es decir el triac siempre se cerrará la pasar la tensión por cero evitando interferencias.
Se pueden utilizar otro tipo de optoacopladores respetando el circuito recomendado por el fabricante.

El esquema es el siguiente:

Etapa de potencia para órgano de luces sicodélicas con Arduino



Y este el aspecto una vez montado (en mi caso la etapa es de 4 canales)

Etapa de potencia para órgano de luces sicodélicas con Arduino

Observar que está montado en una caja convenientemente aislada. Los Triacs llevan disipadores para soportar cargas continuas elevadas (en este caso soportan 8A, lo que permite unos 1500W por canal).

El resultado:


Que os divirtáis ....

Si te ha gustado, recuerda compartirlo en tu red social favorita. Gracias

30 comentarios:

  1. Hola, !me encanta tu proyecto!;).Le he estado echando un vistazo a tu código casi que lo entiendo al 100% y entomces se me ocurrió una idea-duda.Ahora estoy haciendo un proyecto con arduino y mi duda era sobre la posibilidad de combinar la funcionalidad del tuyo con esta matriz de leds (http://www.adafruit.com/products/420) ahí se encuentran los detalles técnicos.
    Observa la entrada para conectar arduino a ala matriz (http://www.ladyada.net/images/rgbmatrix/inputidc.jpg) a la entrada RGB le corresponden 6 en inputs en vez de tres ....Como ejemplo de lo que quiero hacer el más trivial que se me ocurre es el siguiente: dividir la matriz en tres bloques 10x10 R G B y encender segun corresponda a graves medios agudos.¿Como lo ves?Dicha matriz soporta 5V no se que elementos o dispositivos usar para tener esto en cuenta e inmplmentar dicha idea..te agradecería que me echases una mano.

    ResponderEliminar
  2. @tonyc

    Hola

    Por lo que veo, hay un estupendo tutorial de como conectar la matriz a un Arduino en : http://ladyada.net/products/rgbledmatrix/.
    Se puede conectar directamente y no necesitas ningún componente adcional (salvo los cables y conectores)
    El que hayan dos RGB es por que hay 2 paneles de 16x32 juntos y cada uno se controla por separado.
    Para hacer lo que tu dices, creo que lo mejor es utilizar las librerías que mencionan en el tutorial:
    RGB Matrix Panel library y
    Adafruit GFX Library

    y utilizar el método: matrix.fillRect(0, 0, Ancho, Alto, matrix.Color333(R, G, B)) ..

    Por ejemplo:

    matrix.fill(matrix.Color333(0, 0, 0)); // Apagamos todo el panel
    if (siBajos) {
    matrix.fillRect(0, 0, 11, 16, matrix.Color333(255, 0, 0)) // Bloque izquierdo rojo para los graves
    }
    if (siMedios) {
    matrix.fillRect(11, 0, 10, 16, matrix.Color333(0,255, 0)) // Bloque centro verde para los medios
    }
    if (siAgudos) {
    matrix.fillRect(21, 0, 11, 16, matrix.Color333(0, 0, 255)) // Bloque derecho azul para los agudos
    }

    ¡Que te diviertas!

    ResponderEliminar
  3. hola mucho gusto muy bueno tu proyecto estoy buscando ayuda con el codigo de el paso por cero lo necesito muy urg lo intentado varias veces y no me funciona porfavor si me puedes ayudar mi correo es davidleonardo91@gmail.com para que expliques como se programa el paso por cero gracias de antemano

    ResponderEliminar
  4. @david
    No entiendo cual es la pregunta. Necesitas poder detectar el paso por cero, o estás intentando controlar algo y necesitas el código.
    Para detectarlo lo normal es utilizar un optoacoplador , que puede asociarse a una interrupción del arduino para que realizar la tarea que se desee en el momento del paso por cero.
    Este post puede servirte de ayuda:
    http://arduino.cc/forum/index.php?topic=96128.15

    Un saludo.

    ResponderEliminar
  5. si lo quisiera hacer para un voltaje de 110 q cambios recomiendas hacer?

    ResponderEliminar
  6. @Lioncourt
    No necesitas ningún cambio, el circuito funciona igual, sólo necesitarás una alimentador para el circuito que funcione con 110V

    ResponderEliminar
  7. Me ha encantado "Arduino guay" estaba un poco confuso con este tema y me ha ayudado mucho. Muchas gracias. Saludos

    ResponderEliminar
  8. Saludos excelente proyecto, se puede modificar para que en vez de tener solo 3 canales, pudiera tener por ejemplo 12? Y saber si en vez de usar un solo led por canal, se pudiera colocar barras de led digamos 8 por cada canal. En mi caso seria 12x8= 96 led

    ResponderEliminar
  9. @jhefren
    Hola, lo de los 12 canales no es problema. Simplemente poniendo en el código
    #define MUESTRAS 24
    ya tendrás después de calcular en el array salida 12 valores (en vez de 64 como en el ejemplo. Luego no hace falta que repartas en tres bandas como se hace en el código.
    Lo de poner barras en vez de leds, ya es más complicado, podrías utilizar una matriz de manera que las columnas sean las 12 bandas y las filas sean proporcionales al valor de cada banda. Hay ejemplos de como manejar una matriz con Arduino :
    Arduino con MAX 7219
    Manejo de matriz de leds con Arduino

    ResponderEliminar
  10. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  11. Hola, cómo es que conectas el cable de la lampara a la terminal 1 del Triacs?

    ResponderEliminar
  12. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  13. Podría poner las R4, R5, R6 a 330ohm 0 390ohm (son las que he encontrado), en vez de 360? son compatibles? que consecuencias tendría?

    ResponderEliminar
  14. @Jorge León Bullón
    No hay problema, aumentará un poco la corriente de la puerta, pero ten en cuenta que las resistencias tienen una tolerancia (normalmente de 5%) y los valores no son críticos.

    ResponderEliminar
  15. @Abdel Rojas
    Es el montaje recomendado en la hoja de datos del optoacoplador
    MOC3041

    ResponderEliminar
  16. @Jose Daniel Herrera

    Monté el esquema, la resistencia de 360, la he sustituido por una de 330, el problema que tengo es que la tensión de salida no queda constante y como consecuencia me "tiembla" la bombilla a valores medios!
    Se enciende del todo correctamente, y se apaga también, pero cuando quiero que la tensión sea la mitad, veo que el valor no es constate sino que me oscila entorno a 100v. ¿Alguna idea de como poder solucionarlo?

    Gracias!

    ResponderEliminar
  17. @Jorge León Bullón
    No acabo de entender el problema. El valor de la tensión varía continuamente, se supone que sigue el ritmo de la música!

    ResponderEliminar
  18. @Arduino Guay

    Realmente quiero hacer un dimmer para una bombilla normal, y como no tengo ni idea de electrónica y estoy empezando con arduino estoy leyendo mucho y entendiendo lo que puedo. Entonces de tu proyecto quería sacar el circuito de la parte del triac, pero no estaba prestando atención al codigo, y creia que si sacaba por un pin un valor fijo eso se traduciría a la bombilla.
    Leyendo he entendido que hay que programar el arduino, aun ni tengo claro los conceptos pero algo asi como calcular el ángulo de disparo del triac para los 50hz de la corriente alterna. Seguire leyendo en los ratos que puedas hasta que entienda y saque un codigo que haga lo que quiero.

    ResponderEliminar
  19. Hola como estas? soy yo otra vez
    Tú me indicaste que con cambiar el valor de muestreo a 24
    #define MUESTRAS 24 y colocarlo en el arreglo salida ya tenia mis valores, pero en tu programa tu repartes en tres bandas, pero la idea mia era hacer 12 bandas, como la que tienes los ecualizadores: 100 Hz, 250 hz, 600 Hz, 850 Hz, 1200 Hz, etc, etc. cada led se iluminara con cada frecuencia. De acuerdo a lo que me dices con 12 valores en el arreglo de salida tendria ya dichas frecuencias estoy en lo correcto o no? Tampoco haria falta repartir en dichas frecuencia, ni recalcular los valores limites, tal como lo haces en tu programa. Muchas Gracias

    ResponderEliminar
  20. Otras preguntas, tendras alguna idea de como hacer filtros IIR, PIR y Filtros Kalman?

    ResponderEliminar
  21. @jhefren
    Efectivamente, con MUESTRAS 24 ya tienes los 12 canales y no es necesario repartir nada ...
    Los valores límite se recalculan porque se trata de encender un led (o bombilla) y esto permite tener en cuenta las variaciones de nivel de la música, pero si lo que quieres es iluminar una barra tipo vu-meter, no es necesario, directamente el valor que obtengas en cada banda, sera el que debas adecuar a tu barra de luces.

    ResponderEliminar
  22. @jhefrenPersonalmente no :-(, pero si 'googleas' seguro que encuentras algo ;-)

    ResponderEliminar
  23. Como estas Arduino Guay
    Mira queria que me aclararas como trabaja la funcion ventana de Hann paso a paso, hay cosas que no entiendo, por ejemplo cuando colocas (char *vData); que significa
    En el Bucle For declaras uint8_t; que significa
    y por ultimo vData[i]*=factorPeso;
    y Porque no usaste otro tipo de ventana como estos:

    Rectangular
    Hamming
    Blackman
    Blackman-Nuttall
    Flat top
    Gauss
    Triangular
    Bartlett
    Bartlett-Hann
    Kaiser
    Disculpa la preguntadera, pero soy novato en programacion en SeudoCodigo Arduino, trabajo mejor con assembler en microcontroladores PIC. Aunque es mas complejo implementar algo asi como esto en PIC gama media y baja. Muchas Gracias

    ResponderEliminar
  24. @jhefren
    1) char *vData es un array de char, el nombre de la variable es vDAta.
    2) uint8_t es un tipo de de dato unsigned char de 8 bits, es decir un byte
    3) vData[i]*=factorPeso es lo mismo que vData[i]= vData[i] * factorPeso
    Para el tipo de aplicación (encender unas bombillas al ritmo de la música), el tipo de ventana es poco importante, cualquiera de ellas serviría

    ResponderEliminar
  25. hola (otra vez)!! tienes una foto del abajo del power stage?? he tratado de de seguir el esquema, pero no funciona.

    ResponderEliminar
  26. Saludos... ando queriendo realizar este proyecto pero en 4 leds (agudos, medios, bajos y graves) pero me esta costando dividir bien las señales... me gustaria saber si podrias indicarme en que me ando equivocando.

    #include "fix_fft.h"

    #define MUESTRAS 128
    #define LOGM 7

    #define GRAVES_MEDIOSBAJOS 5
    #define MEDIOSBAJOS_MEDIOSALTOS 20
    #define MEDIOSALTOS_AGUDOS 35


    #define APIN 9 // GRAVES
    #define BPIN 10 // MEDIOS BAJOS
    #define CPIN 11 // MEDIOS ALTOS
    #define DPIN 12 // AGUDOS
    #define MAX_PASADAS 10

    char data[MUESTRAS];
    char im[MUESTRAS];

    unsigned char salida[MUESTRAS/2];
    unsigned char graves, mediosbajos, mediosaltos, agudos;

    byte pasada;
    byte ACUGRAVES,ACUMEDIOSB,ACUMEDIOSA,ACUAGUDOS;
    byte LIMGRAVES,LIMMEDIOSB,LIMMEDIOSA,LIMAGUDOS;

    void aplicaVentana (char *vData) {
    double muestrasMenosUno = (double(MUESTRAS) - 1.0);
    for (uint8_t i = 0; i < MUESTRAS/2 ; i++) {
    double indiceMenosUno = double(i);
    double ratio = (indiceMenosUno / muestrasMenosUno);
    double factorPeso = 0.5 * (1.0 - cos(6.28 * ratio));
    vData[i] *= factorPeso;
    vData[MUESTRAS - (i + 1)] *= factorPeso;
    }
    }

    void setup() {
    bitWrite(ADCSRA,ADPS2,1);
    bitWrite(ADCSRA,ADPS1,0);
    bitWrite(ADCSRA,ADPS0,1);

    analogReference(INTERNAL);

    pinMode(APIN,OUTPUT);
    pinMode(BPIN,OUTPUT);
    pinMode(CPIN,OUTPUT);
    pinMode(DPIN,OUTPUT);

    pasada = 0;
    ACUGRAVES,ACUMEDIOSB,ACUMEDIOSA,ACUAGUDOS = 0;
    LIMGRAVES,LIMMEDIOSB,LIMMEDIOSA,LIMAGUDOS = 50;
    }

    void loop() {
    for( int i=0; i < MUESTRAS; i++) {
    data[i] = analogRead(0)/4 -128;
    im[i] = 0;
    }

    aplicaVentana (data);
    fix_fft(data,im,LOGM,0);

    for (int i=0; i < MUESTRAS/2; i++){
    salida[i] = data[i] * data[i] + im[i] * im[i];
    }

    graves = 0;
    for (int i=2; i < GRAVES_MEDIOSBAJOS; i++){
    graves += salida[i];
    }
    graves = graves/2;


    mediosbajos= 0;
    for (int i=GRAVES_MEDIOSBAJOS; i < MEDIOSBAJOS_MEDIOSALTOS; i++){
    mediosbajos += salida[i];
    }
    mediosbajos = mediosbajos/2;

    mediosaltos= 0;
    for (int i=MEDIOSBAJOS_MEDIOSALTOS; i < MEDIOSALTOS_AGUDOS; i++){
    mediosaltos += salida[i];
    }
    mediosaltos = mediosaltos/2;

    agudos = 0;
    for (int i=MEDIOSALTOS_AGUDOS; i < MUESTRAS/2; i++){
    agudos += salida[i];
    }
    agudos = agudos/2;


    int siGraves = graves > LIMGRAVES;
    int siMediosB = mediosbajos > LIMMEDIOSB;
    int siMediosA = mediosaltos > LIMMEDIOSA;
    int siAgudos = agudos > LIMAGUDOS;

    digitalWrite(APIN,siGraves ? HIGH : LOW);
    digitalWrite(BPIN,siMediosB ? HIGH : LOW);
    digitalWrite(CPIN,siMediosA ? HIGH : LOW);
    digitalWrite(DPIN,siAgudos ? HIGH : LOW);

    ACUGRAVES += siGraves;
    ACUMEDIOSB += siMediosB;
    ACUMEDIOSA += siMediosA;
    ACUAGUDOS += siAgudos;

    if ( ++pasada > MAX_PASADAS ) {
    pasada = 0;
    LIMGRAVES = 20 + ACUGRAVES*5;
    LIMMEDIOSB = 20 + ACUMEDIOSB*5;
    LIMMEDIOSA = 25 + ACUMEDIOSA*5;
    LIMAGUDOS = 20 + ACUAGUDOS*5;

    ACUGRAVES = 0;
    ACUMEDIOSB = 0;
    ACUMEDIOSA = 0;
    ACUAGUDOS = 0;
    }
    }

    Gracias!

    ResponderEliminar
  27. @Anónimo
    En principio parece que está todo bien.
    El único problema que veo, es la división de bandas que has hecho:
    Para los graves pones hasta la banda 5 , pero en el bucle que calcula fíjate que se empieza en la 2 y se coge hasta una menos (<), es decir se queda reducido a la banda 3 y 4 , y luego se divide por 2.
    Esto hará que este canal tenga valores muy bajos.
    Puedes añadir más bandas, no dividir *2 (incluso multiplicar por algún coeficiente), o bajar el límite de esta banda.

    graves = 0;
    for (int i=2; i < GRAVES_MEDIOSBAJOS; i++){
    graves += salida[i];
    }
    graves = graves/2;

    ResponderEliminar
  28. Buenas soy nuevo en esto de arduino, he leído tu post y creo que me servirá para la idea que tengo, desde hace un año, con algunas modificaciones.
    Una pregunta, ¿la programación serviría para Arduino nano con el chip atmega 328P?¿y en que salidas lo pondría? para hacerlo con una tiras led.

    Gracias de antemano.

    ResponderEliminar
  29. A se me olvidaba ¿si no me equivoco se alimenta a 5V, verdad?

    ResponderEliminar
  30. Para los que tengan error de copilación, probablemente sea la versión del IDE de arduino que estan utlizando, hay dos soluciones una es modificar la libreria o utilizar la versión 1.5.3 del IDE de arduino.

    ResponderEliminar

Nota: solo los miembros de este blog pueden publicar comentarios.