Circuito de LED que cambia de color al encenderse

1

El circuito que planeo hacer tendrá 3 LED RGB y lo que me gustaría es que cambie de color cada vez que se encienda en un color aleatorio. Soy un nivel principiante, por lo que cualquier ayuda será muy apreciada.

    
pregunta user46982

1 respuesta

1

Una forma sería usar un microcontrolador, si está familiarizado con ellos. 3 pines de salida de un microcontrolador (ANODE1, ANODE2, ANODE3) se conectarán a 3 ánodos de todos los LED RGB. Luego, 3 pines de salida más de un microcontrolador (SELECT1, SELECT2, SELECT3) a 3 bases de transitores NPN, conectados a 3 cátodos de los LED.

simular este circuito : esquema creado usando CircuitLab

Por lo tanto, para cambiar el color de un solo LED RGB, tendría que configurar uno de los pines SELECCIONAR alto y otros dos bajos, entonces tendría que configurar ANODO pines al azar (alto o bajo). Por supuesto, debido a la multiplexación, tendría que hacer esto una y otra vez para que parezca que todos los LED RGB están encendidos todo el tiempo. Pero lo bueno es que puedes usar un pequeño microcontrolador como AVR attiny25 con solo 8 pines.

Si estuvieras trabajando con AVR, el código se vería así:

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define WORK_DDR     DDRD
#define WORK_PORT    PORTD
#define ANODE1       PIND0
#define ANODE2       PIND1
#define ANODE3       PIND2
#define SELECT1      PIND3
#define SELECT2      PIND4
#define SELECT3      PIND5   

// From: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=254771
#define RANDOM       (uint8_t)((double)rand() / ((double)RAND_MAX + 1) * 2)     

// Generate states for each LED and save them for further use:
// 3 states (red, green, blue) either on or off for 3 LEDs
uint8_t led_states[3][3] = 
{
    {RANDOM, RANDOM, RANDOM}, // RGB for first LED
    {RANDOM, RANDOM, RANDOM}, //RGB for second LED
    {RANDOM, RANDOM, RANDOM} // RGB for third LED
};

volatile uint8_t selected_led = 0; // Currently selected RGB LED for display

int main(void)
{
    WORK_PORT = 0; // Set all pins to low
    WORK_DDR |= ((1<<ANODE1) | (1<<ANODE2) | (1<<ANODE3) |
             (1<<SELECT1) | (1<<SELECT2) | (1<<SELECT3)); // Set defined pins as outputs

    sei(); // Enable interrupts
    // Set timer0 for changing the selected RGB LED:
    TCCR0A = (1<<WGM01); // Timer0 CTC mode
    TIMSK = (1<<TOIE0); // Enable interrupt on timer0 overflow
    OCR0A = 31; // ~60Hz on 1MHz clock
    TCCR0B = (1<<CS02); // Start Timer0 with 256x prescaler

    // Infinite loop
    while (1) {

    }
}

// Timer0 overflow interrupt
ISR(TIMER0_OVF_VECT) 
{
    // If we have currently selected last (third) LED, select first one, else just select next one
    if (selected_led == 2) {
        selected_led = 0;           
        WORK_PORT = (1<<SELECT1); // Select first RGB LED
        WORK_PORT |= ((led_states[0][0]<<ANODE1) | (led_states[0][1]<<ANODE2) |  
                  (led_states[0][2]<<ANODE3)); // Update first RGB LED with saved RGB status
    } else {
        // Select next RGB LED
        selected_led += 1;

        if (selected_led == 1) {
            WORK_PORT = (1<<SELECT2);
            WORK_PORT |= ((led_states[1][0]<<ANODE1) | (led_states[1][1]<<ANODE2) | 
                      (led_states[1][2]<<ANODE3)); // Update second RGB LED with saved RGB status
        } else {
            WORK_PORT = (1<<SELECT3);
            WORK_PORT |= ((led_states[2][0]<<ANODE1) | (led_states[2][1]<<ANODE2) | 
                      (led_states[2][2]<<ANODE3)); // Update third RGB LED with saved RGB status
        }
    }
}

Tenga en cuenta que esto no está probado, por lo que no estoy completamente seguro de que funcionará, pero no dude en probarlo y avisarme si algo no está funcionando.

    
respondido por el Golaž

Lea otras preguntas en las etiquetas