My Doctor Who MonoChron Clock

For RTC breakouts, etc., use the Other Products from Adafruit forum

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm

My Doctor Who MonoChron Clock

Post by DanSlage »

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

high_digit = hour/10;
low_digit = hour%10;
I found this to be much faster

Code: Select all

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.

User avatar
adafruit_support_bill
 
Posts: 88090
Joined: Sat Feb 07, 2009 10:11 am

Re: My Doctor Who MonoChron Clock

Post by adafruit_support_bill »

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

odometer
 
Posts: 98
Joined: Sun Aug 21, 2011 11:01 pm

Re: My Doctor Who MonoChron Clock

Post by odometer »

What datatype is "hour"?

This is good up to 99:

Code: Select all

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;}

DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm

Re: My Doctor Who MonoChron Clock

Post by DanSlage »

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.

User avatar
nicodemus_nj
 
Posts: 2
Joined: Wed Apr 27, 2011 11:36 am

Re: My Doctor Who MonoChron Clock

Post by nicodemus_nj »

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

:)

User avatar
kscharf
 
Posts: 277
Joined: Wed Sep 10, 2008 10:29 am

Re: My Doctor Who MonoChron Clock

Post by kscharf »

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
jakes
 
Posts: 13
Joined: Tue Feb 22, 2011 12:15 pm

Re: My Doctor Who MonoChron Clock

Post by jakes »

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

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);  
    }                                
  }                                 
}

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Re: My Doctor Who MonoChron Clock

Post by adafruit »

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

User avatar
richteel
 
Posts: 16
Joined: Fri Aug 31, 2012 11:04 pm

Re: My Doctor Who MonoChron Clock

Post by richteel »

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

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

/*
  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.
}

User avatar
mulveyr
 
Posts: 12
Joined: Thu Dec 26, 2013 5:03 pm

Re: My Doctor Who MonoChron Clock

Post by mulveyr »

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

high_digit = hour/10;
low_digit = hour%10;
I found this to be much faster

Code: Select all

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

DanSlage
 
Posts: 4
Joined: Thu Jan 26, 2012 4:29 pm

Re: My Doctor Who MonoChron Clock

Post by DanSlage »

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.

Locked
Please be positive and constructive with your questions and comments.

Return to “Clock Kits (discontinued)”