Friday, December 14, 2018

Building a BTTF Flux Capacitor



Planning the build

After many years I had watched “Back to the Future” again. No comment needed! But this time, I saw it with very different eyes. And when I saw the flux capacitor, I knew that I wanted one. The electronics will be based on an Arduino (the Arduino Pro Mini which is small and cheap - which I am using in most of my projects), so the main challenge will be on the mechanical side. I am always building things on a budget. So, I am not aiming at 100% accuracy. I just want to get the main features right and, like with my HAL 9000 replica, most people will not be able to tell the difference from the real thing – only a few experts/nerds will be able to do that.
In the first step, I collected information. Here are links that were helpful and inspiring:
The enclosure used for the original prop is a fiberglass electrical enclosure box Stahlin J1210HPL. This can still be bought on eBay (usually versions without the front window). However, it sells typically for more than $100 which is beyond what I plan to pay for the whole device. Like in one of the links, I will build this from wood. Somewhere (I forgot where…), I found the precise measures for the box – here they are:
 

Parts and Pieces

After some research and viewing other people’s builds, this is the list of all the parts that I will use, separated into three categories: enclosure, inner pieces, electronics.

Enclosure

The original movie prop is using the Stahlin J1210HPL industrial enclosure. It measures 12″ H x 6″ D x 10″ W. They sell some of these on Ebay, but they are quite expensive. Furthermore, they usually do not offer the versions with the window, so you would have to add additional work. I decide to build the enclosure from wood. Recently, I got access to a laser cutter, and this is how I’m gonna do it. I will make the .dxf files for the laser cutter in the open source software librecad (for Windows, Apple, and Linux). The enclosure is build from 3/16″ (5mm) plywood. The window is made from 3/32 acrylics, and I get the gasket from Amazon. For the metal pipes on the right and the top, I am using 1 1/2″ PVC elbows.

Inside & Details

  • The round metal disks in the original movie prop used old electrical vacuum solenoids which are not available anymore (maybe as collectors items). Like some other people, I am using the metal piece from these electrical plugs.
  • On top of these come three red rubber spark plug boots, and the yellow cable is cheap Ethernet cable.
  • Next to the metal disks come three 3/8″ acrylic blocks, on top of which I place 12mm plastic tubes in which I place 12 gauge copper wire.

Electronics

The following pieces are used
  • Arduino Pro Mini (ATmega 168, 16MHz, 5V)
  • DFPlayer mini module
  • 128MB microSD card
  • 3W 40mm speaker
  • 12 warm white 5mm LEDs (for the Y-pattern below the acrylic blocks)
  • 1 white 8mm 0.5W straw hat LED (in the center)
  • 8 5mm (cold) white straw hat LEDs for the sides of the enclosure (straw hat LEDs have a more even light distribution pattern)
  • DFPlayer Mini module 
  • 128MB micro SD card
  • 40mm 3W speaker
  • 2N3904 and 2N2222 transistors, various resistors
  • power switch, two momentary switches (to set modes, and sound options)
  • PIR module (infrared motion sensor)
  • 2.1mm power socket
  • USB to 2.1mm power cable

Other

  • Embossing Label Maker DYMO 1540 Office Mate II and red tape for the three labels. (note: other label makers may not have the correct font)
  • Spray paint: glossy medium gray (enclosure), satin black (inner board), almond (sides of the acrylic blocks), silver (PCV elbows)

Laser Cutter & Paint

The construction of this Flux Capacitor makes heavy use of a Laser Cutter. The pieces for the enclosure are cut from 3/16″ plywood.


The enclosure is glued, and the edge of the front window is sanded down, to fit the window gasket.


Then the thin frame is glued to the front window, and the switchplate into the enclosure.



The acrylic blocks are cut out of a 3/8″ acrylic board. The outer edge is masked with masking tape and the sides are sprayed with almond paint.


Then the PVC elbows and the spacers for the metal disks are painted in aluminum.





The enclosure and the front plate are spray painted in dark gray. Then the gasket is inserted into the front window, and a thin (3/32″) piece of acrylic is mounted behind.


The labels from the Dymo 1540 Office Mate are then glued to the front side.

The Inside

The top side of the inner board of the Flux Capacitor is holding the acrylic blocks, and the solenoids.


The inner board is painted matte black. For this build I replaced the (expensive!) solenoids with (cheap!) metal bases of electrical power plugs. I inserted a wooden dowel which then holds a red spark plug cap with the yellow Ethernet cable inserted.


The metal pieces are screwed to silver painted wooden spacers on the board.


The acrylic blocks are glued to the board. Pieces of copper wire are fed through a hole in the power plugs, and inserted into 12mm plastic tubes.




Electronics

The electronics is mounted to the bottom side of the inner board. These consist of an Arduino Pro Mini (168, 16MHz, 5V), warm white clear LEDs (below the acrylic blocks), cold white straw head LEDs (at the sides of the board, they flash when the baby hits 88 mph), the DFPlayer mini module which plays .mp3 sounds from a 128MB (yes "MB", they still make these!) microSD card.


The LEDs that sit below the acrylic blocks are soldered onto three PCBs which are screwed onto the wood.


Here is a sketch how these are connected




The straw hat LEDs and the 3W speaker are hot-glued onto the board. The PCB holding the Arduino Pro Mini and the DFPlayer module is added, and everything is connected by cables. I have described the DFPlayer module in an earlier blog entry.


Here is a sketch of the circuit on the main PCB.


The four openings on the left side of the Flux Capacitor enclosure are holding (from top to bottom): the power switch, two momentary push buttons (for mode of operation and sound volume), and a 2.1mm socket for the USB-to-2.1mm) power cord.

Software

The software is written in the Arduino IDE. I always find it important for a prop like this not to become boring due to a behavior that is too predictable. That's why I always spend some time to come up with a variety of light and/or sound patterns. With short breaks, the Flux Capacitor continues to run randomly one out of five different patterns for the Y-shaped LED bars in the center. After a certain time, it will run a "full power" pattern, which also enables the cold-white LEDs at the edges of the board. This pattern corresponds to reaching 88mph (when something serious happens). The Flux Capacitor operates in four different "activity modes", in which the"full power" patterns occur approx. every 66sec (mode #4), 2 1/2min, 6min, or never (mode #1).
The "full power" operation is accompanied by longer, aggressive electrostatic sparking sounds, while in the regular modes only rarely some softer electro-buzz is heard. The volume can be set to four different levels.
The PIR motion sensor that is built into the bottom of the enclosure is actually not used. Initially, I liked the idea, but ultimately I did not see the point.
When the Flux Capacitor is turned on, the famous Back-to-the-Future "Twinkle" sound is playing. And there is one easter egg: when both the volume and the mode buttons are held during turn-on, it plays the sound clip from Doc Brown: "When this baby hits 88 miles per hour, you're gonna see..."


That's it: this is my Flux Capacitor and I love it! Most people recognize it, and everybody likes it. Once, I took it to a screening of BTTF part I and one kid asked me if it really works - the little boy was not talking about the lights - he was referring to time travel...  The most frequent question I get asked is: "Where is your Delorean?" Well, I guess this Flux Capacitor will have to settle to traveling in an boring Toyota...

Source Files

The files for this project (laser cutter, Arduino code, and sound clips) are stored at GitHub.


Related

My other blog posts on BTTF-related props and pieces:
   - Building the Time Circuits
   - Building the Speedometer
   - Building the Analog Gauges
   - Building the TFC Switch
   - Building a Hoverboard and Charger
   - Building BTTF clocks
   - Building a BTTF Brick Stage (featuring the smallest Flux Capacitor)

Friday, April 6, 2018

Arduino push buttons: debounce, and short vs. long press

A typical Arduino setup may include multiple push buttons having different functions, depending on whether they are pressed for a short or longer time. Furthermore, you want to avoid that these buttons bounce, meaning that they give multiple on/off signals when pressed or when released.

Here is a small piece of code that handles all of the above: It can read a number of different buttons, debounces them, and distinguishes between a short or a long press. Of course, you could also debounce the buttons by adding a small capacitor - but why would you add hardware when you can easily do it in code?

One contact of each button is connected to GND, and the other one to an Arduino pin which is specified in the initialization. In the initialization (the code before the "setup"), you specify the number of buttons used in your project, and the Arduino pins to which they are connected.
// -----------------------------------------------------------------
// --- push buttons: this example is made for five push buttons
const byte maxButton = 5;             // number of buttons
const byte pinPushButton[maxButton] = {2,3,4,5,A2};  // the Arduino pins 
In the "setup", you set the pinMode for the push button pins to "input" and enable the pull-up resistors for those pins.
// ------------------------------------------------------------------------
// --- Setup
// --------------------------------------------------------------------------
void setup() {
  // --- initialize push button pins as inputs with pull-ups
  for (byte i=0; i<maxButton; i++) {
    pinMode(pinPushButton[i], INPUT_PULLUP);
  }
}   
In the following, I assume that your code is written without any longer delays, and your main loop is frequently executed. In my Arduino sketches, the main loop is usually executed more than 10,000 times per second. But it is not necessary to check the buttons that frequent, so I reduced the number of checks to 500 per second. In time intervals of 2 milliseconds I loop over all buttons, and, for each button, call the code to check if a short or a long push was detected. Then I am then executing the code that performs the corresponding actions.
// --------------------------------------------------------------------------
// --- Main loop
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void loop() {

  static unsigned long previousTime = 0;  
  const byte timeInterval = 2;   // pick a short time interval, you don't have to 
                                 // check the button with 10kHz
  byte a[maxButton] = {};        // array to store the latest readings

  // - check all buttons
  if ((millis()-previousTime) > timeInterval) {
    previousTime = millis();
    for (byte i=0; i<maxButton; i++) {
      a[i] = checkButtons(i);  
    }

    if (a[0] == 1)  [your code, when button 0 is short-pushed];
    if (a[0] == 2)  [your code, when button 0 is long-pushed];
    if (a[1] == 1)  [your code, when button 1 is short-pushed];
    if (a[1] == 2)  [your code, when button 1 is long-pushed];
    if (a[2] == 1)  [your code, when button 2 is short-pushed];
    if (a[2] == 2)  [your code, when button 2 is long-pushed];
    if (a[3] == 1)  [your code, when button 3 is short-pushed];
    if (a[3] == 2)  [your code, when button 3 is long-pushed];
    if (a[4] == 1)  [your code, when button 4 is short-pushed];
    if (a[4] == 2)  [your code, when button 4 is long-pushed];
  }

} 
That last item is the main one: the subroutine "checkButtons([button-number])" which, after debouncing the button, determines if it was push for a short time (<400ms long="" or="">400ms). The 400ms is hard-coded. It worked well for me (and my daughter's robot), but you may modify it according to your personal preferences. The subroutine returns zero if the button was not pressed, one in case of a short press, and two for a long press. This is what the code does: The "state" variables for all buttons are initialized as zero. If it is detected that a button (that was not pressed before) was pressed, its "state" variable is set to 1, and the current time is stored in "previousTime". If a button was pressed before (meaning its "state" is 1), the code waits 100ms (this takes care of the debouncing) After 100ms, it checks if the button was released before 400ms expired - if yes, this was a short press. After the 400ms expired (and a short press was not detected, it must have been a long press. In that case, the code waits until the button is released. Afterwards, the code waits another 200ms before it is ready to accept any new presses.

// -----------------------------------------------------------------
// ---------------------------------------------------------------------------------
// --- check one button for short or long push
// ---------------------------------------------------------------------------------
//     returns: 0-none  1-short  2-long
//
byte checkButtons(byte buttonNo) {
  const unsigned long timeDebounce = 100; // time to debounce 
  const unsigned long timeLong = 400;    // minimum time for Long press 
  const unsigned long timeBreak = 200;   // time interval after button release, 
                                         //  before ready for next press 
  static byte state[maxButton] = {};     // this initializes all elements to zero
  static unsigned long previousTime[maxButton] = {};  // this initializes all elements to zero
  byte r = 0;

  r = 0;      // 0:not  1:short  2:long

  if (state[buttonNo] == 0) {             // --- no button has been pressed - check if 
    if (digitalRead(pinPushButton[buttonNo]) == LOW) {
      previousTime[buttonNo] = millis();
      state[buttonNo] = 1;
    }
  } else if (state[buttonNo] == 1) {  // --- button was pressed - check for how long
    if ( (millis()-previousTime[buttonNo]) > timeDebounce) {
      if ( (millis()-previousTime[buttonNo]) < timeLong) {
        if ( digitalRead(pinPushButton[buttonNo]) == HIGH) { // released -> short press
          previousTime[buttonNo] = millis();
          state[buttonNo] = 3;
          r = 1;
        }
      } else {                        // it was a long press
        state[buttonNo] = 2;
        r = 2;
      }
    }
  } else if (state[buttonNo] == 2) {  // --- wait for long button press to end
    if (digitalRead(pinPushButton[buttonNo]) == HIGH) {
      previousTime[buttonNo] = millis();
      state[buttonNo] = 3;
    }
  } else if (state[buttonNo] == 3) {  // --- wait a little while after previous button press
    if ( (millis()-previousTime[buttonNo]) > timeBreak) {
      state[buttonNo] = 0;
    }
  }
  return r;
} 
That's it! The above code works nicely in a few of my recent projects. In a few cases it allowed me to use less buttons, and therefore fewer Arduino pins. In one case it helped me to add functionality to a project that was built using a single button.
Note: Two typos in the code were fixed on July 10, 2018 - now it works correctly
2nd Note: Another bug was in the code that was fixed on July 23, 2018. Now it really works beautifully in my projects, distinguishing between short and long button pushes.

Tuesday, April 3, 2018

Plant Stand

Spring has started, and this year I wanted a tomato plant for our back yard. I bought two: a cheaper, smaller one (that will need some patience) and a bigger one that already carries a few (currently still green) cherry tomatoes.
But it should not sit on the ground, so I use some scrap wood to build a little stand.
I am using treated lumber, 2"x2" for the legs and the frame, and 3/4"x4" boards for the stand and the sides.

Make sure to leave some space between the bottom boards, so excess water can drain.


It is, actually, heavier than I expected - but that's a good thing.
And now I'm waiting for the tomatoes to ripen! (The little tomato plant one on the right will need a little more time)