Go for it! If you don’t own a DeLorean, this will still impress your co-workers and look great on your desk. Or maybe you can devise a scheme around Halloween or a cosplay geek-fest like Dragon*Con. Bolt it just below the arc reactor on your Iron Man suit (you do have an Iron Man suit, right?). Or if you have a young son in a stroller, attach the time circuit to the tray, dress junior in mirrored shades and a “life preserver” down vest, while dad dons a Doc Brown getup…you’ll take home all the candy in the neighborhood!
Even if you don’t build this exact item, if it inspires any nifty electronics projects (*cough*Proton Pack*cough*), please share them in the forums, bring them to the Saturday night show-and-tell or document your build on a site like Instructables. Customer projects are frequently showcased on the Adafruit blog!
Resources
Parts from the Adafruit store include:
- Teensy (ATmega32u4 USB dev board)
- ChronoDot Ultra-precise Real Time Clock
- 0.56″ 4-Digit 7-Segment Display w/I2C Backpack – Red
- 0.56″ 4-Digit 7-Segment Display w/I2C Backpack – Green
- 0.56″ 4-Digit 7-Segment Display w/I2C Backpack – Yellow
- Diffused Red 3mm LED (note: film prop used yellow LEDs on destination time)
- Diffused Green 3mm LED
Additional parts acquired from Digi-Key include:
Elsewhere:
- Here’s an excellent DIY flux capacitor tutorial.
- The Replica Prop Forum is a great resource for build assistance, hard-to-find parts and to show off your finished work.
- YourProps likewise for original movie prop reference pics.
- At Maker Faire Bay Area 2012, Adam Savage (of Mythbusters fame) gave an entertaining and impassioned talk (YouTube) about our compulsion to recreate our favorite big-screen icons.
Code
Here’s the Arduino sketch that runs the show.
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries // // SPDX-License-Identifier: MIT // Time Circuit sketch for Adafruit 4-Digit 7-Segment Display w/I2C Backpack. // Modeled after Doc Brown's DeLorean time circuit from the "Back to the // Future" movies. Uses three (3) each of the following displays: // Red : http://www.adafruit.com/products/878 // Green : http://www.adafruit.com/products/880 // Yellow: http://www.adafruit.com/products/879 // A blue version is also available, but not used here. Also uses two (2) // each 3mm discrete LEDs: // Green : http://www.adafruit.com/products/779 // Red : http://www.adafruit.com/products/777 // Two yellow LEDs are used, but these aren't available in the shop -- they // can be purchased through Digi-Key, etc. The same sources will likely // carry a 74HC138 3-to-8 line decoder w/inverting outputs (or, with some // changes to the code, a more common 74HC32 quad 2-input OR gate could // also be used, if you already have one on hand -- see comments later). // The resulting item is not 100% screen accurate. The film prop used // 2-digit displays for day, hour and minute, the discrete LEDs for the // top (red) display were yellow, while the 3-character month displays were // back-painted glass fakes. This demo was put together for fun, not // pedantry, and generally gets the idea across. Everyone recognizes it! // These 4-digit displays can be assigned any of eight I2C addresses via // solder jumpers on the back. But the full time circuit requires *nine* // displays. A dirty hack exploits the fact that we only need one-way // (write only) access to the displays. The I2C data line is connected to // all devices as normal...then the I2C clock drives the enable line of a // 74HC138, while the select lines choose among multiple ersatz I2C buses // (potentially up to 8, though we're only using 3 here). Only that bus // then responds to the incoming data. The 74HC138 was chosen for its // inverting outputs -- the idle state is high, consistent with I2C. // So, each bus contains three 4-digit displays, and within each bus they're // assigned address 0 (for MM.DD), 1 (YYYY) and 2 (HH:MM). This simplifies // the code, as display addresses are the same across all dates. A ChronoDot // (RTC_DS1307) clock chip is also used...bidirectional communication works // because this connects to the regular I2C clock & data lines, not one of // the 74HC138 outputs. Altogether there's 10 devices attached to the I2C // data line. I'm not sure what the recommended fanout is for the ATmega... // but if this runs into trouble, can always add a second 74HC138 for data, // using the same bus select bits. #include <Wire.h> #include <Adafruit_LEDBackpack.h> #include <Adafruit_GFX.h> #include <RTClib.h> Adafruit_7segment matrix[3] = { Adafruit_7segment(), Adafruit_7segment(), Adafruit_7segment() }; RTC_DS1307 clock; // RTClib isn't pre-Y2K (or post-Y2.1K) compliant, so an ugly trick is used // to represent "fantasy" dates. Because our clock displays don't show // seconds, that field in the DateTime class is borrowed to indicate a // century #. Honest-to-goodness DateTimes will have a seconds() value of // 0 to 59. If seconds >= 100, this field (-100) is the two-digit century. DateTime dest(55, 11, 5, 22, 4, 100 + 19), // Nov 5, 1955 10:04 PM last(85, 10, 26, 1, 24, 100 + 19); // Oct 26, 1985 1:24 AM void setup() { uint8_t m, b; clock.begin(); // NOTE: all pin numbers used here are for the Teensy microcontroller // board, NOT a stock Arduino. You may need to adapt this code to // your particular situation. (e.g. if making a prop that also uses // the Wave Shield to add sounds, you'd want to use an Arduino Uno and // then steer clear of all the SPI pins (10-13)). // Enable select lines for I2C multiplexing (only 2 are used here) pinMode( 9, OUTPUT); pinMode(10, OUTPUT); // Enable AM/PM LED outputs, set all LOW (off) for(b=11; b<=16; b++) { pinMode(b, OUTPUT); digitalWrite(b, LOW); } // Initialize all three displays on all three buses for(b=0; b<3; b++) { selectBus(b); for(m=0; m<3; m++) matrix[m].begin(0x70 + m); } } boolean dots = false; // For flashing colon on HH:MM times void loop() { displayDate(0, dest); // Destination time displayDate(1, clock.now()); // Present time displayDate(2, last); // Last time departed dots = !dots; // Blink blink blink delay(500); } // This function enables one of the 3 (but potentially up to 8) I2C buses // by setting the select lines on the 74HC138 (only 2 lines are used in the // circuit, the third is tied to ground). A 74HC32 quad OR gate could also // be used, but each bus will require its own select line (set corresponding // output HIGH to disable, LOW to enable). I wanted to use the least pins // so that others remain free for the addition of a possible keypad later. // (Could also free up pins using a port expander or shift register for // the AM/PM LEDs.) void selectBus(uint8_t b) { digitalWrite(10, (b & 1) ? HIGH : LOW); digitalWrite( 9, (b & 2) ? HIGH : LOW); // Can add third bit here if more buses are needed } // Show contents of DateTime object on the three displays across one bus void displayDate(uint8_t b, DateTime d) { int x; selectBus(b); // Write MM.DD (zero padded) to display #0 x = d.month(); matrix[0].writeDigitNum(0, x / 10); matrix[0].writeDigitNum(1, x % 10, true); x = d.day(); matrix[0].writeDigitNum(3, x / 10); matrix[0].writeDigitNum(4, x % 10); // Write year to display #1 (4-digit, zero-padded) // Great Scott! RTClib isn't pre-Y2K compliant, so 'second' // is borrowed as a flag to indicate fantasy dates. if((x = d.second()) >= 100) x = d.year() - 2000 + x * 100; else x = d.year(); matrix[1].writeDigitNum(0, (x / 1000) % 10); matrix[1].writeDigitNum(1, (x / 100) % 10); matrix[1].writeDigitNum(3, (x / 10) % 10); matrix[1].writeDigitNum(4, x % 10); // Write time to display #2 (HH:MM, zero-padded + AM/PM indicator) x = d.hour(); if(x < 12) { // AM digitalWrite(b * 2 + 11, HIGH); // Upper LED on digitalWrite(b * 2 + 12, LOW); // Lower LED off } else { // PM digitalWrite(b * 2 + 11, LOW); // Upper LED off digitalWrite(b * 2 + 12, HIGH); // Lower LED on } if(x > 12) x -= 12; // Convert 24-hour to 12-hour time matrix[2].writeDigitNum(0, x / 10); matrix[2].writeDigitNum(1, x % 10); x = d.minute(); matrix[2].writeDigitNum(3, x / 10); matrix[2].writeDigitNum(4, x % 10); matrix[2].drawColon(dots); // Refresh all three displays on current bus for(x=0; x<3; x++) matrix[x].writeDisplay(); }