Saturday, February 20, 2021

0000 0000 0101 0101

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. 

Also I was simultaneously devastated for all the work trying to make the TO-92 package do the same!



Now a little bit of 4-LED random code for the ATTiny13 as follows:

// -----------------------------------------------------------------
// 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 outputs
  PORTB = 0b11110000;         // the rest input pullup
  myrand = 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