Looking for "Random flash" in a light

Suggested in post #3. One sequence for PWM levels, another for time. They wouldn’t have to be very long either.

A friend saw my new MELD-based light from tterev3, and decided he needed a nasty multicolor random strobe too. My attiny13a flashing hardware is still on its way so I haven’t touched the code, but I think the rest should be pretty easy with parts from RMM’s store. Everything including the host and a battery and charger comes to about $40.

Personally, I’m more interested in variable-speed strobes with really short duty cycles, for freezing moving objects in place. I spec’d out all the timings for one and Everett was nice enough to customize his firmware for me, and it turns out my spec works pretty well. So I have one light which does it and I’m planning to make a more advanced one when the rest of my hardware arrives.

Instead of delay_ms() though, I’m planning to use the PWM hardware to control the strobe. It provides higher time resolution and uses less power, but comes with the caveat that the code will have to adapt to time moving at different speeds depending on the current strobe settings.

So I tried the rand() strobe program earlier and couldn’t get it to work properly, it just flickered very slightly, but only just realised hours later that randpwm and randtime could have 50 and 2000 exchanged?

So tried a if/else statement to drive a Output pin, like this: Rand % 255, 0-100 led on / 100-255 led off. With Randtime % 30 it gives a pretty intense random strobe.

I made a couple of changes:

OCR0B = rand() % 90 + 10; // This gives a minimum of 10 and max of 100. I didn’t want to test full 255 blasts.
uint16_t randTime = rand() % 1990 + 10; // This gives a minimum delay of 10 ms and max 2000 ms

I did the same to the LFSR routin:
OCR0B = (pwm % 90) + 10;
uint16_t timeDelay = time % 1990 + 10;

It just so happened that I used different variable names for time in the two routines, but doesn’t matter.

It it makes a difference, this is how I start main for these small tests:
DDRB=2; //define PB1 as output
TCCR0A=0b00100001; TCCR0B=0b00000001; //PWM setup, 9kHz
OCR0B=5; //set PWM level

If you want to see it all you can download my source at http://www.mikec.se/Stuff/MikeCT1.zip
It also has a fading strobe/beacon I wanted to test.

Everything is commented out… Just uncomment between the = rows to run the specific routine.

Hello everyone. I am a newbie so please forgive the basic questions.

I am building a small light sculpture at Burning Man and am scouring the web for a light source that can emit a strobe, random in both frequency and intensity.

This thread looks very interesting, however everyone here is talking in terms and abbreviations that I do not understand.

Would someone be so kind to guide me through the process of achieving this effect? (what parts to get and possibly where and dare I say it, point me in a direction where I could obtain schematics if necessary?)

Thank you for your time.

How far along are you? You’ll need to flash an ATtiny13A MCU after you compile a firmware.. Depending on how much light you need there are different driver options. The Nanjg 105c is really the prototypical driver for most of our efforts. These efforts largely started with Tido’s BLF-VLD firmware. While his firmware is not as commonly used or discussed anymore, the initial info thread kicked things off and is still a great start for beginners. Related information is also available on this wiki page.

I don’t know what the power requirements of your burning man project will be, but RBD maintains a list including some other drivers you could use.

All that said, be very careful if you aren’t that familiar with LEDs and electronics. If you are running your project on a big battery (car battery, deep cycle, many 18650’s in parallel, etc) then the popular “DD” drivers may not be appropriate (they may destroy LEDs depending on the input to the driver).

My cusom SRK driver has a nasty random strobe mode (intensity and pulse rate). I use the CRC16 function as a random number generator. It doesn’t use much memory. For some true-ish randomness toss in the low order bit from a few reads on a floating input on an ADC channel.

I just made a quick test firmware based on Mike C’s post earlier… seems like it’ll be pretty easy to get the code working (especially if you only need one mode), but the hardware could be tricky depending on what you’re doing.

FWIW, here is the random strobe function I put together as a quick test… only took a few minutes while I was in a voice meeting, so I’d imagine a “real” version wouldn’t be very hard either:

    while(1) {
        // turn the emitter on at a random level,
        // for a random amount of time between 1ms and 20ms (* 4/3)
        uint16_t randTime = rand() % 19 + 1;
        PWM_LVL = rand() % 190 + 10;
        while(randTime--) {                   // _delay_ms() can't take variables that can change, make loop with variable instead
            _delay_ms(1);                     // and delay_ms with fixed value within loop
        }

        // turn the emitter off,
        // for a random amount of time between 1ms and 1000ms (* 4/3)
        randTime = rand() % 999 + 1;
        PWM_LVL = 0;
        while(randTime--) {
            _delay_ms(1);
        }
    }

Slightly OT, but I have seen this "_delay_ms() can't take variables" so many times that it's time to do something for it:

#define OWN_DELAY
#ifdef OWN_DELAY
#include <util/delay_basic.h>
// Having own _delay_ms() saves some bytes AND adds possibility to use variables as input
static void _delay_ms(uint16_t n)
{
    while(n-- > 0)
        _delay_loop_2(1024);
}
#else
#include <util/delay.h>
#endif

…main…

#ifndef OWN_DELAY
uint16_t randTime;
#endif

while(1)
{
// turn the emitter on at a random level,
// for a random amount of time between 1ms and 20ms (* 4/3)
PWM_LVL = rand() % 190 + 10;
#ifdef OWN_DELAY
_delay_ms(rand() % 19 + 1);
#else
randTime = rand() % 19 + 1;
while(randTime–) // _delay_ms() can’t take variables that can change, make loop with variable instead
_delay_ms(1); // and delay_ms with fixed value within loop
#endif
// turn the emitter off,
// for a random amount of time between 1ms and 1000ms (* 4/3)
PWM_LVL = 0;
#ifdef OWN_DELAY
_delay_ms(rand() % 999 + 1);
#else
randTime = rand() % 999 + 1;
while(randTime–)
_delay_ms(1);
#endif
}

In this example, using own delay saved us 16 bytes (with -Os) and made the code cleaner.

Enjoy! :)

Thanks!

This code improves several things:

  • It accepts variables and expressions instead of just hard-coded values.
  • It compiles to a smaller binary, especially if you call it several times from different parts of the code (I saved about 140 bytes!).
  • Its timing can be calibrated in one central spot to provide relatively accurate results. I found that 890 worked pretty well instead of 1024, and now I can use _delay_ms(1000) to make it blink at the same speed as a 60bpm metronome.

I tried briefly to make a custom _delay_ms() function but after half an hour of trying random ideas I didn’t have anything better than the original, so I went back to the default. This one works much better! :slight_smile:

(and now I have another 140 bytes to fill… the possibilities are endless!)

I haven nothing to add to this thread but this is one of my all time favorite dilbert strips.

Not all ATtiny13As have their clocks calibrated. Different voltage and/or temperature will also have some effect => I have seen +-10% results with my drivers, but values around 1000 should be "near enough".

It could also be because I’m using avr-gcc 4.7.2 instead of 4.8.X. It seems to produce bigger binaries, and I suspect it might run a little slower overall (though I’m not sure).

Even just trying two different drivers though, I’m seeing an execution-speed variation of about 5%. I calibrated one so that it’d flash at almost exactly 60bpm, and on another driver it seems to be going at 63bpm with the same code. Maybe I’ll have to calibrate it for each unit, when I have timing-related stuff in the code. I’m not mass-producing anything, so I think I can do that.

I definitely am impressed with the responsiveness of this forum.

I took an extensive look at the reply provided by Wight, thank you for the very helpful links.

The whole subject matter is pretty convoluted for a beginner with a relatively tight deadline however. :~

The ATtiny13A MCU appears to be a bit of a piece of work with somewhat shaky hardware and pretty confusing code involved. I don’t mean to be timid, but I have to have a functioning device by August 15th, otherwise my project will fail to be visible at night and become a safety hazard.

Texaspyro’s SRK driver looks perfect however, thanks for your post. It wasn’t quite clear though if this driver/board has been made available for purchase yet, has it?

It seemed there is a lot of people interested in simply buying this board and I would definitely count myself in there for three boards.

The random strobe effect will really help breathe life into my installation, thank you for your help.

So, you have about three weeks to go from zero to fully-working product?

That might be difficult since some of the parts might need to be shipped from China, and that alone can take longer than three weeks. Most parts can be found within the US (RMM’s store has most of the good stuff), but other pieces might not be available without a wait.

Do you have any idea how much actual light you’ll need? How long it needs to run per charge? Does it need to run from batteries or an external power supply? These all affect the choice of host to use. I mean, at a guess, a 1x18650 tube light might work, assuming it’ll be viewed at night and you’re lighting up a reasonably small area. You might have to change the battery once in a while, depending on the settings you use.

Also, do you know more details about the strobe you’re looking for? I mean, yeah, random, but what kind of speed range and do you want the pulses to be short (freeze motion) or long (looks brighter but has motion blur and eats the battery faster)?

In any case, I’d probably focus on acquiring all the relevant hardware for now, and hopefully it’ll arrive in time.

I attached a drawing of the installation, the strobe effect will be housed between the wings and should feel like a wild heart/energy source,
I intended to house a 12v car battery in the pedestal, (which should be recharged by a solar panel ideally), but would not mind bringing batteries and changing them out throughout the night, which lasts from ~8pm to ~5am.

Why not set the strobe to the beat/melody of your favorite song?

The installation will live far out in the deep playa with nothing surrounding it but open desert. Sometimes there will be sound from passing by mutant vehicles and sometimes it will be eerily quiet. The explosive strobe will be equally at home in both scenarios.

What about using several separate lights in a single group, each with a different strobe timing? The patterns do some really interesting interactions when they're running at different frequencies.

Most of the customizable hardware we've been working with are for low voltage inputs, mostly meant for a single 4.2v lithium rechargeable cell. You could of course use a step-down converter between the 12v battery & the flashlight drivers. You can get a 10-pack of adjustable voltage DC-DC converters off ebay for dirt cheap, each one can supply up to around 2 amps without needing anything special for cooling. Search for 'LM2596 converter' or something similar, limit sellers to US-only if you need them quickly (though doing that will severely limit your options).

Example of the board version you'll want: http://www.ebay.com/itm/251575972513

For the LEDs you can mount several LEDs each run by their own driver onto a single smallish heatsink, effectively creating one strobe unit-thing.

So, I took a video of the random strobe thingie I made. Really less of a strobe and more like a fast random lightning effect.

http://toykeeper.net/torches/random-strobe-mushroom.avi

It’s easy to modify the timing. For example, to eliminate the longer pauses and cut the maximum off-time in half, basically just change a single value in the code. I just wanted to see if this was even anywhere close to what Swissmountain had in mind.

I haven’t measured the current draw (kind of hard to get an average to get a runtime estimate), but I suspect this would probably run all night on a single 18650 battery. I mean, it’s off most of the time… so the battery should last quite a while. It’d need protected cells though, since it doesn’t do any low-voltage detection.