Memorial day is 05/25/2015 – Orders will ship out on May 26th. There will not be any deliveries or shipping on Monday. Any order placed after 11am ET on Friday May 22nd will not start to ship out until Tuesday May 26th.

My Doctor Who MonoChron Clock
Moderators: adafruit_support_bill, adafruit

My Doctor Who MonoChron Clock

by DanSlage on Fri Feb 03, 2012 2:19 pm

I am working on a Doctor Who inspired clock for the MonoChron. A video can be seen here. http://youtu.be/DHecR3Matss

The TARDIS travels through an wiggly wormhole. Pressing a button or switch (except "Menu") will cause the TARDIS to dematerialize and rematerialize a moment later in a random spot. My daughter plans on using this as her primary alarm clock once I figure out how to replace the alarm siren with the Doctor Who theme song.

I had to rewrite the wormhole code a few times to get it fast enough render correctly. The GLCD.h drawing routines are way too slow instead the wormhole uses glcdDataWrite()s directly to draw everything.

To speed things up I also EXTERMINATEd all division and modulus operations. For example to separate the hour into a high digit and low digit:

Traditional

Code: Select all | TOGGLE FULL SIZE
high_digit = hour/10;
low_digit = hour%10;

I found this to be much faster

Code: Select all | TOGGLE FULL SIZE
high_digit = 0;
low_digit = hour;
while (low_digit >= 10) {  // Count tens
  high_digit++;
  low_digit -= 10;
}

When you have as much motion as this clock does every clock cycle counts.
Last edited by DanSlage on Tue Jul 02, 2013 9:20 am, edited 1 time in total.
DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm

Re: My Doctor Who MonoChron Clock

by adafruit_support_bill on Fri Feb 03, 2012 2:35 pm

Nice one! You should post this in this thead too: :D
http://forums.adafruit.com/viewtopic.php?f=41&t=14769

adafruit_support_bill
 
Posts: 37483
Joined: Sat Feb 07, 2009 10:11 am

Re: My Doctor Who MonoChron Clock

by odometer on Sat Feb 04, 2012 5:12 pm

What datatype is "hour"?

This is good up to 99:
Code: Select all | TOGGLE FULL SIZE
high_digit = 0;
low_digit = something;
if (low_digit >= 60) {high_digit += 6; low_digit -= 60;}
if (low_digit >= 30) {high_digit += 3; low_digit -= 30;}
if (low_digit >= 20) {high_digit += 2; low_digit -= 20;}
if (low_digit >= 10) {high_digit += 1; low_digit -= 10;}
odometer
 
Posts: 98
Joined: Sun Aug 21, 2011 11:01 pm

Re: My Doctor Who MonoChron Clock

by DanSlage on Sat Feb 04, 2012 6:11 pm

Nice Odometer! The datatype is uint8_t but never goes larger than 59 in my program. My gut tells me your code would be faster than mine. I wonder if anyone has ever done any speed trials.
DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm

Re: My Doctor Who MonoChron Clock

by Nicodemus_NJ on Wed May 23, 2012 12:20 pm

I hate to be "that guy" but... It's TARDIS! (Time and Relative Dimension in Space)

:)
Nicodemus_NJ
 
Posts: 1
Joined: Wed Apr 27, 2011 11:36 am

Re: My Doctor Who MonoChron Clock

by kscharf on Wed May 23, 2012 1:29 pm

DanSlage wrote:I am working on a Doctor Who inspired clock for the MonoChron. A video can be seen here. http://youtu.be/DHecR3Matss

My daughter plans on using this as her primary alarm clock once I figure out how to replace the alarm siren with the Doctor Who theme song.


Sounds like you need to interface a wave shield to the clock some how.
User avatar
kscharf
 
Posts: 186
Joined: Wed Sep 10, 2008 10:29 am

Re: My Doctor Who MonoChron Clock

by JakeS on Wed May 23, 2012 5:41 pm

Hi-

Saw your project featured in the Adafruit blog- nice!

We did a Dr. Who song through a piezo speaker an on Arduino. I used an existing program for the piezo frequencies and sound generation, which I have forgotten and can't attribute, sorry! We only figured out the melody and the timing.

Code: Select all | TOGGLE FULL SIZE
const int  b=     4056;    // 261 Hz
const int  c=     3830;    // 261 Hz
const int  d=     3400;    // 294 Hz
const int  e=     3038;    // 329 Hz
const int  f=     2864;    // 349 Hz
const int  g=     2550;    // 392 Hz
const int  a=     2272;    // 440 Hz
const int  B=     2028;    // 493 Hz
const int  C=     1912;    // 523 Hz
const int  D=     1700;    // 523 Hz
const int  E=     1508;    // 523 Hz
const int  F=     1432;    // 523 Hz
const int  G=     1278;    // 523 Hz
const int  A=     1136;    // 523 Hz
// Define a special note, 'R', to represent a rest
const int  R=     0;

int speakerOut = 13;

int melody[] = { b,  C,  B,  D,  a,  B,  B, g,  d,  b,  d, c, b,R } ;
int beats[]  = { 8,  8, 48,  8,  8, 64,  8, 8,  8,  8, 16, 16,16,96 } ;
int MAX_COUNT = 14; // Melody length, for looping.

// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES

for(int js=0; js<20; js++) {
   for (int i=0; i<MAX_COUNT; i++) {
    tone_ = melody[i];
    beat = 4*beats[i];

    duration = beat * tempo; // Set up timing

    playTone();
    // A pause between notes...
    delayMicroseconds(pause);
   }
}

void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {

      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(tone_ / 2);

      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    }
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration); 
    }                               
  }                                 
}
JakeS
 
Posts: 10
Joined: Tue Feb 22, 2011 12:15 pm

Re: My Doctor Who MonoChron Clock

by adafruit on Thu May 24, 2012 6:31 pm

I second using the piezo to just play the theme, it sounds good on Tesla coils so a piezo should be fine too :)

adafruit
 
Posts: 11904
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: My Doctor Who MonoChron Clock

by richteel on Sat Feb 15, 2014 4:12 pm

JakeS,

I tried to run the posted code but it is incomplete. I was able to get it to run but it does not play anything recogizable. I suspect that there was a bit more left out of your code than I was able to quickly repair/replace.

Code: Select all | TOGGLE FULL SIZE
const int  b=     4056;    // 261 Hz
const int  c=     3830;    // 261 Hz
const int  d=     3400;    // 294 Hz
const int  e=     3038;    // 329 Hz
const int  f=     2864;    // 349 Hz
const int  g=     2550;    // 392 Hz
const int  a=     2272;    // 440 Hz
const int  B=     2028;    // 493 Hz
const int  C=     1912;    // 523 Hz
const int  D=     1700;    // 523 Hz
const int  E=     1508;    // 523 Hz
const int  F=     1432;    // 523 Hz
const int  G=     1278;    // 523 Hz
const int  A=     1136;    // 523 Hz
// Define a special note, 'R', to represent a rest
const int  R=     0;

int speakerOut = 9;

int melody[] = { b,  C,  B,  D,  a,  B,  B, g,  d,  b,  d, c, b,R } ;
int beats[]  = { 8,  8, 48,  8,  8, 64,  8, 8,  8,  8, 16, 16,16,96 } ;
int MAX_COUNT = 14; // Melody length, for looping.

// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES

int tone_=0;
int duration=0;

void setup() {
  pinMode(speakerOut, OUTPUT);
  drWhooTune();
}

void loop() {
}

void drWhooTune() {
  int beat=0;
 
  for(int js=0; js<20; js++) {
     for (int i=0; i<MAX_COUNT; i++) {
      tone_ = melody[i];
      beat = 4*beats[i];
 
      duration = beat * tempo; // Set up timing
 
      playTone();
      // A pause between notes...
      delayMicroseconds(pause);
     }
  }
}

void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {

      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(tone_ / 2);

      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    }
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration); 
    }                               
  }                                 
}


This bit of code worked much better but still did not sound like anything from Doctor Who.

Code: Select all | TOGGLE FULL SIZE
/*
  Melody
 
 Plays a melody
 
 circuit:
 * 8-ohm speaker on digital pin 8
 
 created 21 Jan 2010
 modified 30 Aug 2011
 by Tom Igoe

This example code is in the public domain.
 
 http://arduino.cc/en/Tutorial/Tone
 
 */
#include "pitches.h"

#define spk_pin 9

// notes in the melody:
int melody[] = {NOTE_B3, NOTE_C4, NOTE_B3, NOTE_D4, NOTE_A4, NOTE_B3, NOTE_B3, NOTE_G4, NOTE_D4, NOTE_B3, NOTE_D4, NOTE_C4, NOTE_B3, 0};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {8, 8, 48, 8, 8, 64, 8, 8, 8, 8, 16, 16, 16, 96};

void setup() {
  pinMode(spk_pin, OUTPUT);
 
  // iterate over the notes of the melody:
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    tone(spk_pin, melody[thisNote],noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(spk_pin);
  }
}

void loop() {
  // no need to repeat the melody.
}

richteel
 
Posts: 6
Joined: Fri Aug 31, 2012 11:04 pm

Re: My Doctor Who MonoChron Clock

by mulveyr on Sun Mar 02, 2014 6:16 pm

DanSlage wrote:I am working on a Doctor Who inspired clock for the MonoChron. A video can be seen here. http://youtu.be/DHecR3Matss

The TARDIS travels through an wiggly wormhole. Pressing a button or switch (except "Menu") will cause the TARDIS to dematerialize and rematerialize a moment later in a random spot. My daughter plans on using this as her primary alarm clock once I figure out how to replace the alarm siren with the Doctor Who theme song.

I had to rewrite the wormhole code a few times to get it fast enough render correctly. The GLCD.h drawing routines are way too slow instead the wormhole uses glcdDataWrite()s directly to draw everything.

To speed things up I also EXTERMINATEd all division and modulus operations. For example to separate the hour into a high digit and low digit:

Traditional

Code: Select all | TOGGLE FULL SIZE
high_digit = hour/10;
low_digit = hour%10;

I found this to be much faster

Code: Select all | TOGGLE FULL SIZE
high_digit = 0;
low_digit = hour;
while (low_digit >= 10) {  // Count tens
  high_digit++;
  low_digit -= 10;
}

When you have as much motion as this clock does every clock cycle counts.


Is there somewhere where we can download the compiled firmware? My son has a Monochron and would like to try the clock out.

Thanks!

- Rich
mulveyr
 
Posts: 12
Joined: Thu Dec 26, 2013 5:03 pm

Re: My Doctor Who MonoChron Clock

by DanSlage on Fri May 02, 2014 9:13 am

Sorry I haven't checked this thread in a while. My Doctor Who Monochron is still one of my favorite clocks. The laptop I used to program the clock broke but I will look through my backup files. If I can recover the code I will post it here.
DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm