Mar 31
2017

Building Grove — interactive trees that come alive to your breath at Burning Man 2016

Grove is a set of 10 interactive biofeedback sculptures, a conversation between humans and trees. Each tree is made of steel tubes, thousands of LEDs, and custom breathing sensors.

Grove is a 2016 honorarium installation at Burning Man and is the second installation made by the group that made Pulse & Bloom in 2014. The core team is ten people: Saba Ghole, Shilo Shiv Suleman, Severin Smith, Steve Lyon, Hunter Scott, David Wang, Francis Coelho, Naeemeh Alavi, Luke Iseman, and myself, Samuel Clay. Grove was conceptualized by the artist Shilo Shiv Suleman as part of her larger series exploring nature, intimacy and technology called Beloved.

Here's how Grove works: you sit down at the base of a tree and a flower opens up in front of you as it senses your presence. As you breathe into a pink flower lit from inside, the tree fills up with your breath, rising white streams overtaking multiple slowly descending green lines. As you breathe, the tree shimmers with light as it becomes a nighttime desert oasis.

This post offers details on how this installation was built, from the custom circuit boards to the blooming flower and breathing sensors. You can access the complete source for Grove on GitHub.

Grove is made up of ten trees, each of which has its own breath sensor and set of two thousand LEDs across four 5 meter 144 LEDs/meter LED strips and 16 high current LEDs in the leaves. That takes both a lot of power to run and a lot of manpower to setup. This is what that setup looks like.

This photo and a few others below are by Daily Swa Laurel

How the electronics are made

Since the trees light up with your breath, we need to consider how the breath is sensed and then how the thousands of LEDs are driven.

These are five stages to making the electronics work together:

  1. Designing a breathing sensor
  2. Making the main control board
  3. Driving high current LEDs with a custom lighting board
  4. Writing the firmware
  5. Powering ten trees in Grove

1. Designing a breathing sensor

First things first, we need to focus on how to design a breathing sensor.

The plastic lotus flower assembly

This is the plastic lotus flower assembly built and designed by the NuVu team in Boston. It is supported by a 3 foot gooseneck that is tied to the base of the tree. This allows the person sitting down by the tree to pull the flower, that at this point is lit up and has magically opened itself, over to their mouth.

We placed a pair of passive IR motion sensors a few feet up the base of the tree looking out on both sides to detect when somebody sits down. That signal then directs the servo motor in the flower to open the flower up and make the LEDs inside the flower pulsate. This beckons the person to pull the flower over to them.

The flower has a proximity sensor embedded inside that is more commonly used by paper towel dispensers to detect hand movement. We used the Si1143, same as in the pulse sensor in Pulse & Bloom, to detect proximity. When we detect that a person is positioned directly in front of the flower, we then allow the breath measurements to light up the tree. Otherwise wind would take over and the tree would be constantly lit.

Above you can see the board that is placed inside the flower. There is a trumpet that fits directly over the board and directs airflow over the board. There are two slots in the board that allow your breath to flow over the hot-wire thermistors and out the back of the flower. Otherwise when you breathed into the flower, the flower would send your last breath back out.

The sensor board and the main board are driven and controlled by their own Teensy 3.2. I cannot say enough good things about the Teensy. We originally used an 8-bit Arduino Uno compatible ATmega328p chip but found the 8K memory limiting when we wanted to address thousands of LEDs at once.

The Teensy gives us plenty of head room and it was easy to get a GCC-based Makefile deployment setup so all we had to do was run one make command and the board was flashed and rebooted.

Detecting your breath

Now we get to the heart of the matter. To detect your breathing, we turn to the Modern Device wind sensor. They use what's called the "hot-wire" technique. This involves heating a couple of thermistors to a constant temperature and then measuring the electrical power required to maintain the heated thermistor at temperature as wind cools it down. The electrical power is directly proportional to the square of the wind speed.

You can buy anemometers for hundreds of dollars but we made our own following the Modern Device wind sensor. Hot-wire anemometers excel at low wind speed, which is pretty much the same speed as breathing.

While out on the playa we discovered that the plastic trumpet, which is used to channel your breath toward the sensor while keeping out wind, would cover a bit too much of the proximity sensor. We solved this problem by adding ultrasonic sensors (thanks to Frys for letting us buy out their collection of ultrasonic sensors on the way to the burn), pictured below on top of the orange trumpet.

We spent a couple days adding these ultrasonic sensors into the boards, soldering in the desert and making do with what we had. Thankfully we left a few pins open that we could then use for the new and improved proximity sensors.

You can explore the code we used to sense your breath on Github. There's a few parts that I'll highlight below in the writing the firmware section.

2. Making the main control board

This is the board that talks to the sensor board and the dispatcher board and gets all of the LED strips plugged into it. This is where the main battery connects to the tree and where power is distributed to each of the sensors and LEDs. This board also communicates with the dispatcher board up top in the leaves to make the high current LEDs fade between colors.

You'll notice on the left is an 8A DC-to-DC step-down voltage regulator that brought the 12V down to 5V needed for the LED strips and sensor board. The dispatcher board and its 16 high current LEDs needs the full 12V. We originally used a cheaper 3A voltage regulator, but it turns out that the number of LEDs we had on at any given time would regularly hit 5A, so we had to boost the voltage regulator.

You should also note that we used a Teensy here as well. There are some protections built into the circuit to prevent burning out the Teensy if we happen to short somewhere. Thankfully this didn't happen, but we made the Teensy removable and replaceable in case it did.

All of the wire-to-board connectors are MTA100 Series female and male pin headers. They are an inexpensive connector that you can crimp onto AWG 22 gauge wires and then easily insert into 0.1" male header pins. They even include an optional polarity wedge on the side so that you can ensure the wires are always plugged in the right direction, which is especially helpful when you have people helping you out and you want to ensure that no mistakes are even possible.

Crimping the MTA100 headers to the wires is pretty fast. You can use either a $30 insertion tool or a $100 crimping tool with a $163 MTA100-specific crimping head.

The best part about the MTA100 is that the wires are removable, so if you make a mistake you can just pull the wire out of the crimped head and try again.

Sometimes the connections wouldn't take and they would have to be re-crimped. This happened on a few of the trees. In the future what we would have done is add circuit testing to the mainboard. This would be an in circuit current measurement sensor. On boot we would turn each of the LEDs on individually, sensing whether or not the LEDs are actually drawing current. This way we can identify improperly crimped LEDs (or just plain old broken LEDs) and turn on a status LED on the board to quickly check.

3. Driving high current LEDs with a custom lighting board

That brings us to the dispatcher board on top. The goal is to have 16 individual 3W ultra-bright LEDs on top of the tree light up as each breath climbs to the top of the tree. These high current LEDs look like they are effectively breathing, turning your breath into the breath of an entire tree. It's a magical effect and to pull it off we're going to need a custom board just to handle these tricky LEDs.

Last time with Pulse & Bloom we didn't have a dispatcher board, instead relying on driving the LEDs with loose wires connected directly to PicoBucks. It was a mess. Here's the wiring diagram just for the 9 high current LEDs.

This means that there are over a hundred wires (6 per LED) per tree.

We decided instead to make a board that not only could handle all of this wiring mess but also allow us to easily change out the PicoBucks if they shorted, which is something that happened surprisingly often until we realized that the factory solder jobs on the LEDs themselves could sometimes short.

You can see from the schematic below that we simplified the setup by hooking up a set of four high current LEDs per PicoBuck. This let us individually address four sets of lights, giving the tree a mesmerizing pattern of lights that would slowly breathe on their own in green, turning blue when filled with "oxygen" from somebody sitting down and breathing into the breathing sensor at the base of the tree.

We also added protection fuses to the dispatcher board in case the LEDs did short. Since each LED draws a quarter amp at 12 V, we needed to make sure that they would be protected.

There is also a 12 channel SPI DAC. Since the PicoBucks need an analog signal as input to specify the PWM-enabled brightness on the LEDs, we couldn't easily send an analog signal up from the main board since it would have to traverse over 5 meters and be subject to massive voltage drop. Instead we sent a digital signal and converted it to analog on top. This was easy and inexpensive to do with the $4 BH2221FV chip from Rohm.

4. Writing the firmware

There are two boards that need their own firmware loaded on to their own Teensy. The sensor board and the main board can both be found on Github.

The sensor board

Let's go over a few of the more interesting functions that are used to light up your breath.

void loop() {
    readRemoteState();
    updateLEDs();
    updateFlowerServo();
    updatePIR();

    runWindAvgs();
    updateProx();

    evaluateState();
    runBreathDetection();
}

To begin, the sensor board runs through a tight loop looking for the proximity and PIR motion sensors to trigger so that it can begin to read breath measurements. If the proximity sensor is not firing then that means nobody is in front of the front and we should not be showing any of the breath measurements we might be reading due to wind.

If we didn't have a working proximity sensor (which happened to a few trees) then we would actually just be showing the Earth breathing, otherwise known as the wind. The Earth breathes differently than you or me. Instead of long pulses of hot air, the wind shows up as a sustained line of many tiny pulses, since it's both cooler and smoother than your breath.

Next we have a finite state machine determine which state we're in. The choices are neutral, motion detected, and proximity detected.

void evaluateState() {
    switch (overallState) {
        case STATE_NEUTRAL: {
            if (pirState == PIR_ON) {
                overallState = STATE_OPEN;
                openFlower();
            }
            break;
        }
        case STATE_OPEN: {
            long now = millis();
            if (now - openTimeoutLastEvent > openTimeout) {
                overallState = STATE_NEUTRAL;
                closeFlower();
            } else if (isProx()) {
                overallState = STATE_PROX;
            }
            break;
        }
        case STATE_PROX : {
            if (remoteState == STATE_NEUTRAL) {
                overallState = STATE_NEUTRAL;
                closeFlower();
            } else if (!isProx()) {
                overallState = STATE_OPEN;
                breathOff();
            } else {
                runBreathDetection();
            }
            break;
        }
    }
}

Using a FSM makes it easy to ensure that we always know where we are, even with three separate sensors that all trigger independently of each other, while ensuring that one does not cause a change in the tree without its predecessors.

void runWindAvgs() {
    long now = millis();
    if (now - lastWindSampleTime > windSampleInterval) {
        // Currently tuned to sample every 20ms roughly
        int raw = getRawWind();

        lowWindAvg = lowWindAvg * lowWindAvgFactor + raw * (1 - lowWindAvgFactor);
        highWindAvg = highWindAvg * highWindAvgFactor + raw * (1 - highWindAvgFactor);

        lastBpassWind = bpassWind;
        bpassWind = (int)(highWindAvg-lowWindAvg);
        windHistory[windHistoryIndex++] = bpassWind - lastBpassWind;

        if (windHistoryIndex >= WIND_HIST_LEN) windHistoryIndex = 0;

        lastWindSampleTime = now;
    }
}

We use the above runWindAvgs to average the raw readings and establish a moving average with hysteresis. This means that we want to intentionally avoid rapid switching of states, so we have upper and lower thresholds that move with the average.

The main control board

Next we come to the main board. Let's walk through the steps. Instead of showing the code from the main board, I'm going to talk about the various functions. You can view all of the main board's code on Github.

void loop() {
    addRandomDrip();
    advanceRestDrips();

    updatePIR(0);
    updatePIR(1);
    transmitSensor();
    receiveSensor();

    #ifdef RANDOMBREATHS
    if (millis() % (60 * 1000) < 5000) {
        addBreath();
    }
    #else
    if (proximityState == STATE_PIR_ACTIVE && detectedBreath) {
        addBreath();
    }
    #endif
    advanceBreaths();

    runLeaves();
    runBase();

    leds.show();    
}

What's going to happen is that the tree will randomly add "drips" to the top of the tree.

    addRandomDrip();
    advanceRestDrips();

These drips are a random length with a random green-tinted color. They will use easing equations to slowly but rhythmically drip down the tree. The effect is that the trees are swimming in their own green waves.

    updatePIR(0);
    updatePIR(1);
    transmitSensor();

When a person sits down at the base of the tree, the PIR motion sensor fires. We then send this signal over to the sensor board, which then opens up the flower using a servo motor and changes the color of the flower.

    receiveSensor();

The sensor then sends back data about the proximity sensor and the detected breaths.

    #ifdef RANDOMBREATHS
    if (millis() % (60 * 1000) < 5000) {
        addBreath();
    }
    #else
    if (proximityState == STATE_PIR_ACTIVE && detectedBreath) {
        addBreath();
    }
    #endif

Once a breath is detected, we add the head of the breath to the bottom of the tree and guide it upwards.

    advanceBreaths();

The high current LEDs in the leaves are glowing in randomly paced greens.

    runLeaves();
    runBase();

When the head of the breath reaches the top of the tree, the high current LEDs then begin to glow in a whiteish blue. This signals that the tree is breathing at the same pace as the person sitting underneath it.

    leds.show();

Since we've queued up all of the LEDs, it's now time to send the data over the line and update the tree for this loop. There will be dozens of loops per second, enough to make the tree's many LEDs look fluid in their motion.

The dispatcher board

Finally, because we're using a 12 channel SPI DAC on the dispatcher so that we can send digital signals up the long trunk of the tree to later be converted to analog signals used to set brightness of the high current LEDs, we need to make the simple transactions over SPI.

/**
 * Set the analog output on the dispatcher board.
 * Channels are numbered 1 to 12 inclusive (THEY DON'T START AT ZERO !!) 
 * value is 0-255 range analog output of the dac/LED brightness
 */
void dispatcher(uint8_t chan, uint8_t value) {
    // We could normalize here to a "real" range
    // There's nothing below 45 because below 0.5 the pico buck is off
    // value = value * 210 / 255;
    // if (value > 0) value += 45;

    // take the SS pin low to select the chip:
    SPI.beginTransaction(dispatcherSPISettings);

    digitalWrite(slaveSelectPin, LOW);
    //  send in the address and value via SPI:
    SPI.transfer(flipByte((chan & 0x0F) << 4));
    SPI.transfer(value);
    // take the SS pin high to de-select the chip:
    digitalWrite(slaveSelectPin,HIGH);

    SPI.endTransaction();
}

5. Powering ten trees in Grove

Running an electronics installation out in the desert presents a few power problems. First is that there is nowhere to plug in, so all of the energy you're going to need, whether it is stored or rechargeable, is going to have to be brought out there on the playa with you.

We quickly decided on running the installation on solar-powered deep cycle batteries. The cost for the batteries was mitigated slightly by the fact that we already had a 1.2 kW solar array handy. In past years you could affordably rent solar arrays from non-profits (like Black Rock Solar, who have written about how to solarize your playa art installation), but changes in Nevada's energy policy have meant that's no longer an option. It's kind of tragic and the New York Times recently covered how Solar City had to move out of the state.

The other option is to use a generator, but while relatively cheap, they are loud and would detract from the serenity of the installation. We could instead choose to run a generator in a baffle box and run AC power over a length 50 meter distance, but that was deemed un-Grove-like and we stuck with batteries.

Let's take a look at what's on the market.

Most batteries cost around 20 cents per Watt-hour. Let's perform some calculations to figure out how much we need. Let's look at a single tree. Most of the time a tree is going to be in a "rest" state, where nobody is actively using it. This means the tree is draped in green and the high current LEDs are in a lower power state.

About 5% of the time we're going to be in active mode, with brighter LED colors on the 4 × 5 meter strips and 16 × high current LED colors.

 95% × ((4 LED strips × 1.50A @ 5V per strip) + (0.25A @ 5V base lighting) + (16 × 0.08A @ 12V))
+ 5% × ((4 LED strips × 1.75A @ 5V per strip) + (0.25A @ 5V base lighting) + (16 × 0.10A @ 12V))

= 0.95 * (4*1.5*5 + .25*5 + 16*.08*12) + 0.05 * (4*1.75*5 + .25*5 + 16*.1*12)

≈ 47W per tree

At 10 trees, that's 470 watts of power. We expect the installation to run 10 hours (8pm - 6am). That's 4,700 Watt-hours. We're looking at a set of batteries that should cost (4700 Wh × $0.20/Wh) = $940.

What we did was put 3 6V 250 Ah batteries in series to boost it up to 18V instead of just using 2 6V batteries at 12V. We did this to limit the DC voltage drop between the battery array and the trees, each of which was between 10 and 20 meters away from the battery array. Since voltage drop is linear with respect to distance, the reduction from 18V to ~15V is a 16% drop but 12V to ~9V is a 25% drop. This prevents the high current LEDs from flickering, since they need a minimum of 10V to work.

We charged the batteries using Luke's solar array that he just happened to have handy. Here's Luke on the challenges we faced:

Sam and I had a few 5-minute discussions about how much power we needed, and this was inadequate: our installation often ran out of power around sunrise. I should have brought twice as many batteries and 1.5x the solar panels. By dumb luck, this 'low power mode' produced an interesting 'dead red' effect: the batteries at lowest levels provided only enough power for the red leds to pulse, leaving out all other colors. Unfortunately, the batteries needed desulfated for a month straight after playa and a few were still killed.

In the future, we'll test the actual power consumption of our installation in the real world: with a kill-a-watt or other power meter, how much is your installation actually drawing over the course of 24 hours? Your battery capacity should be at least 4x this: 2x to keep from discharging more than 50%, and another 2x for when somebody (in our case, me) imbibes too much and forgets to move batteries to solar array until noon.

Installing the Installation

Before the trees go up we need to assemble them and give them a coat of spray paint. These trees are shaped steel tubes that need some gold applied.

All of the work is done at American Steel Studios in Oakland, California. We want to do as much work as possible before we get to the playa. Once we're in the desert, anything we may need is going to be 6 hours round trip to Reno, whereas the Home Depot in Oakland is a 5 minute drive away.

Alas, as much as we try to avoid it, there's plenty of firmware debugging to be done on the playa.

Naturally, firmware debugging often lasted well into the night.

Putting the trees up is also a ton of work. We prototyped the leaves at a small scale.

But once on the playa we realize it's a lot more work to attach 16 individual leaves to each of the 10 trees simply as a matter of scale.

The trees go up a lot faster than individual subassemblies on the tree. This is a good photo of the Pareto principle for art installations. Putting up the first 80% of the installation by volume only took 20% of the time.

Enjoying the fruits of our labor

It's dusty out there!

And as we did with Pulse & Bloom, these cushions are some of the only seating on the playa, offering a beautiful respite and place to recharge and re-energize from the heat of the playa.

The entire process lasted 3 months and involved 5 people on the electronics team, a half dozen people on fabrication, and another dozen people on assembly and installation. My hope is that others learn from our work and use some of the open-source firmware and designs for their own art installations.

If you'd like to bring Grove to your art or music festival, please contact Shilo Shiv Suleman.

I'd love to hear from you if you're inspired or build your own art installation. Reach me @samuelclay on Twitter.

breath (n), breathe (v)

Nov 21
2016

Open letter to my family in Ohio: I am still coming home for Thanksgiving this year

Dear Mom and Pop,

This was going to be an awkward year for us from the start. Thanksgiving is normally a time when we, two dozen immigrant Jews and first-generation Americans, come together to eat a turkey stuffed with oranges, served with a side of smoked fish and a dozen competing salads.

Before the election, I thought the greatest thing that would divide our dinner table would be my recently adopted vegetarianism. But us Jews are all about dietary restrictions. Eight breadless days of weight loss every year during Passover. Fasting from food and water every year for the day of atonement. Two sets of plates for Shabbat and for everyday. I was certain that refusing meat wouldn’t stop me from feeling embraced and loved at the table.

A russian salad feast courtesy of my friend Andrey Petrov

But then last week you voted for Trump. Jewish refugees from the Ukraine now living in Ohio voted for Trump. You have told me several times that Obama is the worst president in our lifetime. And so you voted for Trump.

This letter would not have been written if this were just about politics. Both of you have always voted conservatively. And I wouldn’t be this livid if it were just about privatization of health care, or import tariffs, or the unchecked negative externalities of infrastructure spending on energy extraction. The political tide goes in and out. How we run the country makes for a spirited debate over the Thanksgiving dinner table and I welcome our family’s contrary viewpoints. But this is not about politics.

Voting for Trump is clearly a vote for hate. I know you voted against Hillary, and not “in favor” of Trump, but the action is the same. Your vote signals to me that you see our fellow citizens as less than human. History shows where this leads and history is not just words in a textbook for us. You are choosing to ignore our past.

Donald Trump Says He’d ‘Absolutely’ Require Muslims to Register

We would have seven times as many cousins if it weren’t for the Nazis. You helped elect a fascist and are now complicit in what’s going to happen to families both in and outside of our country.

It is not unreasonable for people to think that fascists, if given power and an attempt to govern, will moderate their views. But history repeats itself.

“Several reliable, well-informed sources confirmed the idea that Hitler’s anti-Semitism was not so genuine or violent as it sounded, and that he was merely using anti-Semitic propaganda as a bait to catch masses of followers and keep them aroused, enthusiastic, and in line for the time when his organization is perfected and sufficiently powerful to be employed effectively for political purposes.”

“You can’t expect the masses to understand or appreciate your finer real aims. You must feed the masses with cruder morsels and ideas like anti-Semitism. It would be politically all wrong to tell them the truth about where you really are leading them.”

I take Trump at his hate-filled words. Last time we spoke, you did not. You said he probably wouldn’t be fulfilling any of his promises, like the ones to register Muslims or deport Latinos. However, even if you do believe that his campaign was only hype, you still ignored despicable behavior and rhetoric. Normalizing racism is itself an act of racism.

Some positions are binary. You either care about the protection of minorities or you do not. I have friends now who will stand in the same shoes that my grandparents stood in before. And you knew, regardless of your enthusiasm for Trump’s economic policies, that these people would suffer. The increasing number of graffitied swastikas, along with other vile behaviors now edging into the mainstream, are the kind of atrocities your vote was supposed to suppress.

You taught me that my highest responsibility as a Jew is to never forget, to fight against discrimination. This was a common refrain told to me during seven years of Hebrew school. I take that responsibility seriously and that is what I am trying to do now. Elie Wiesel said “We must take sides. Neutrality helps the oppressor, never the victim. Silence encourages the tormentor, never the tormented.”

I understand why you voted to put Trump in office. It’s just hard for me to forgive you for it. And now is not the time to give bigotry a pass. I’m trying to live by the values you taught me, which is why I am only asking you to take our President at his word. And when he tells you of his bigoted promises to force members of a religion to register, you should be outraged.

I am coming home this Thanksgiving and it’s going to be painful, most of all for me. I try to be empathetic with how you feel about the state of our country, but what I do not understand is how you think that voting for a racist and hate-filled demogogue with no political experience is going to promote growth and peace. At best, it will alienate over half of this country, and at worst, history will repeat itself.

I am coming home because I want to believe the love that brings us together at Thanksgiving is strong enough to not only include a vegetarian, but also strong enough to allow you to understand my perspective and possibly even change your minds. I need my family with me in this fight.

Your son,
Samuel

Sep 06
2014

Building Pulse & Bloom - an interactive biofeedback installation at Burning Man 2014

This was my second year attending Burning Man. Many use Burning Man as a week to detach from their workweek and experience a new life of intense leisure. Not me, I come to Burning Man to build.

Pulse & Bloom is a 2014 honorarium installation. The core team of 6 people — Saba Ghole, Shilo Shiv Suleman, Rohan Dixit, Heather Stewart, Luke Iseman, and myself — built 20 interactive lotus flowers made out of steel and rowlux. Each lotus flower ranges from 8 to 18 feet tall, each of which lights up with your pulse. You and another person can put your hands on a couple of Hamsa hands at the base of the lotus flower and your respective heartbeats will light up the flower.

We've gotten some great press coverage at the BBC, The Guardian, The Atlantic's Big Picture twice, CBS News, NBC News, and MSNBC.

As usual, the complete source code for Pulse & Bloom is on GitHub.

Your heartbeat in light

Here are a couple videos of all twenty lotus flowers in full working order.

Each lotus flower is blue until a person or two sits down at its base and places their hand on the pulse sensor. You can see the Hamsa hand and its embedded pulse sensor in this shot of my girlfriend Brittany and me working on keeping the electronics going.

Photo credit Jim Urquhart / Reuters

When a pulse is read, the lotus flower shoots the heartbeat up the stem and into the petals, where it blooms in a brilliant display of amber. When two people's hands are being measured, both of their heartbeats are shown as two distinct colors.

How the electronics are made

There are five stages to making the electronics:

  1. Making the custom circuit boards
  2. Making the custom pulse sensors
  3. Driving the high current LEDs
  4. Writing the firmware
  5. Powering the lotuses

1. Making the custom circuit boards

The circuit board controls all of the lighting, sensors, timing, and debugging sequences. A reliable circuit board couldn't just be an Arduino and a breadboard. I decided to use OSH Park and OSH Stencils to fabricate inexpensive circuit boards. I ultimately went through seven revisions while we worked out the final design of the lotuses. This included adding additional lights, additional sensors, controls for EL wire, and better power management using an external buck converter.

This board has support for multiple high current petal LEDs driven by digital RGB pins (used for fading colors in and out using PWM) and in multiple voltages. The high current petal LEDs runs on 12V, which comes directly off the battery, the ATmega328p chip and stem LEDs run at 5V, and the pulse sensor runs at 3.3V.

To convert 12V to 5V I use a $3 switching voltage regulator from Electrodragon. This requires a +/- connection for both 12V in and 5V out. To convert 5V to 3.3V I used a linear voltage regulator soldered directly on the board, since the current requirements of the pulse sensor were around 20mA. The heat dissipated was negligible compared to the rest of the circuit.

I also added terminal connections for two 5 meter LEDs that wrapped around the tall lotus stem. We attached two 5 meter LED strips around the stems because when two people put their hands on the two pulse sensors, we need an easy way to show both heartbeats without one winning out over the other. When only one person's hand in being measured, both 5 meter light strips show the same color, which makes it that much brighter for a single person.

Lastly, the two pulse sensors terminate their I2C wires directly on the board. I used two separate I2C channels instead of one to cut down on time. I could easily have put both pulse sensors on the same I2C connections, but that would've required both pull-up resistors on the SDA and SCL data lines as well as a rewrite of the timing functions for the sensor.

All of these terminations are made using 2.5mm and 3.5mm pitch screw terminals. In hindsight I would have used female JST-SM mounted connectors and ordered custom wires with JST-SM male connectors. I assumed the lowest common denomenator would be bare tinned wire, but all of the bare wires could easily have been switched over to polarized, latching connectors. This would have reduced over 90% of the field work I had to perform on boards, as their wire would fall out of the screw terminals due to not being screwed in with enough force.

The board was laid out to be as big as a pack of gum. All of the 12V traces are thickened and isolated on the right side of the board. They are rated for 3 amps although they would end up only driving 1 amp on the playa.

These boards are then stenciled with solder paste and populated with their chips and passive components.

An inexpensive hot plate is used to reflow the solder. The chip is in a TQFP package, which has a 0.5mm pitch between pins. This makes it nearly impossible to hand solder. This stencil and reflow technique works well and my yield stayed high at around 95%.

Finally, the board is ready to be populated with screw terminals.

The final board in a dust-proof enclosure.

2. Making the custom pulse sensors

This was both the riskiest piece of the puzzle and also the most fun to build. In order to show your heartbeat on the lotus, I need to have a clear reading of your pulse. There are a fair number of issues with most off-the-shelf heartbeat sensors, including:

  • Cost: While a $50 pulse sensor is nice, it's way out of our budget. We spent $6 in components to make each of our pulse sensors for a total of 40 sensors (two per lotus).
  • Design affordance: There were a fair number of pulse sensors that required an infrared light on one side of your finger and an infrared detector/receiver on the other. This clamping of your finger wasn't something we could get away with in the desert. We needed a sensor you could just touch and hold on one side. It needed to be a simple interface so we wouldn't have to show any instructions.
  • Reliability: When a sensor gets covered in dust, will it still work? Infrared light, thankfully, passes through a layer of dust and can read the changes in blood flow in your finger. Some options were entirely visual and they would have performed quite poorly out on the playa.

The first prototype I built suffered from the design affordance and reliability issues, although it worked pretty well in ideal conditions.

We ended up finding an IC by Silicon Labs called the Si114x, which uses three LEDs — two infrared and one visible — and a small QFN-10 sized light sensor. The original sensor we used was the Modern Device pulse sensor, which also provided firmware and ideas for a board layout. The folks at Modern Device were kind enough to offer advice on how they built their sensor and about how to fix the infrared LED issues we hit. I owe them beers for saving me from many more excruciating hours of trying to build sensors that don't sense.

I built out a small PCB the size of a fingertip.

This tiny IC is a bit tricky to solder as it has no leads and the pins are extremely close together. My yield dropped to about 80%, but 4 out of every 5 pulse sensors I built worked perfectly the first time. If they failed, I would remount them on the hot plate and try wicking away any solder bridges I could find. This worked only about half the time. After that I gave up and now have a plastic cup full of broken pulse sensors.

Finally the sensor is hooked up and a tiny red light is emitted, letting people know where to put their fingers.

3. Driving the high current LEDs

What turned these lotuses from flowers into gems are the high current LEDs mounted in the petals at the top. There are 9 of these high current LEDs per lotus, split into groups of three, each driven by a constant current driver.

If you were to look at one of these LEDs from a few feet away, you would immediately see spots in your eyes. They are extremely bright pinpoints of light. The fact that they are also full color and need a heatsink due to their brightness means that you won't just find these in an easy package ready for plugging in.

Photo credit Jim Urquhart / Reuters

Normally a single LED is powered by a single constant current driver. This driver can drive up to 1A of current at 12V. Because we were only using a single channel of color (blue) in the rest state, which is where the lotus spent most of its time, we could triple the number of LEDs driven by a single constant current driver.

When in use the petals glow amber, which uses two channels (100% red, 50% green) but only for a moment while at peak current. So while the peak current is above what this constant current driver is rated for, it's only at peak and therefore within our tolerance.

Using a Chinese distributor, we bought these Sparkfun high current LEDs for $0.86 each instead of the full $15. However, we also bought 80 of Sparkfun's PicoBucks to use as our constant current driver. While we could have built this ourselves to save money, buying 80 of something at $15 each is still only $1.2k, while building them ourselves would only have saved a few hundred dollars.

We bought 200 high current LEDs, all of which had to have their 6 anode and cathode connections soldered.

In order to connect 9 high current LEDs to the board, we need to drive them in groups of three. Each group has 6 connections: red, green, blue anodes, and red, green, blue cathodes. The wiring diagram for this setup can get a bit rats nesty, but the end result was fairly easy to work with, as the picobuck groups didn't cross.

Finally, a shot of a complete picobuck with the wire connectors in the background.

4. Writing the firmware

The complete source code for Pulse & Bloom is on GitHub. There you can find the firmware used to program the main circuit board's ATmega328p chip, as well as designs for the laser cut cowl that sits over the pulse sensor's Si1143x IC.

The easiest way to read the firmware is to dive into src/pulse.cpp. It has all of the pulse and rest states and handles the high level logic.

The state machine that runs the entire routine is determined by a couple of critical measurements. The program takes a measurement of both pulse sensors and determines whether a finger is covering either of them and whether or not that finger has an active pulse going.

// Modes
void determinePlayerMode();
void determineFingerMode(int sensor1On, int sensor2On);
void resetStem(PulsePlug *pulse);
uint8_t adjustBpm(PulsePlug *pulse);

When there are no fingers on either of the pulse sensors, the program runs the rest state, which is a blue-topped lotus with a small blue snake running up and down the stem. The program is merely waiting for somebody to put their finger on a sensor.

// State: resting
void runResting();
void runRestStem();
void runRestStem(PulsePlug *pulse, int16_t currentLed);
void clearStemLeds(PulsePlug *pulse);
void beginPetalResting();
bool runPetalResting();

The firmware for the pulse sensor originally came from Modern Device's pulse sensor. Before a heartbeat is shown an accurate measurement of a heartbeat needs to be read. In order to determine whether a heartbeat is found and at what speed, a number of light detection measurements are taken and analyzed.

Modern Device's firmware simply finds the high frequency curve (the heartbeat) and the low frequency curve (the light sensors leveling out) and then use a simple peak and valley hueristic to determine the moment a heartbeat begins. This can take up to two or three seconds at first, so a bit of unwinding animation prepares you when you first put your finger on the sensor. I modified the firmware to account for multiple pulses on the same lotus and to have thresholds that worked better for the desert.

When a finger is detected, the stem snake lights shoot backwards up and down the lotus in prep for a heartbeat. This looks seamless as it clears the stem. This way a heartbeat doesn't interrupt the rest state.

// State: end resting
void beginSplittingStem();
void runSplittingStem();
void runSplittingStem(PulsePlug *pulse, int16_t currentLed);

When a heartbeat is detected, it is first shot up the stem. The color is determined by how many pulse sensors are being used. 1 heartbeat shows amber. 2 heartbeats show in white and light red.

// State: stem rising
bool runStemRising(PulsePlug *pulse, PulsePlug *shadowPulse);

Once the heartbeat reaches the top of the stem, the petals then fill with light.

// State: petal rising
void beginPetalRising();
bool runPetalRising();

After a set delay, the petal slowly lose light while waiting for the next heartbeat.

// State: petal falling
void beginPetalFalling();
bool runPetalFalling();

Lots of debugging messages have been left in the code and are accessible using the Serial pin on the board. Just turn on USE_SERIAL, which is commented out at top. Note that this increases binary code size by about 2.5K. I wrote a lot of logging.

// Debugging
void printHeader();
void blink(int loops, int loopTime, bool half);
int freeRam ();

5. Powering the lotuses

While much of what I built above came out of knowledge I already had, learning how to power this large of an installation off just a battery was all new to me. I'm used to microelectronics that run off a coin cell or AA batteries.

Measuring current and power usage

First, in order to figure out how big of a battery we needed, we had to measure how much power we were taking. I hooked up an ammeter in series with a single lotus to measure the current draw. In rest state, a single lotus drew 0.75A at 12V. In the active pulsing heartbeat state, a single lotus drew 1.5A at 12V. Since a lotus spends 95% of its time at rest, we rounded the average current consumption to 1A.

Twenty lotuses at 1A at 12V meant we needed 240Ah to sustain a 12 hour night. A car battery was recommended, but car batteries can only discharge down to 80% without irreparable harm. However, a marine deep-cycle battery can go down to 20% without harm.

This 150 lb. battery has enough capacity, although we ended up adding a couple 6V batteries in series (to boost them to 12V) and then running them in parallel to offset some of the load.

Dealing with the voltage drop

A big issue we ran into was the voltage drop across the power lines. We placed the batteries on the edge of the installation, which meant some of the lotuses had 20 meters of wire between them and the battery. The voltage drop per 10 meter section is nearly 2V, which means that the voltage reaching the further lotuses was down to 7.5V.

The high current LEDs were not able to be smoothly driven at this low of a voltage, causing them to flicker. We determined that a voltage drop was responsible for the flickering, which got worse the further the lotus sat from the batteries. But when we discovered this the wires had already been trenched 6 inches beneath the playa. A day of work lost, but we sucked it up and ripped out all of the ground wiring to accommodate the battery which had to be moved into the center of the installation.

At the end of each night we had to bike out with a trike and carry all 300 lbs. of batteries back to camp, where they were hooked up to a 1 kW solar array, where they were charged at 48A over 6 hours.

Prototyping the lotuses

Back at American Steel in Oakland, the lotus stems, bases, and petals were ready to be hooked up. These twenty lotus stems were bent by Heather. They range from 6ft to 16ft in length and each weighs 50 lbs.

Such a heavy stem needs a larger base and heavy anchors to stay upright in the wind.

We placed the lily pad over the base to cover it up and then added all of the electronics. Lights, sensors, and circuit boards all had to be mounted.

This is a photo of our first complete lotus flower. Just compare its sheer size to Shilo.

Once we were confident that one lotus would successfully light we left the other 19 lotuses packed away for assembly on the playa.

A dusty scene

We drove out in the biggest rental car I could get my hands on. Our minivan is full of electronics, bicycles, tents, costumes, coolers full of fruit and veggies, dry snacks, and water.

Since we were early arrival, they give you these red bracelets. They say Work hard, don't do stupid shit.

The boards would accumulate dust on them everyday. Our plastic enclosures turned out to be too big for the holes we made in the platform. So we ended up using ziploc bags. These baggies stayed attached, but the only reason they didn't cause any issues is that the boards worked just fine in the dust, as you can see here.

If dust was a real problem for the boards, then I would have spent a whole lot more time making a tight fitting enclosure and a hole for it that protects it both from the elements and from people.

The playa gets covered in dust storms regularly throughout the week. A particularly nasty dust storm is pictured here, eating our poor lotus flowers alive.

Although during the day when its not dust storming the lotuses offer a cozy respite from the heat of the playa.

Photo credit Jim Urquhart / Reuters

The entire process lasted 4 months with 2.5 months of nearly full-time work on my part. I'm thrilled that I get to open-source both the process and the firmware. I hope others who build art installations can use some of my lessons learned here. I'm happy to answer any questions on Twitter.

See you next year on the playa!

Samuel Clay is the founder of NewsBlur, a personal RSS news reader for web, iOS, and Android. He is also the founder of Turn Touch, beautiful control for your smart home.

He lives in San Francisco, California. In another life in New York, he worked at the New York Times on DocumentCloud, an open-source repository of primary source documents contributed by journalists.

You can read about his past and present projects at samuelclay.com.

Follow @samuelclay on Twitter.

You can email Samuel at samuel@ofbrooklyn.com. He loves receiving email from new people. Who doesn't?

Elsewhere