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.
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.
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.
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.