Endless random LEDs
I have spent many hours trying to figure out how I could use a TO-92 QX5252 to give continuous reliable current all day from a solar panel, when in it's natural state it is configured to shut off at night time.
In a previous blog and YouTube video I triumphantly showed how it could be done by using two such ICs.
Well, the triumph was short-lived as LCSC sent me some SOT23-5 form factor ICs with an extra pin! What could it mean? The datasheet referred to it as LS (light sensor?) but declined to give any useful information about it's function.
So I mounted one of the tiny guys on a SOP8 to DIP adapter and then using a mock up of the circuit on a breadboard I found to my great delight that if the LS was held to ground, the QX5252 was designed to output constantly to pin3.// ----------------------------------------------------------------- // Description: A lightshow built on four "random" LEDs which flick // on or off for a random amount of time depending on which state // is selected. // // Author: OneCircuit Date: 28/01/2021 // ----------------------------------------------------------------- // // MicroChip ATTINY13 μC // // +-\/-+ // RESET--ACD0--5/A0--PCINT5--PB5 1| |8 VCC // CLKI--ACD3--3/A3--PCINT3--PB3 2| |7 PB2--PCINT2--2/A1--SCK--ADC1 // ACD2--4/A2--PCINT4--PB4 3| |6 PB1--PCINT1---1---MISO--OCOB--INT0* // GND 4| |5 PB0--PCINT0---0---MOSI--OCOA* // +----+ // * indicates PWM port // #include <avr/sleep.h> // the sleep routines byte getleds = 0b00000000; // initial all leds off byte sleeptime = 0; // initial timer = 0 uint16_t myrand = 2901; // initial seed -> happy birthday void setup() { DDRB = 0b00001111; // only four outputsPORTB = 0b11110000; // the rest input pullupmyrand = myrand+analogRead(PB4); // reset the seed
} ISR(WDT_vect) { } // generate a "random" number between small and big uint16_t gimmerand(uint16_t small, uint16_t big) { myrand ^= (myrand << 13); myrand ^= (myrand >> 9); myrand ^= (myrand << 7); return abs(myrand) % 23 * (big - small) / 23 + small; } void powerDown(void) { MCUCR = 0b00110000; // see datasheet WDTCR = 0b01000010; // 64ms ADCSRA &= ~(1 << ADEN); // turn off ADC ACSR |= (1 << ACD); // turn off Analog comparator. sei(); // enable global interrupts set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep deeply little one sleep_enable(); // enable sleep mode cli(); // Disable BOD steps BODCR = (1 << BODSE) | (1 << BODS); BODCR = (1 << BODS); sei(); sleep_cpu(); sleep_disable(); // ISR routine returns here so wake up ADCSRA |= (1 << ADEN); // turn on ADC ACSR = (0 << ACD); // turn on Analog comparator. delay(10); // settle time } void loop() { getleds = gimmerand(0, 16); // returns 0..15
sleeptime = gimmerand(1, 25); PORTB = getleds; for (int howmanysleeps = 0; howmanysleeps < sleeptime; howmanysleeps++) { powerDown(); } }
In my mind I wanted to make a neat little package to put the whole shebang into, so I whipped up a 3D printed enclosure, soldered up the circuit and popped the result on the windowsill to flicker away randomly, perhaps forever?
P.S. Update - 4 weeks and still going strong...
No comments:
Post a Comment