I thought about titling this "Don't blink" in honor of the great Doctor Who episode, but that would sound like I was recommending against the ThingM products.
And that isn't true. I think the BlinkM is, unfortunately, underpowered for theatrical use. I took my breadboard out to the theater and viewed it from stage distance against a variety of subdued lighting looks and the best that can be said is that it will light up a diffuser globe real well with color. Casting light you can see on an actor, though...not so much.
So it is time to play Tool-Tim Tim, but there are a bewildering variety of options for "More Power!" I spent a while trying to spreadsheet them (and downloading lots and lots of datasheets from different manufacturers). And, well...for a smaller and simpler battery-powered device the BlinkM MaxM is actually quite competitive. So my work in hacking up alternate software wasn't a complete waste (although I really need to rewrite the core function as an interrupt-driven loop -- and there are some cute PWM tricks you can do to speed things up even more).
At the lowest price end of the options, the ATtiny chips can sink 40 ma from each of the I/O pins. Each channel in an RGB "Piranha" LED is about 20 ma. So technically one CPU chip could drive as many as three Pirahna, making it 3x the power output. Which of course will not appear 3x as bright in most situations! There are other 20 ma LEDs around, but most of the super-bright and ultra-bright (which inevitably give misleading specs in millicandella) are narrow-angle. And that just isn't appropriate for most of the lighting applications I have in mind. One exception is the "flat-top" LED sold by some Hong Kong suppliers, which offers 25 ma and a half angle of 120 degrees.
For making a pure candle (or perhaps some RGB thing that is around the same effective output) it is hard to beat the price point of buying ATtiny's and Piranha LEDs in bulk. Wire them up with no driver, no power regulator...nothing but ballast resistors. You can make them on a perf or in "dead bug" style for a nice small form factor. Actually, you can make them brighter and more efficient by sacrificing the RGB and using amber, yellow, or "warm white" LEDs instead. The main advantage to using multiple LEDs in a candle is that you can move the point source around a little and produce a nice flicker in angle as well as in intensity.
For practically anything else I can think of in theater -- and that includes a railway lantern or any period portable light sources other than candles -- we need more power. Which introduces drivers to the equation. The simplest driver circuit is a Darlington. The handy ULN2803 can sink 8 channels worth at 500 ma each from a basic 20-pin DIP package. The venerable TIP120 power Darlington can swing as much as 5 WATTS.
Wiring up multiple LEDs yourself can be time consuming. SparkFun carries the "Satellite" from the same people who built the ShiftBright; it is a grid of 13 single-color Piranha meaning it puts out about 300 ma per color channel. Which makes it about 15 x the lumens of the BlinkM. Adding the driver and CPU and some discretes, however, brings you close to the $24 of the MaxM -- which is already assembled, and uses just three high-power RGBs to put out the same juice in a more compact package.
So to make it worthwhile you need to jump up to the Luxeons and similar LEDs pulling from half an amp to a whopping 10 amps each. SparkFun does have breakouts, but they are pricey; it brings the surface-mount Luxeon Rebel up to about $7 a channel -- not including controller -- and $18 for an RGB array. Plus you might just want to add diffusing lens, additional heat sink, even a constant-current source.
At which point you step back and say, "I'm not trying to do UL-listed architectural lighting here; I just want an effect for stage use." And this makes some of the Hong Kong suppliers hanging out on eBay very attractive; as some of them offer 1-3 watt (300 to 750 ma) single-color surface-mount LEDs with rudimentary breakout boards/heatsinks for as low as a buck each. Throw in some TIP120's to switch them, hack out some primitive PWM code on an ATtiny, and if you are lucky it won't burn out (or worse, burn up) before the show closes.
Which, if someone comes up to me today and says, "We want Willy Wonka's cane to light up when he taps it on the floor," is what I will do.
And I'm still going to stick my modified BlinkM in one of those cheap plastic candlesticks to show it off.
Tricks of the trade, discussion of design principles, and musings and rants about theater from a working theater technician/designer.
Saturday, May 26, 2012
Wednesday, May 23, 2012
Blink Blink
My code is kudzu, but have the basics for the new BlinkM running. One thing I didn't think about was that mixing to amber isn't wonderful on an RGB LED. It makes an "okay" candle but it isn't a lovely color. Might be better to build one from scratch around a 1 watt amber LED instead!
Except -- one thing I was thinking as I remembered how real candles and lanterns look, is that they don't just dim up and down. The location of the light SHIFTS over time, which can lead to very visible flickering shadows. So a cluster of amber LEDs, each fading independently, is a better model and a better effect.
So maybe I should just design my own board from scratch. Sigh.
In other electronics news, one of the three shows in the pipeline might have an R/C robot in it. I think the director's idea was that we would find a cool toy robot and use it, but just maybe we'll make up our own stage-sized, 1970's looking, camera-toting robot.
A fresh look around and we could put together a tracked chassis and controller for a bit over a hundred bucks. How long it would take to program to respond to the controller is unknown -- it might be a simple plug-and-play, or it might be a hassle.
Well, back to trimming the kudzu. I'm using a hand-drawn look-up table to smooth the fade curve (128 possible programmed levels feeds into 255 pulse width positions). I'm still using delay(microseconds) instead of delving into an interrupt timer, because I'm pretty sure the built-in Arduino functions are all pointing at the wrong register locations for an ATtiny45. Actually, I'm rather surprised at how much of the Arduino code compiles without issue on the ATtiny. If I really cared about performance I'd re-do the code in straight C.
I've tried three different methods of plugging in target values; the random(min, max) function, a toggle or switch/case for simple binary looks (like a power button pulse), and an array for multi-step programs.
I haven't added the next layer of the code, which is smooth cross fading from one running program to another. I'm not sure it is actually needed. What I DO have to try out soon is the button method. At Makers Faire, ThingM was showing off a couple of MaxM demonstrations with program functions through that analog input port. So it obviously can be done. Unfortunately that same pin is part of the ISP header, so programming and testing this is likely to be fun.
As I suspected, it was fun -- the exposed analog I/O pin is shared with Sck -- the clock pin necessary for programming. So spent a delightful hour pulling out and putting back that pin so I could try out different software interpretations of the analog input.
The concept proofs. Using a 500K linear slide pot, I am able to solidly dial in at least 10 selections. Once I get it off breadboard and soldered up properly with power supply smoothing and so forth it should be just fine.
But writing various "looks" so I could see what it was like to switch between them really impressed on me that I need to finish the "program step" code that will allow me to simply write a short array of numbers and let the software take care of the rest of it.
It never is quite so simple, is it? I wrote a somewhat cool set of functions that read off target values from an array. This meant I could write new looks just by writing columns of four numbers (R, G, B intensity and Fade Rate.) In addition, a set of "999" codes told the software whether to loop back or hold at the end of the array values.
Except. Because of my shaky breadboard and random old potentiometers -- plus the hassle of pulling the Scl Pin out of the programmer and putting it back over and over -- I didn't realize the jitter I was seeing was actually in the code.
Apparently arrays are a bit funky on the ATtiny. Or they are funky when combined with things like AnalogRead. Because even when I gave up on getting stable behavior with the analog pin, I still couldn't switch looks with a digital input without all sorts of funny behavior.
So I tossed that whole section of code. As it turned out anyhow, most of the looks I wanted to write were randomized functions (candle light, color swirls) and those were already rather shoe-horned into the array value code. But I did have to give up being able to change looks any arbitrary point in a fade cycle; all those button calls were making the fades jittery.
The new version works. It was solid enough going from look to look via potentiometer, which means that a selected resistor soldered to a switch will work just fine. And since I'd already gone too late to start on other tasks, I checked out the XBee connection as well. Since the XBee node I was using was configured to reset the pin values after 650 ms, I had to do a bit of a hack to be able to switch looks. In the proper version, the XBee will maintain a particular pin state and thus the BlinkM will always be able to detect it the next time it hits the end of a fade loop.
But I'd say the concept is now well and truly proofed.
The question is, is it worth it? For what I want to do with theatrical candles or lanterns, it might be smarter to purchase amber LEDs and create a custom circuit. Even using a through-hole ATtiny, in the 8-pin DIP configuration the electronics package is still going to be smaller than the battery. And for other applications, like the Witch's Crystal Ball for "Wizard of Oz," I think I need more output than the BlinkM can give me.
And here we have a few choices, all of them poor. The MaxM, which can take the same programming but is about twice the cost of the BlinkM. SparkFun has a fairly cheap breakout and driver board for the Luxeon LEDs but it is badly designed and using it just offends the engineer in me. The ATtiny chip by itself tops out at the 30 mW or so of the Piranha LEDs (and buying ATtinys and Piranhas in bulk is a lot cheaper than buying BlinkMs) but that is not any brighter. There are some driver chips that will handle an intermediate value...but at some point you need to admit what you need for some effects is close to the output of a theatrical instrument. So we're talking 5 watt LEDs here and a lot of work with drivers and power supplies and heat sinks.
Well. The concept is proofed, but it is hard to show off a breadboard with ISP and battery pack stuck to it with double-stick. I might, might just find a cheap candlestick -- even better, one that already has a fake candle flame at one end -- and hack it to the full glory of a remote-controlled candle.
November 9, 2012 --
Made two more discoveries. First is that the current show is using a dozen or so of those LED tea candles, and they are quite bright enough for what they are doing. So the BlinkM, modified or not, may not be capable of doing all of the effects I wanted from it, but it can make a realistic candle.
(I also brought my current circuit to a dinner party and left it running on a coffee table -- and the host asked "is that candle over there safe or should we put it out before it catches something on fire?")
The other was discovery of an article on the internal coding of the Arduino "digitalWrite" function. It had not occurred to me that the function could be THAT inefficient. 56 program cycles? This explains why my math was off by what appeared to be (without benefit of an oscilloscope) about two magnitudes.
So writing a new version that uses direct pin manipulation instead of the Arduino macro would run a good 50 times faster. And that would mean smoother fading.
Except -- one thing I was thinking as I remembered how real candles and lanterns look, is that they don't just dim up and down. The location of the light SHIFTS over time, which can lead to very visible flickering shadows. So a cluster of amber LEDs, each fading independently, is a better model and a better effect.
So maybe I should just design my own board from scratch. Sigh.
In other electronics news, one of the three shows in the pipeline might have an R/C robot in it. I think the director's idea was that we would find a cool toy robot and use it, but just maybe we'll make up our own stage-sized, 1970's looking, camera-toting robot.
A fresh look around and we could put together a tracked chassis and controller for a bit over a hundred bucks. How long it would take to program to respond to the controller is unknown -- it might be a simple plug-and-play, or it might be a hassle.
Well, back to trimming the kudzu. I'm using a hand-drawn look-up table to smooth the fade curve (128 possible programmed levels feeds into 255 pulse width positions). I'm still using delay(microseconds) instead of delving into an interrupt timer, because I'm pretty sure the built-in Arduino functions are all pointing at the wrong register locations for an ATtiny45. Actually, I'm rather surprised at how much of the Arduino code compiles without issue on the ATtiny. If I really cared about performance I'd re-do the code in straight C.
I've tried three different methods of plugging in target values; the random(min, max) function, a toggle or switch/case for simple binary looks (like a power button pulse), and an array for multi-step programs.
I haven't added the next layer of the code, which is smooth cross fading from one running program to another. I'm not sure it is actually needed. What I DO have to try out soon is the button method. At Makers Faire, ThingM was showing off a couple of MaxM demonstrations with program functions through that analog input port. So it obviously can be done. Unfortunately that same pin is part of the ISP header, so programming and testing this is likely to be fun.
As I suspected, it was fun -- the exposed analog I/O pin is shared with Sck -- the clock pin necessary for programming. So spent a delightful hour pulling out and putting back that pin so I could try out different software interpretations of the analog input.
The concept proofs. Using a 500K linear slide pot, I am able to solidly dial in at least 10 selections. Once I get it off breadboard and soldered up properly with power supply smoothing and so forth it should be just fine.
But writing various "looks" so I could see what it was like to switch between them really impressed on me that I need to finish the "program step" code that will allow me to simply write a short array of numbers and let the software take care of the rest of it.
It never is quite so simple, is it? I wrote a somewhat cool set of functions that read off target values from an array. This meant I could write new looks just by writing columns of four numbers (R, G, B intensity and Fade Rate.) In addition, a set of "999" codes told the software whether to loop back or hold at the end of the array values.
Except. Because of my shaky breadboard and random old potentiometers -- plus the hassle of pulling the Scl Pin out of the programmer and putting it back over and over -- I didn't realize the jitter I was seeing was actually in the code.
Apparently arrays are a bit funky on the ATtiny. Or they are funky when combined with things like AnalogRead. Because even when I gave up on getting stable behavior with the analog pin, I still couldn't switch looks with a digital input without all sorts of funny behavior.
So I tossed that whole section of code. As it turned out anyhow, most of the looks I wanted to write were randomized functions (candle light, color swirls) and those were already rather shoe-horned into the array value code. But I did have to give up being able to change looks any arbitrary point in a fade cycle; all those button calls were making the fades jittery.
The new version works. It was solid enough going from look to look via potentiometer, which means that a selected resistor soldered to a switch will work just fine. And since I'd already gone too late to start on other tasks, I checked out the XBee connection as well. Since the XBee node I was using was configured to reset the pin values after 650 ms, I had to do a bit of a hack to be able to switch looks. In the proper version, the XBee will maintain a particular pin state and thus the BlinkM will always be able to detect it the next time it hits the end of a fade loop.
But I'd say the concept is now well and truly proofed.
The question is, is it worth it? For what I want to do with theatrical candles or lanterns, it might be smarter to purchase amber LEDs and create a custom circuit. Even using a through-hole ATtiny, in the 8-pin DIP configuration the electronics package is still going to be smaller than the battery. And for other applications, like the Witch's Crystal Ball for "Wizard of Oz," I think I need more output than the BlinkM can give me.
And here we have a few choices, all of them poor. The MaxM, which can take the same programming but is about twice the cost of the BlinkM. SparkFun has a fairly cheap breakout and driver board for the Luxeon LEDs but it is badly designed and using it just offends the engineer in me. The ATtiny chip by itself tops out at the 30 mW or so of the Piranha LEDs (and buying ATtinys and Piranhas in bulk is a lot cheaper than buying BlinkMs) but that is not any brighter. There are some driver chips that will handle an intermediate value...but at some point you need to admit what you need for some effects is close to the output of a theatrical instrument. So we're talking 5 watt LEDs here and a lot of work with drivers and power supplies and heat sinks.
Well. The concept is proofed, but it is hard to show off a breadboard with ISP and battery pack stuck to it with double-stick. I might, might just find a cheap candlestick -- even better, one that already has a fake candle flame at one end -- and hack it to the full glory of a remote-controlled candle.
November 9, 2012 --
Made two more discoveries. First is that the current show is using a dozen or so of those LED tea candles, and they are quite bright enough for what they are doing. So the BlinkM, modified or not, may not be capable of doing all of the effects I wanted from it, but it can make a realistic candle.
(I also brought my current circuit to a dinner party and left it running on a coffee table -- and the host asked "is that candle over there safe or should we put it out before it catches something on fire?")
The other was discovery of an article on the internal coding of the Arduino "digitalWrite" function. It had not occurred to me that the function could be THAT inefficient. 56 program cycles? This explains why my math was off by what appeared to be (without benefit of an oscilloscope) about two magnitudes.
So writing a new version that uses direct pin manipulation instead of the Arduino macro would run a good 50 times faster. And that would mean smoother fading.
Sunday, May 20, 2012
Quick Hack
Makers Faire was this weekend and for once I didn't have to work a show. I went, I wandered, I bought a couple parts, but mostly I listened to music, pedaled a generator at the pedal-powered stage, and drank the only beer they sold (although I was dying for some decent German beer).
Was house tech over the weekend for a show that brings their own sound and light operators. Except for one early-morning showcase performance. When they handed me a CD and told me they had a couple of simple lighting cues. Problem; the sound board is still at FOH position (actually, rear of the house, but the important part is, it is NOT near the light board).
So pulled some toys out of the bag to be able to run the light board remotely. There's one MacGuyver episode where he has to build a telescope from random lenses and he has maybe five minutes to do what took Galileo years. But as Mac puts it -- he already knew it could be done. Same with the lighting console -- I'd SEEN another group use one of the MIDI functions to control the ETC "Expression" board. I just hadn't done it myself.
Opened the manual. The Expression speaks MSC (MIDI Show Control) and will take a "Go" in that format. Ran a MIDI connection through the audio snake that was already there via my hand-made pair of MIDI-to-XLR adapter cables. I remembered QLab had some kind of drop-down menu of MIDI control sequences already written for you -- I opened up my fully-registered copy of QLab 1.0 and looked around.
The board didn't seem to be seeing the commands, but then after I'd tapped at the button a few times (trying different options) I noticed the lights had changed. Turns out you had to deliberately press and hold the "send a message now" button within the QLab interface before it would spit out the full-length MSC.
Now, since it was already in my bag, I pulled out my Arduino-based MIDI message generator and the XBee-modified Staple's Easy Button. And now I could trigger the "Go" button for the next lighting cue from basically anywhere in the theater.
It's a hack, and a bit of a chain; the inside of the Easy Button currently holds not just the XBee node but is wasting a perfectly good USB Explorer as a break-out board. I haven't gotten around to putting in a new breakout board (and boost converter) as replacements. When the Easy Button is pressed, the XBee node sends a radio message with the changed status of pin D0. The receiving node toggles the output level of its pin D0 in response, and the Arduino it is connected to detects this as a switch closed (aka +v is present on a pin that is otherwise pulled to ground. Or is it the other way around?) The Arduino, which at least is in a nice box, debounces the "switch/sensor" input, creates a NoteOn event, and sends it out the serial port at 31250 BAUD. A standard MIDI connector picks this up, creates a newly formatted message via USB, and this triggers a cue within QLab. The QLab cue creates a new MIDI event -- an MSC "Go" command -- and shoots that OUT the same USB MIDI adapter. That runs through two adapter cables and sixty feet of audio snake to reach the back of the lighting console.
But, the point of the demonstration is, this worked. And more importantly than that, it worked off-the-shelf. I had the components already, and I didn't even have to go inside via the USB connection and write new code to one or more of the components to do this particular task (which, if I had, could have removed the laptop and its MIDI adapter from the chain of connections).
And this is what I've been striving at with all of my theatrical gadgets; to have things that I can pull out of the gig bag and hook up in a few minutes to solve a problem. Or to so something new that hasn't been done before, thus enhancing the fun and the creative options of a show.
And today I needed to do a touch-up focus on stage and I had no assistant to run the board. At least this theater has an RFU (Remote Focus Unit), but it was still faster to write a couple of cues, each containing just the system I needed to touch up, then hook up my Wireless Easy Button again. And then I could move from light to light without having to run back to the board each time.
Was house tech over the weekend for a show that brings their own sound and light operators. Except for one early-morning showcase performance. When they handed me a CD and told me they had a couple of simple lighting cues. Problem; the sound board is still at FOH position (actually, rear of the house, but the important part is, it is NOT near the light board).
So pulled some toys out of the bag to be able to run the light board remotely. There's one MacGuyver episode where he has to build a telescope from random lenses and he has maybe five minutes to do what took Galileo years. But as Mac puts it -- he already knew it could be done. Same with the lighting console -- I'd SEEN another group use one of the MIDI functions to control the ETC "Expression" board. I just hadn't done it myself.
Opened the manual. The Expression speaks MSC (MIDI Show Control) and will take a "Go" in that format. Ran a MIDI connection through the audio snake that was already there via my hand-made pair of MIDI-to-XLR adapter cables. I remembered QLab had some kind of drop-down menu of MIDI control sequences already written for you -- I opened up my fully-registered copy of QLab 1.0 and looked around.
The board didn't seem to be seeing the commands, but then after I'd tapped at the button a few times (trying different options) I noticed the lights had changed. Turns out you had to deliberately press and hold the "send a message now" button within the QLab interface before it would spit out the full-length MSC.
Now, since it was already in my bag, I pulled out my Arduino-based MIDI message generator and the XBee-modified Staple's Easy Button. And now I could trigger the "Go" button for the next lighting cue from basically anywhere in the theater.
It's a hack, and a bit of a chain; the inside of the Easy Button currently holds not just the XBee node but is wasting a perfectly good USB Explorer as a break-out board. I haven't gotten around to putting in a new breakout board (and boost converter) as replacements. When the Easy Button is pressed, the XBee node sends a radio message with the changed status of pin D0. The receiving node toggles the output level of its pin D0 in response, and the Arduino it is connected to detects this as a switch closed (aka +v is present on a pin that is otherwise pulled to ground. Or is it the other way around?) The Arduino, which at least is in a nice box, debounces the "switch/sensor" input, creates a NoteOn event, and sends it out the serial port at 31250 BAUD. A standard MIDI connector picks this up, creates a newly formatted message via USB, and this triggers a cue within QLab. The QLab cue creates a new MIDI event -- an MSC "Go" command -- and shoots that OUT the same USB MIDI adapter. That runs through two adapter cables and sixty feet of audio snake to reach the back of the lighting console.
But, the point of the demonstration is, this worked. And more importantly than that, it worked off-the-shelf. I had the components already, and I didn't even have to go inside via the USB connection and write new code to one or more of the components to do this particular task (which, if I had, could have removed the laptop and its MIDI adapter from the chain of connections).
And this is what I've been striving at with all of my theatrical gadgets; to have things that I can pull out of the gig bag and hook up in a few minutes to solve a problem. Or to so something new that hasn't been done before, thus enhancing the fun and the creative options of a show.
And today I needed to do a touch-up focus on stage and I had no assistant to run the board. At least this theater has an RFU (Remote Focus Unit), but it was still faster to write a couple of cues, each containing just the system I needed to touch up, then hook up my Wireless Easy Button again. And then I could move from light to light without having to run back to the board each time.
Thursday, May 10, 2012
Feeping Creaturitis
Physiologists are continuing to refine just how they feel about stretching. I know that back when I was doing some serious cross-country running, I did not believe in stretching while my muscles were cold. Instead I would warm up by jogging in place, shallow bends, and so forth. And I'd stretch out following a run, because it seemed to me I cramped up less if I eased my muscles down to rest again. Except even when I converted to treadmill running, I found a better cool-down was using the Treadwall my gym had for far too short a time.
Anyhow...stretching may or may not damage your body, but stretch goals can damsure hurt a project.
One of the basic -- and hardest -- elements of good engineering is parameterization. You have to identify the problem at a larger level than "how do I best make a machine do this" or, worse, "how can I make this machine I happen to have do this?" Good enough parameterization can ofter parameterize the engineering itself right out of the game; "Oh, I guess there IS a commercial machine that already does it well enough," or "Well, it doesn't look like anyone would even use this application."
Which is all a round-about way of getting to my current work with the BlinkM. This started with bottom-up practice; there is a device which puts on one very small footprint PCB a bright RGB LED and an AVR. And it is configured out of the box to upload and run both commands and programs via an I2C serial port. So I started with a solution in search of an application; could this product be of any use in addressing the various kinds of controllable lights I've identified a need for in live theater?
I wasted a fair amount of time in trying to implement a minimum-component serial-over-wireless link for these devices before I finally got around to doing the higher-level parameterization. And one thing leapt out at me; there was no identified theatrical application for which full serial communication was necessary.
Of course the basic problem in this kind of geekery for theater is that you are not just replacing existing solutions with more elegant ones. You are trying to identify solutions for what no-one has identified as a problem before. Few people have come up and said "In our production of 'Gypsy,' it would be very useful if Electra's boob lights would light every time she bumped." Fewer still have come up and said "In our production of 'Godot,' it would be great if the spectral plot of the wind sound altered in response to how close Estragon gets to the bush, tree, shrub...whatever the heck that thing is."
In the first example, someone might have imagined the effect, but assumed it was technically unfeasible and thus never brought it up in production or design meetings. In the latter example, no-one had even envisioned the potential of dynamic alteration of the soundscape of the play via sensor networks and DSP.
Actually, honestly, by the time the resident geek is even consulted even easily solvable problems have already been "solved" either by changing the blocking, or altering the set, or using one of the venerable theater tools like fishline.
(Although sometimes there is the flip side -- a company like Berkeley Rep, that might ask for "blood to come pouring out of the giant translucent eye"; a problem that required electro-pneumatics and some kitchen chemistry to solve.)
The point being, the set of known applications is much, much smaller than the total set of solutions for what had never previously been identified as potentially soluable problems!
Anyhow. The one BlinkM-derivative application I am absolutely sure of is the candle or lantern. Because I've done so many of them in the past.
My best lantern solution was a half-dozen grain-of-wheat bulbs or amber LEDs, wrapped with diffusion from the lighting supply closet, and a 9V battery pack stuck in the original fuel reservoir. The most elegant switch I made was wired to the wick adjustment wheel. The most intriguing one I saw, however, was at Berkeley Rep, which used an R/C model car servo to turn a potentiometer, when thus allowed the lamp to be turned off remotely and on cue.
Which allows this application to be readily parameterized; "A battery-powered, fully portable simulated lantern light that will fit into a prop lantern, that is bright enough to be visible under stage lights, and that can be turned on and off remotely -- preferably from within lighting cues (aka it becomes a wireless DMX device)."
The first round of stretch goals would be to allow a range of stable intensities (not just fade up, fade out), and to flicker.
The next round of stretch goals says, since this is a potential "drop in any light" solution -- aka candles, small torches, even a wall sconce on a portable set piece -- we should add control of the color, and control of the range of the flicker effect.
I can't actually imagine any other application so specific and well-described. I can think of, say, a crystal ball (such as is used by the Witch in "Wizard of Oz." Or a Vial of Mysterious Liquid that glows from within (it might even be Atomic!)
But it seems plausible that whatever the application, the very process of being small, battery powered, not that bright, and installed in a prop, seems to imply that the wanted behavior for each application can be worked out easily before installation. Which is to say -- it doesn't have to be re-programmed over the air.
And in many, many applications, it makes more sense to have a button in the hands of the actor than it does a wireless connection to the lighting console.
So throw out the attempts to create a serial link. Instead, as the BlinkM board makes available one analog input of the AVR, simply set it to be controlled via a resistor ladder. As many different pre-programmed behaviors as the resolution of the analog in port allows can be called up with nothing more complicated than a button.
For the lantern, the most sensible is two commands; fade to lantern-on flicker loop, and fade to all LEDs off.
And if you do desire wireless control? Why, then, you can use the pin-passing mode of a pair of XBee nodes to pass an analog value. Assuming you can work out the balance between the 4.5V nominal of the BlinkM and the 3.3V supply desired for the XBee, you should be able to press a button (or run a line of code on a host AVR) and have the XBee network pass that button value wirelessly to the lantern.
So here I am coding. I am still using microseconds() to keep the size of the PWM loop consistent, but even though it is a lot more work I may want to switch to an interrupt routine based on one of the ATtiny45's two hardware timers. The basic idea is straight-forward; for each loop through the PWM loop, the LEDs are all switched off, then at set values from the first step to the last step of the loop they are switched on, thus creating a duty cycle varying from (basically) 0% to 100%.
An added wrinkle is that human perception is roughly log, not linear, thus it makes sense to either include a gamma correction calculation or look-up table prior to determining the duty cycle. This has the advantage of meaning you need less resolution (fewer steps) in the loop in order to maintain resolution (visible changes in brightness) at the lowest end of the scale.
The simplest possible shell code to this just feeds three numbers into the PWM loop; one each for R, G, and B.
The next iteration is a fade-to. For this, we have the known RGB state, and a target RGB state, and a rate (the number of program steps between one and the other). At this point the central statement looks more like float current_value = (old_value - new_value/rate); if (timer > gamma_table[int (float current_value)) { LED = high; }
Which is to say; we need to use a floating-point variable in order to correctly track fractions of increase, convert it to Int to find the next whole-number step, and feed that into the look-up table in order to find the moment the LED needs to switch on.
But what of, say, a pulse like the sleep light on a computer? This alternates between two steps; fadeTo on, and fadeTo out. Or, rather, fade to, in alternating order, two defined RGB values. So the program flags when all fade steps are completed, and then grabs the new target value and re-commenses.
Except. It is easy to imagine a program in which more than two states follow. A traffic-light pattern, say. So rather than make an arbitrary list, instead we will establish an array of RGB values, and test on the completion of each fade loop if there is an array element in the ++ location. And, of course, since not all steps would necessarily be the same length, the fourth element in the array is unique fade rates for each target.
And now the goals are getting reeeeaaallly stretchy. Because it is easy enough to imagine having to fade from one multi-element loop to another. In the simplest case, imagine a flickering candle slowly fading. You don't want to freeze the flicker and fade from whatever the current color is. Instead, you want to continue running the flicker program whilst changing ALL of the values in an incremental way according to the external fade loop.
And since you are being silly already, why not ask how you would go from a steady pulsing white light to a steady pulsing RED light -- without a stutter? Well, by putting in the command that says "fade to new pulse" a flag that requires the new loop to synchronize with the old loop.
And at some point you realize the iterations become endless -- that there is always some scenario you can imagine by which a multi-stage program could be cross-faded with another multi-stage program.
And that's the point at which stretching really starts to hurt. Better to get back to the known basics -- things like a flickering candle that can be dimmed -- and actually finish the code for that before adding on more and more bells and whistles.
Anyhow...stretching may or may not damage your body, but stretch goals can damsure hurt a project.
One of the basic -- and hardest -- elements of good engineering is parameterization. You have to identify the problem at a larger level than "how do I best make a machine do this" or, worse, "how can I make this machine I happen to have do this?" Good enough parameterization can ofter parameterize the engineering itself right out of the game; "Oh, I guess there IS a commercial machine that already does it well enough," or "Well, it doesn't look like anyone would even use this application."
Which is all a round-about way of getting to my current work with the BlinkM. This started with bottom-up practice; there is a device which puts on one very small footprint PCB a bright RGB LED and an AVR. And it is configured out of the box to upload and run both commands and programs via an I2C serial port. So I started with a solution in search of an application; could this product be of any use in addressing the various kinds of controllable lights I've identified a need for in live theater?
I wasted a fair amount of time in trying to implement a minimum-component serial-over-wireless link for these devices before I finally got around to doing the higher-level parameterization. And one thing leapt out at me; there was no identified theatrical application for which full serial communication was necessary.
Of course the basic problem in this kind of geekery for theater is that you are not just replacing existing solutions with more elegant ones. You are trying to identify solutions for what no-one has identified as a problem before. Few people have come up and said "In our production of 'Gypsy,' it would be very useful if Electra's boob lights would light every time she bumped." Fewer still have come up and said "In our production of 'Godot,' it would be great if the spectral plot of the wind sound altered in response to how close Estragon gets to the bush, tree, shrub...whatever the heck that thing is."
In the first example, someone might have imagined the effect, but assumed it was technically unfeasible and thus never brought it up in production or design meetings. In the latter example, no-one had even envisioned the potential of dynamic alteration of the soundscape of the play via sensor networks and DSP.
Actually, honestly, by the time the resident geek is even consulted even easily solvable problems have already been "solved" either by changing the blocking, or altering the set, or using one of the venerable theater tools like fishline.
(Although sometimes there is the flip side -- a company like Berkeley Rep, that might ask for "blood to come pouring out of the giant translucent eye"; a problem that required electro-pneumatics and some kitchen chemistry to solve.)
The point being, the set of known applications is much, much smaller than the total set of solutions for what had never previously been identified as potentially soluable problems!
Anyhow. The one BlinkM-derivative application I am absolutely sure of is the candle or lantern. Because I've done so many of them in the past.
My best lantern solution was a half-dozen grain-of-wheat bulbs or amber LEDs, wrapped with diffusion from the lighting supply closet, and a 9V battery pack stuck in the original fuel reservoir. The most elegant switch I made was wired to the wick adjustment wheel. The most intriguing one I saw, however, was at Berkeley Rep, which used an R/C model car servo to turn a potentiometer, when thus allowed the lamp to be turned off remotely and on cue.
Which allows this application to be readily parameterized; "A battery-powered, fully portable simulated lantern light that will fit into a prop lantern, that is bright enough to be visible under stage lights, and that can be turned on and off remotely -- preferably from within lighting cues (aka it becomes a wireless DMX device)."
The first round of stretch goals would be to allow a range of stable intensities (not just fade up, fade out), and to flicker.
The next round of stretch goals says, since this is a potential "drop in any light" solution -- aka candles, small torches, even a wall sconce on a portable set piece -- we should add control of the color, and control of the range of the flicker effect.
I can't actually imagine any other application so specific and well-described. I can think of, say, a crystal ball (such as is used by the Witch in "Wizard of Oz." Or a Vial of Mysterious Liquid that glows from within (it might even be Atomic!)
But it seems plausible that whatever the application, the very process of being small, battery powered, not that bright, and installed in a prop, seems to imply that the wanted behavior for each application can be worked out easily before installation. Which is to say -- it doesn't have to be re-programmed over the air.
And in many, many applications, it makes more sense to have a button in the hands of the actor than it does a wireless connection to the lighting console.
So throw out the attempts to create a serial link. Instead, as the BlinkM board makes available one analog input of the AVR, simply set it to be controlled via a resistor ladder. As many different pre-programmed behaviors as the resolution of the analog in port allows can be called up with nothing more complicated than a button.
For the lantern, the most sensible is two commands; fade to lantern-on flicker loop, and fade to all LEDs off.
And if you do desire wireless control? Why, then, you can use the pin-passing mode of a pair of XBee nodes to pass an analog value. Assuming you can work out the balance between the 4.5V nominal of the BlinkM and the 3.3V supply desired for the XBee, you should be able to press a button (or run a line of code on a host AVR) and have the XBee network pass that button value wirelessly to the lantern.
So here I am coding. I am still using microseconds() to keep the size of the PWM loop consistent, but even though it is a lot more work I may want to switch to an interrupt routine based on one of the ATtiny45's two hardware timers. The basic idea is straight-forward; for each loop through the PWM loop, the LEDs are all switched off, then at set values from the first step to the last step of the loop they are switched on, thus creating a duty cycle varying from (basically) 0% to 100%.
An added wrinkle is that human perception is roughly log, not linear, thus it makes sense to either include a gamma correction calculation or look-up table prior to determining the duty cycle. This has the advantage of meaning you need less resolution (fewer steps) in the loop in order to maintain resolution (visible changes in brightness) at the lowest end of the scale.
The simplest possible shell code to this just feeds three numbers into the PWM loop; one each for R, G, and B.
The next iteration is a fade-to. For this, we have the known RGB state, and a target RGB state, and a rate (the number of program steps between one and the other). At this point the central statement looks more like float current_value = (old_value - new_value/rate); if (timer > gamma_table[int (float current_value)) { LED = high; }
Which is to say; we need to use a floating-point variable in order to correctly track fractions of increase, convert it to Int to find the next whole-number step, and feed that into the look-up table in order to find the moment the LED needs to switch on.
But what of, say, a pulse like the sleep light on a computer? This alternates between two steps; fadeTo on, and fadeTo out. Or, rather, fade to, in alternating order, two defined RGB values. So the program flags when all fade steps are completed, and then grabs the new target value and re-commenses.
Except. It is easy to imagine a program in which more than two states follow. A traffic-light pattern, say. So rather than make an arbitrary list, instead we will establish an array of RGB values, and test on the completion of each fade loop if there is an array element in the ++ location. And, of course, since not all steps would necessarily be the same length, the fourth element in the array is unique fade rates for each target.
And now the goals are getting reeeeaaallly stretchy. Because it is easy enough to imagine having to fade from one multi-element loop to another. In the simplest case, imagine a flickering candle slowly fading. You don't want to freeze the flicker and fade from whatever the current color is. Instead, you want to continue running the flicker program whilst changing ALL of the values in an incremental way according to the external fade loop.
And since you are being silly already, why not ask how you would go from a steady pulsing white light to a steady pulsing RED light -- without a stutter? Well, by putting in the command that says "fade to new pulse" a flag that requires the new loop to synchronize with the old loop.
And at some point you realize the iterations become endless -- that there is always some scenario you can imagine by which a multi-stage program could be cross-faded with another multi-stage program.
And that's the point at which stretching really starts to hurt. Better to get back to the known basics -- things like a flickering candle that can be dimmed -- and actually finish the code for that before adding on more and more bells and whistles.
Saturday, April 28, 2012
Small Update
I'm in the middle of a six-performance weekend and what little free hours I have are being consumed in repairing microphone elements and re-writing some sound cues.
(Actually, changing over from QLab to VSamp for some camera shutter and chop-socky effects I am improvising live during performance. I was doing them in QLab using the ability to hot-fire a sound from computer key or MIDI keyboard, but putting them in VSamp -- a low-profile, shareware software sampler for the Mac -- means I can play multiple "notes" as fast as my fingers can move on the keyboard.)
Anyhow.
My XBee Pro came in the mail, but so did a BlinkM. I have to take apart a prop that is featured in the current show in order to interrogate the XBee node inside it and then program and replace it with the higher-power Pro. So I'm holding off on that until after this weekend's performances!
Which gives me time to mess with the BlinkM.
First impressions; tiny form factor, no power conditioning needed (well, within the somewhat narrow range of voltages). Bright, but that's on the scale of small LEDs; I think it is just barely bright enough to do a candle effect on stage (stage lights are fierce competition). Fortunately, there is the MaxM (or you could break out the PWM lines and Power-MOSFET them into some of those 5-watt monsters they make now.)
In the raw form, you use an Arduino as a serial-to-I2C converter. I had a bit of an issue when my current version of the Arduino IDE wouldn't run the BlinkM communicator, and the latest version of the Arduino IDE wouldn't run on my computer, but regressing to version 0023 solved both problems.
The programmer/sequencer is cute and runs smoothly but is painful to use. Most of the kinds of things one would want to do would be smooth fading from color to color (or color to out). What you'd want is the ability to express those mathematically, or graphically in the form of spline curves. Instead you have a 30-step piano-roll that you fill in manually. Fun to play with, but hard to construct smooth fade curves on.
The worse problem, from my perspective, is that although turning two of the PWM outputs on an Arduino into a I2C interface is simple enough, and I2C protocol allows multiple units on the same line, and the built-in instruction set is large and well thought-out, most of the applications that spring to my mind would be better suited by 8-n-1.
Such as connecting to an XBee to allow streaming of new instructions via wireless link.
Well, with the extremely simple online instructions and my Adafruit "TinyISP" it took only a few minutes to upload a new program from the Arduino IDE. This wipes out the installed boot, but as far as I know it doesn't install an Arduino-type bootloader -- I'll probably have to use the ISP to continue programming. But aside from that mechanical detail, the experience becomes exactly like putting code on an Arduino.
Some reading of the schematic from ThinkM (and comparing it with the ATtiny45 datasheet from ATmel!) shows that -- given that the ATtiny45 only has two PWM pins -- this is controlling the three LEDs by strobing three digital pins. The way the BlinkM breakout is built, one unused digital I/O is brought out to the front of the board, as is a copy of the PWM/I/O pin used for the blue LED.
Anyhow...there are enough pins being brought out to implement soft serial, which is my next experiment. In the meanwhile, though, I'm writing up my own version of a code for the thing.
Or, rather, working on how to best use program cycles to handle the different and changing pulse-width requirements of three different LEDs simultaneously -- a task that really is better suited to the internal timers and PWM outputs. At the moment my experimental code is running through a 0-100 integer loop, and turning each LED off at the appropriate "slice" along that loop, from 1% duty cycle (a barely visible flicker) to 100%. However, my current code appears to be running so slowly the maximum smooth fade (aka incrementing one "slice" with every pass through the loop) consumes around half a second.
Which sounds like a deep error in my test code -- at 8 MHz, even running on compiled C code the RISC chip (which executes most operations in a single clock cycle) should be WAY faster than that (according to my calculations, in fact, over 1,000 times faster).
Grafting on the entire front end of the BlinkM is more than I want to handle. But, fortunately, I think I can make do with a limited capability to either go to select colors, or to go to various off-line programmed "useful" sequences (like candle-light). I may, though, now that I think of it, add to the instruction set something like "RandomColor( baseR, baseG, baseB, rangeR, rangeG, rangeB, rate )."
Once I get the basic PWM and fade code working right, that is!
(Actually, changing over from QLab to VSamp for some camera shutter and chop-socky effects I am improvising live during performance. I was doing them in QLab using the ability to hot-fire a sound from computer key or MIDI keyboard, but putting them in VSamp -- a low-profile, shareware software sampler for the Mac -- means I can play multiple "notes" as fast as my fingers can move on the keyboard.)
Anyhow.
My XBee Pro came in the mail, but so did a BlinkM. I have to take apart a prop that is featured in the current show in order to interrogate the XBee node inside it and then program and replace it with the higher-power Pro. So I'm holding off on that until after this weekend's performances!
Which gives me time to mess with the BlinkM.
First impressions; tiny form factor, no power conditioning needed (well, within the somewhat narrow range of voltages). Bright, but that's on the scale of small LEDs; I think it is just barely bright enough to do a candle effect on stage (stage lights are fierce competition). Fortunately, there is the MaxM (or you could break out the PWM lines and Power-MOSFET them into some of those 5-watt monsters they make now.)
In the raw form, you use an Arduino as a serial-to-I2C converter. I had a bit of an issue when my current version of the Arduino IDE wouldn't run the BlinkM communicator, and the latest version of the Arduino IDE wouldn't run on my computer, but regressing to version 0023 solved both problems.
The programmer/sequencer is cute and runs smoothly but is painful to use. Most of the kinds of things one would want to do would be smooth fading from color to color (or color to out). What you'd want is the ability to express those mathematically, or graphically in the form of spline curves. Instead you have a 30-step piano-roll that you fill in manually. Fun to play with, but hard to construct smooth fade curves on.
The worse problem, from my perspective, is that although turning two of the PWM outputs on an Arduino into a I2C interface is simple enough, and I2C protocol allows multiple units on the same line, and the built-in instruction set is large and well thought-out, most of the applications that spring to my mind would be better suited by 8-n-1.
Such as connecting to an XBee to allow streaming of new instructions via wireless link.
Well, with the extremely simple online instructions and my Adafruit "TinyISP" it took only a few minutes to upload a new program from the Arduino IDE. This wipes out the installed boot, but as far as I know it doesn't install an Arduino-type bootloader -- I'll probably have to use the ISP to continue programming. But aside from that mechanical detail, the experience becomes exactly like putting code on an Arduino.
Some reading of the schematic from ThinkM (and comparing it with the ATtiny45 datasheet from ATmel!) shows that -- given that the ATtiny45 only has two PWM pins -- this is controlling the three LEDs by strobing three digital pins. The way the BlinkM breakout is built, one unused digital I/O is brought out to the front of the board, as is a copy of the PWM/I/O pin used for the blue LED.
Anyhow...there are enough pins being brought out to implement soft serial, which is my next experiment. In the meanwhile, though, I'm writing up my own version of a code for the thing.
Or, rather, working on how to best use program cycles to handle the different and changing pulse-width requirements of three different LEDs simultaneously -- a task that really is better suited to the internal timers and PWM outputs. At the moment my experimental code is running through a 0-100 integer loop, and turning each LED off at the appropriate "slice" along that loop, from 1% duty cycle (a barely visible flicker) to 100%. However, my current code appears to be running so slowly the maximum smooth fade (aka incrementing one "slice" with every pass through the loop) consumes around half a second.
Which sounds like a deep error in my test code -- at 8 MHz, even running on compiled C code the RISC chip (which executes most operations in a single clock cycle) should be WAY faster than that (according to my calculations, in fact, over 1,000 times faster).
Grafting on the entire front end of the BlinkM is more than I want to handle. But, fortunately, I think I can make do with a limited capability to either go to select colors, or to go to various off-line programmed "useful" sequences (like candle-light). I may, though, now that I think of it, add to the instruction set something like "RandomColor( baseR, baseG, baseB, rangeR, rangeG, rangeB, rate )."
Once I get the basic PWM and fade code working right, that is!
Wednesday, April 25, 2012
Not So Easy
Well, I wired my Easy Button with an XBee. After all that hassling over reading serial data in Processing, I realized it was more appropriate for this project to use the simpler I/O Line Passing Mode of the 802.15.4 "Series 1" XBee nodes.
The way I/O line passing works, the status of any enabled digital or analog inputs on the transmitter will be echoed by the corresponding digital pins or PWM pins on the receiver.
At that point it was an easy matter to stick the programmed XBee node inside the Easy Button, and wire it to the original button.
I experimented a bit with power supplies as well. The XBee nodes are designed to run on 3.3V although the I/O pins are 5V compatible (which is handy for interfacing with micros with a 5V bus). They are radios, and thus sensitive to voltage fluctuations, but according to the datasheet they can handle a range of 2.8V to 3.4V -- this meant I could use the nominal 3.0V of the pair of AAA batteries the Easy Button was already provisioned for.
(Alternatives ranged from sticking a hard-to-get to battery pack inside to installing a complete charge circuit for a lithium-poly battery. However, the LiPo's run as high as 4.1V when fully charged, meaning to protect the XBee you'd need to add a voltage regulator. The regulator provided on the commonly available XBee breakouts from Sparkfun and Adafruit drop about a volt, however, meaning the usable charge of the LiPo is severely limited. I have ordered a low-dropout regulator from Digikey, but I'm not sure I want to spend the time wiring up an LDO as well as LiPo charge manager!)
(Yet another alternative is to use a 3.3V boost power converter, that ramps up and regulates the output of a pair of AAA cells...all the way down to the output of one nearly-discharged cell (something like 0.8 volts) before it finally gives up. I have one of these on order as well!)
Oh, and I already had the other end:
My venerable Arduino-based MIDI event generator had just finished a show connected to the Easy Button -- at that time, the button was hard-wired via the terminal block you can see in the photograph. Since the terminal block presents both +V and ground, it was simple to power an XBee Explorer off it (which has an onboard 5V to 3.3V regulator), and when my pin D0 is pulled low on the transmitter (internal resistors pull the inputs high), it pulls one of the digital pins of the Arduino low via the XBee link.
And it all worked great on the bench, and I soldered up everything and closed up the button.
And then I did the plugs-out test and it failed.
Battery usage was fine...it went past twelve hours on a fresh-charged pair. But the transmission was very much line-of-sight; at ten feet, it couldn't even transmit through my own body if I held it behind my back.
This is as against the original proof-of-concept, when I got 120 feet of range through several set-pieces. The primary flaw appears to be the nature of the I/O Line Passing Mode itself. It appears to transmit only when the status of the digital input line changes (which makes for great battery life, at least). This means that not only is there no re-try, but the I/O pins can lose synchronization and have to be "reminded." Which is NOT good behavior for a theatrical effect.
However. I've gone back into the transmitter and set IR to FF -- that is, forcing the node to take a sample of its inputs (and transmit the results) every 255 milliseconds. And I'm reading up on sleep modes, which should accomplish the same thing with a better power economy. This has increased the robustness of the transmission enough to where I can transmit reliably at 20 feet and through one wall. I probably need to juggle settings on the receiver as well to make sure it resets the outputs within a quarter-second of any break in radio contact.
I don't know yet if the batteries can handle this greater transmit volume, but as of this moment I've been operating for one hour and 7 minutes on the same pair of batteries.
I believe the more robust option is going to have to be full serial transmission, for which I need to add an AVR (and which means I finally have to learn how to use the UART on an ATtiny). Other options are going to regulated power (and supplying the transmitter with the full designed 3.3 volts), using wire antenna instead of chip antenna XBee models, and upgrading to XBee Pro (which have much greater output power and spec at over twice the effective range).
In the meanwhile, I could try to use this current unit, by locating the receiver close to the stage. But the show has been rehearsed already with a visual sound cue instead of an actor-operated one, and there's no real point to changing now (and even less reason to introduce the risk of new technology).
The batteries made it past ten hours in the new mode. On further reading, and tentatively confirmed in testing, when IR is set at other than the default of "0" the node does wait for an ACK and re-try up to three times if it doesn't get one. And I lowered my sample interval to about 100 millseconds. And also set a 100 millisecond automatic reset interval on the receiver's pins using the Tn command so if it loses contact with the transmitter it won't "hang."
In the theater, it made it from the stage to the back of the house but only when there was a clear line of sight. Next step, then, is to swap out the existing node with a Pro node instead.
ADDENDUM TWO: with an XBee Pro node installed, I was able to achieve reliable trigger from stage to sound booth. In fact, it triggered semi-reliably from all the way back in the dressing room. My first test was actually from orchestra pit to lobby -- I had the parts spread out on the Concessions counter while I was putting in the Pro node, and I draped a wireless mic over my laptop computer then went down and listened to the computer through the band vocal monitor!
As I said in an earlier post (Theater Should Not be a Hackerspace) although it works and the actor admired it very much, it will not be used in this show. We are already rehearsed with taking the sound cue manually. But now the button is ready for any application down the road where I need to hand a button to an actor or band member or Stage Manager to trigger an event wireless-ly.
The way I/O line passing works, the status of any enabled digital or analog inputs on the transmitter will be echoed by the corresponding digital pins or PWM pins on the receiver.
At that point it was an easy matter to stick the programmed XBee node inside the Easy Button, and wire it to the original button.
I experimented a bit with power supplies as well. The XBee nodes are designed to run on 3.3V although the I/O pins are 5V compatible (which is handy for interfacing with micros with a 5V bus). They are radios, and thus sensitive to voltage fluctuations, but according to the datasheet they can handle a range of 2.8V to 3.4V -- this meant I could use the nominal 3.0V of the pair of AAA batteries the Easy Button was already provisioned for.
(Alternatives ranged from sticking a hard-to-get to battery pack inside to installing a complete charge circuit for a lithium-poly battery. However, the LiPo's run as high as 4.1V when fully charged, meaning to protect the XBee you'd need to add a voltage regulator. The regulator provided on the commonly available XBee breakouts from Sparkfun and Adafruit drop about a volt, however, meaning the usable charge of the LiPo is severely limited. I have ordered a low-dropout regulator from Digikey, but I'm not sure I want to spend the time wiring up an LDO as well as LiPo charge manager!)
(Yet another alternative is to use a 3.3V boost power converter, that ramps up and regulates the output of a pair of AAA cells...all the way down to the output of one nearly-discharged cell (something like 0.8 volts) before it finally gives up. I have one of these on order as well!)
Oh, and I already had the other end:
My venerable Arduino-based MIDI event generator had just finished a show connected to the Easy Button -- at that time, the button was hard-wired via the terminal block you can see in the photograph. Since the terminal block presents both +V and ground, it was simple to power an XBee Explorer off it (which has an onboard 5V to 3.3V regulator), and when my pin D0 is pulled low on the transmitter (internal resistors pull the inputs high), it pulls one of the digital pins of the Arduino low via the XBee link.
And it all worked great on the bench, and I soldered up everything and closed up the button.
And then I did the plugs-out test and it failed.
Battery usage was fine...it went past twelve hours on a fresh-charged pair. But the transmission was very much line-of-sight; at ten feet, it couldn't even transmit through my own body if I held it behind my back.
This is as against the original proof-of-concept, when I got 120 feet of range through several set-pieces. The primary flaw appears to be the nature of the I/O Line Passing Mode itself. It appears to transmit only when the status of the digital input line changes (which makes for great battery life, at least). This means that not only is there no re-try, but the I/O pins can lose synchronization and have to be "reminded." Which is NOT good behavior for a theatrical effect.
However. I've gone back into the transmitter and set IR to FF -- that is, forcing the node to take a sample of its inputs (and transmit the results) every 255 milliseconds. And I'm reading up on sleep modes, which should accomplish the same thing with a better power economy. This has increased the robustness of the transmission enough to where I can transmit reliably at 20 feet and through one wall. I probably need to juggle settings on the receiver as well to make sure it resets the outputs within a quarter-second of any break in radio contact.
I don't know yet if the batteries can handle this greater transmit volume, but as of this moment I've been operating for one hour and 7 minutes on the same pair of batteries.
I believe the more robust option is going to have to be full serial transmission, for which I need to add an AVR (and which means I finally have to learn how to use the UART on an ATtiny). Other options are going to regulated power (and supplying the transmitter with the full designed 3.3 volts), using wire antenna instead of chip antenna XBee models, and upgrading to XBee Pro (which have much greater output power and spec at over twice the effective range).
In the meanwhile, I could try to use this current unit, by locating the receiver close to the stage. But the show has been rehearsed already with a visual sound cue instead of an actor-operated one, and there's no real point to changing now (and even less reason to introduce the risk of new technology).
The batteries made it past ten hours in the new mode. On further reading, and tentatively confirmed in testing, when IR is set at other than the default of "0" the node does wait for an ACK and re-try up to three times if it doesn't get one. And I lowered my sample interval to about 100 millseconds. And also set a 100 millisecond automatic reset interval on the receiver's pins using the Tn command so if it loses contact with the transmitter it won't "hang."
In the theater, it made it from the stage to the back of the house but only when there was a clear line of sight. Next step, then, is to swap out the existing node with a Pro node instead.
ADDENDUM TWO: with an XBee Pro node installed, I was able to achieve reliable trigger from stage to sound booth. In fact, it triggered semi-reliably from all the way back in the dressing room. My first test was actually from orchestra pit to lobby -- I had the parts spread out on the Concessions counter while I was putting in the Pro node, and I draped a wireless mic over my laptop computer then went down and listened to the computer through the band vocal monitor!
As I said in an earlier post (Theater Should Not be a Hackerspace) although it works and the actor admired it very much, it will not be used in this show. We are already rehearsed with taking the sound cue manually. But now the button is ready for any application down the road where I need to hand a button to an actor or band member or Stage Manager to trigger an event wireless-ly.
Friday, March 30, 2012
Buzz, Buzz
Still tinkering with the XBees. Progress is slow and I'm feeling more stupid than usual. I do have the excuse of an ongoing show in one town and a load-in in another town.
Yesterday was typical, though. Wasn't able to get the XBee to respond to my desktop, thought I had another Java issue, in the process of re-installing Java realized I really needed to do a round of file back-ups and general cleaning on three different machines...and after several hours of that, more driver installs, and change back to the previous version of Processing...realized it was a bad USB cable all along.
I've been trying to interpret the signals from the XBee, which are sent as strings of different lengths. I'm trying to parse them using Processing's string functions and it is NOT going well. Whether it is due to Processing considering string handling beneath it (the manual gives short shrift to the subject), the difficult-to-decipher documentation on the XBee, or that my own brain is not quite running right this week...
The easiest way to use XBees is as a transparent serial link. With two XBees in the factory defaults, and serial-to-USB connections to them (via say the XBee Explorer USB, which uses the perennial FTDI chip to produce a virtual COM port on the USB hub -- don't forget to install the FTDI drivers!) you can type into a terminal application on one computer and the text will appear on the other.
After struggling with the broken Java implementation of MIDI on OSX 10.4 through 10.5, I was able to get a proof-of-concept working via a nice little piece of freeware called the Hairless MIDI to Serial Bridge. For whatever weird reason, Processing uses -128 to 128 as the range of values for the Byte data format, so to get something like 144 (the decimal value of the "NoteOn" command) I had to do some odd tinkering.
But it all worked well enough. I ran a Processing sketch on my laptop that would spit out a serial string on command, and Hairless was on the slave computer, hooked up as a virtual MIDI input to QLab. And the actual serial connection between the two machines was via XBee modules plugged into the USB ports. Using just Series 1 modules with chip antennas I was able to fire off a sound cue even with the sound computer at the back of the house (in the lighting booth) and my laptop all the way upstage behind the scenery.
And this will...work. It means intelligence on the sending end. My preference was that the transmitter would be "dumb," merely reporting on the status of the sensors or other inputs connected to it, and that the massaging of the data and creation of a MIDI or DMX signal would happen on software running on the receiving computer. But to get this working either requires I learn how to program on CoreAudio itself (bypassing Java entirely) or wait until I am working on machines running 10.6 and above.
I can hack it now, though, by having an AVR do the listening to the sensors and conditioning of them, and constructing a viable serial string. The advantage to having intelligence at the sensor end is you can add battery status and other diagnostic and self-reporting functions. The downside is that trimming the sensor or otherwise changing the response means re-programming a micro. Or adding more hardware to the transmitter so you can interact with it directly (aka display, buttons, etc.)
The next show has a potential "Jeopardy" type button. Basically, that means sticking an XBee into the "Easy" button we are using right now to run QLab. I think a wireless "Easy" button is far too useful not to have around. I do want to build it with some sort of self-diagnostics, though, and of course I need the ability to change out the battery easily.
Probably the nicest solution is a custom fabbed board with an AVR, LED drivers, and perhaps a MAX power monitor chip on it. At the moment, I'd just waste an Arduino in order to get it up and functioning -- if there was room for an Arduino and shield inside the button. I'm not quite comfortable with serial I/O on a "naked" AVR yet.
Or move the intelligence. The XBee modules have several I/O ports that can be configured as digital inputs, ADCs, digital outs, or even PWMs. That was the big progress for this week; I finally got an XBee set up to where it would stand in idle mode without doing anything, but transmit a short burst whenever the status of a "sensor" (aka a button) on one pin changed.
The XBees are very much designed for remote monitoring applications and thus also have a variety of sleep modes, including sleep-until-pin and wake-every-n-seconds. In my current arrangement, I'm not sleeping the module at all; it is remaining in active state. It just isn't transmitting unless it has something to say.
I've already been working up a control surface for use with QLab -- several large buttons (maybe even arcade buttons) on a box that is powered from the USB connector and shows up (via the ATmel family of USB-compliant chips) as a MIDI device.
It is much easier to hook up the AT-USB chips as HID -- to make them emulate mice and keyboards. But there are a growing number of MIDI libraries for them now and I'm pretty sure I can get that working in a couple more weeks.
So in this format, the XBee is a dumb terminal; it sits around, reporting what it sees on its inputs. The micro sitting inside the control surface up in the sound booth interprets the sensor readings, adds them to the button inputs, and spits out MIDI-over-USB which is interpreted by QLab.
And, yes, using Max/MSP as a go-between, and upgrading to OSC (or just sending serial to Max and letting it deal with it) is a smarter solution. I'm just used to MIDI, I don't need to pay for it, and it will work with any host -- like the typical "someone supplied a laptop to run sound effects but they need it back after the show." Same for the XBee, really -- you can get cheaper radio links, but the cost on the XBees is as low as 17 bucks each and they handle all the error correction and multiple transmit tries and so forth for you.
Of course it doesn't stop there. The XBee has those outputs, after all. You can quite easily have them controlling relays or servos. But there is another trick that, again, leverages the insane intelligence available these days in very small packages.
For instance, by hooking it to a BlinkM. According to my reading, A BlinkM can be run off an unregulated 6v supply. The typical breakout for the XBee includes a 3.3V regulator. The UARTs on both devices are tolerant enough to operate across a range of voltages.
The end result would be a high-power RGB LED running a pre-programmed sequence that can change behavior (change sequences) by remote command.
I don't know how many shows I've had a candle or lantern on stage. The difficulties are both getting them bright enough to read against stage lighting, and being able to turn them on and off. On a production of "Lulu" some time back the solution was to glue a servo and radio (from an RC model car) to the shaft of a potentiometer inside the lamp. Thus, by using the RC controller you could dial the light up or down.
In this case, once you are in digital domain like this, the control impetus can come from anywhere...from the lighting board, for instance. So a lantern hanging in the barn will go up automatically with the lights, go out at the blackout, and flicker in a pleasing manner during the scene.
Or turn red and blue or flash like a police car, if you wanted it to. It's all right there in the remote controls.
In the upcoming show, I also have some electric collars. Mention was made during the production meeting of the light-up collars in the old Star Trek episode "The Gamesters of Triskellion." It is totally do-able with this sort of hardware. With lithium coin cells you could even make it self-contained (but an external battery pack would be nicer). Under direct control from the booth the collars could be radio controlled to light up and change color.
Waaaay too useful a tool not to try to put together.
Argh. The BlinkM is designed to take I2C. You can bitbang with an XBee to talk to a I2C device, but it is a complicated, slow, and power-hungry process. You could use the two PWM outputs of the XBee for a light controller (via some Darlington drivers) but this has several disadvantages; it wouldn't be a full RGB, you have to transmit constantly, and the only way to access these pins anyhow is via "echo mode" -- where one XBee is fed an analog value on several pins and the other mimics it out the corresponding pins.
You could include any of the family of AVR or Arduino clones to act as a translator from XBee to BlinkM, but that is adding to the cost, complexity, and size of the device, and is a bit silly besides; the BlinkM already HAS an AVR.
As it turns out, you can hack the BlinkM. You can even burn an Arduino-style bootloader and run it via the Arduino IDE, if you happen to have an ISP handy (which I do). At which point, you could write your own open version of the BlinkM software. Opening up the BlinkM also opens up the available I/O pins -- unfortunately it does not include the UART but you can use one of the soft serial libraries.
So, in short, it is still a plausible idea; to connect XBee to BlinkM, add a battery, and make an over-the-air programmable RGB light. It just requires a lot more work on the software side.
###
As I describe in a later post, once you've added the BlinkM to the list of compatible boards in the Arduino IDE, you can write modified Arduino code to it. And since one analog in port is uncovered (aka broken out to a pin), a trim pot or resistor ladder can be used as a multi-position switch. Presumably you could also use the PWM output of an XBee for this. My proof of concept, though, involved a digital output from the XBee and two resistors to toggle the BlinkM between two programmed states.
Of course, you could do soft serial. Or even write your own asynchronous unidirectional protocol; three "clicks" from the XBee means go to the blinking red program, four clicks means turn the LED off, etc. (Or, even more clever...an asynchronous PWM comparator; count the time from leading edge to falling edge and compare to the time from falling edge to leading edge. Then use the comparison as an analog value.)
Yesterday was typical, though. Wasn't able to get the XBee to respond to my desktop, thought I had another Java issue, in the process of re-installing Java realized I really needed to do a round of file back-ups and general cleaning on three different machines...and after several hours of that, more driver installs, and change back to the previous version of Processing...realized it was a bad USB cable all along.
I've been trying to interpret the signals from the XBee, which are sent as strings of different lengths. I'm trying to parse them using Processing's string functions and it is NOT going well. Whether it is due to Processing considering string handling beneath it (the manual gives short shrift to the subject), the difficult-to-decipher documentation on the XBee, or that my own brain is not quite running right this week...
The easiest way to use XBees is as a transparent serial link. With two XBees in the factory defaults, and serial-to-USB connections to them (via say the XBee Explorer USB, which uses the perennial FTDI chip to produce a virtual COM port on the USB hub -- don't forget to install the FTDI drivers!) you can type into a terminal application on one computer and the text will appear on the other.
After struggling with the broken Java implementation of MIDI on OSX 10.4 through 10.5, I was able to get a proof-of-concept working via a nice little piece of freeware called the Hairless MIDI to Serial Bridge. For whatever weird reason, Processing uses -128 to 128 as the range of values for the Byte data format, so to get something like 144 (the decimal value of the "NoteOn" command) I had to do some odd tinkering.
But it all worked well enough. I ran a Processing sketch on my laptop that would spit out a serial string on command, and Hairless was on the slave computer, hooked up as a virtual MIDI input to QLab. And the actual serial connection between the two machines was via XBee modules plugged into the USB ports. Using just Series 1 modules with chip antennas I was able to fire off a sound cue even with the sound computer at the back of the house (in the lighting booth) and my laptop all the way upstage behind the scenery.
And this will...work. It means intelligence on the sending end. My preference was that the transmitter would be "dumb," merely reporting on the status of the sensors or other inputs connected to it, and that the massaging of the data and creation of a MIDI or DMX signal would happen on software running on the receiving computer. But to get this working either requires I learn how to program on CoreAudio itself (bypassing Java entirely) or wait until I am working on machines running 10.6 and above.
I can hack it now, though, by having an AVR do the listening to the sensors and conditioning of them, and constructing a viable serial string. The advantage to having intelligence at the sensor end is you can add battery status and other diagnostic and self-reporting functions. The downside is that trimming the sensor or otherwise changing the response means re-programming a micro. Or adding more hardware to the transmitter so you can interact with it directly (aka display, buttons, etc.)
The next show has a potential "Jeopardy" type button. Basically, that means sticking an XBee into the "Easy" button we are using right now to run QLab. I think a wireless "Easy" button is far too useful not to have around. I do want to build it with some sort of self-diagnostics, though, and of course I need the ability to change out the battery easily.
Probably the nicest solution is a custom fabbed board with an AVR, LED drivers, and perhaps a MAX power monitor chip on it. At the moment, I'd just waste an Arduino in order to get it up and functioning -- if there was room for an Arduino and shield inside the button. I'm not quite comfortable with serial I/O on a "naked" AVR yet.
Or move the intelligence. The XBee modules have several I/O ports that can be configured as digital inputs, ADCs, digital outs, or even PWMs. That was the big progress for this week; I finally got an XBee set up to where it would stand in idle mode without doing anything, but transmit a short burst whenever the status of a "sensor" (aka a button) on one pin changed.
The XBees are very much designed for remote monitoring applications and thus also have a variety of sleep modes, including sleep-until-pin and wake-every-n-seconds. In my current arrangement, I'm not sleeping the module at all; it is remaining in active state. It just isn't transmitting unless it has something to say.
I've already been working up a control surface for use with QLab -- several large buttons (maybe even arcade buttons) on a box that is powered from the USB connector and shows up (via the ATmel family of USB-compliant chips) as a MIDI device.
It is much easier to hook up the AT-USB chips as HID -- to make them emulate mice and keyboards. But there are a growing number of MIDI libraries for them now and I'm pretty sure I can get that working in a couple more weeks.
So in this format, the XBee is a dumb terminal; it sits around, reporting what it sees on its inputs. The micro sitting inside the control surface up in the sound booth interprets the sensor readings, adds them to the button inputs, and spits out MIDI-over-USB which is interpreted by QLab.
And, yes, using Max/MSP as a go-between, and upgrading to OSC (or just sending serial to Max and letting it deal with it) is a smarter solution. I'm just used to MIDI, I don't need to pay for it, and it will work with any host -- like the typical "someone supplied a laptop to run sound effects but they need it back after the show." Same for the XBee, really -- you can get cheaper radio links, but the cost on the XBees is as low as 17 bucks each and they handle all the error correction and multiple transmit tries and so forth for you.
Of course it doesn't stop there. The XBee has those outputs, after all. You can quite easily have them controlling relays or servos. But there is another trick that, again, leverages the insane intelligence available these days in very small packages.
For instance, by hooking it to a BlinkM. According to my reading, A BlinkM can be run off an unregulated 6v supply. The typical breakout for the XBee includes a 3.3V regulator. The UARTs on both devices are tolerant enough to operate across a range of voltages.
The end result would be a high-power RGB LED running a pre-programmed sequence that can change behavior (change sequences) by remote command.
I don't know how many shows I've had a candle or lantern on stage. The difficulties are both getting them bright enough to read against stage lighting, and being able to turn them on and off. On a production of "Lulu" some time back the solution was to glue a servo and radio (from an RC model car) to the shaft of a potentiometer inside the lamp. Thus, by using the RC controller you could dial the light up or down.
In this case, once you are in digital domain like this, the control impetus can come from anywhere...from the lighting board, for instance. So a lantern hanging in the barn will go up automatically with the lights, go out at the blackout, and flicker in a pleasing manner during the scene.
Or turn red and blue or flash like a police car, if you wanted it to. It's all right there in the remote controls.
In the upcoming show, I also have some electric collars. Mention was made during the production meeting of the light-up collars in the old Star Trek episode "The Gamesters of Triskellion." It is totally do-able with this sort of hardware. With lithium coin cells you could even make it self-contained (but an external battery pack would be nicer). Under direct control from the booth the collars could be radio controlled to light up and change color.
Waaaay too useful a tool not to try to put together.
Argh. The BlinkM is designed to take I2C. You can bitbang with an XBee to talk to a I2C device, but it is a complicated, slow, and power-hungry process. You could use the two PWM outputs of the XBee for a light controller (via some Darlington drivers) but this has several disadvantages; it wouldn't be a full RGB, you have to transmit constantly, and the only way to access these pins anyhow is via "echo mode" -- where one XBee is fed an analog value on several pins and the other mimics it out the corresponding pins.
You could include any of the family of AVR or Arduino clones to act as a translator from XBee to BlinkM, but that is adding to the cost, complexity, and size of the device, and is a bit silly besides; the BlinkM already HAS an AVR.
As it turns out, you can hack the BlinkM. You can even burn an Arduino-style bootloader and run it via the Arduino IDE, if you happen to have an ISP handy (which I do). At which point, you could write your own open version of the BlinkM software. Opening up the BlinkM also opens up the available I/O pins -- unfortunately it does not include the UART but you can use one of the soft serial libraries.
So, in short, it is still a plausible idea; to connect XBee to BlinkM, add a battery, and make an over-the-air programmable RGB light. It just requires a lot more work on the software side.
###
As I describe in a later post, once you've added the BlinkM to the list of compatible boards in the Arduino IDE, you can write modified Arduino code to it. And since one analog in port is uncovered (aka broken out to a pin), a trim pot or resistor ladder can be used as a multi-position switch. Presumably you could also use the PWM output of an XBee for this. My proof of concept, though, involved a digital output from the XBee and two resistors to toggle the BlinkM between two programmed states.
Of course, you could do soft serial. Or even write your own asynchronous unidirectional protocol; three "clicks" from the XBee means go to the blinking red program, four clicks means turn the LED off, etc. (Or, even more clever...an asynchronous PWM comparator; count the time from leading edge to falling edge and compare to the time from falling edge to leading edge. Then use the comparison as an analog value.)
Subscribe to:
Comments (Atom)


