Arduino and atomic clock (WWVB) receiver

Here's an edge triggered method for decoding the pulses

/**********************************************************************
 * Clock WWVB Data Decode Edge Triggered  by capt.tagon
 *
 * WWVB receiver input on digital pin 2
 **********************************************************************/

#define wwvbIn      2  // WWVB receiver data input digital pin
#define ledRxPin    4  // WWVB receiver state indicator pin
#define ledFramePin 6  // Data received frame indicator pin
#define ledBitPin   5  // LED data decoded indicator pin
#define ledMarkPin  7  // Data received mark inicator pin

// variable changed by interrupt service routine - volatile
volatile byte wwvbInState;            // store receiver signal level

byte prevWwvbInState;                 // store previous signal level
unsigned int prevEdgeMillis;          // store time signal was read
byte bitVal;                          // bit decoded 0, 1 or Mark
byte badBit;                          // bad bit, noise detected
byte prevMark;                        // store previous mark bit

void setup() {
  pinMode(wwvbIn, INPUT);
  pinMode(ledRxPin, OUTPUT);
  pinMode(ledFramePin, OUTPUT);
  pinMode(ledBitPin, OUTPUT);
  pinMode(ledMarkPin, OUTPUT);
  attachInterrupt(0, readLevel, CHANGE); // fire interrupt on edge detected
  Serial.begin(9600);
  lcdInit();
}

void loop() {
  if (wwvbInState != prevWwvbInState) {
    pulseValue();
    prevWwvbInState = wwvbInState;
  }
}

/******************************************************************
 * pulseValue()
 *
 * determine pulse width 200ms = 0, 500ms = 1, 800ms = mark
 ******************************************************************/

void pulseValue() {
  unsigned int edgeMillis = millis();         // save current time
  badBit = 0;                                 // set noise counter to zero
  if (wwvbInState == 1) {                     // rising edge
    prevEdgeMillis = edgeMillis;              // set previous time to current
  } 
  else {                                    // falling edge
    int pulseLength = edgeMillis - prevEdgeMillis; // calculate pulse length millis
    if (pulseLength < 100) {                  // less than 100ms, noise pulses
      badBit = 1;
    } 
    else if (pulseLength < 400) {           // 800ms carrier drop mark
      bitVal = 2;
    } 
    else if (pulseLength < 700) {           // 500ms carrier drop one
      bitVal = 1;
    } 
    else {                                  // 200ms carrier drop zero
      bitVal = 0;
    }
    if (badBit == 0) {
      printBitVal();
    }
  }
}

/******************************************************************************
 * readLevel() {
 *
 * Pin 2 INT0 Interrupt Handler Reads pin state - flashes signal indicator LED
 ******************************************************************************/

void readLevel() {
  wwvbInState = digitalRead(wwvbIn);   // read signal level
  digitalWrite(ledRxPin, wwvbInState); // flash WWVB receiver indicator pin
}

/******************************************************************************
 * printBitVal()
 *
 * Display bit values to terminal screen, output delimited data stream with 
 * colons at mark and new line at frame start.
 ******************************************************************************/

void printBitVal() {
  if ((bitVal == 2) && (prevMark == 0)) {
    Serial.print(" : ");
    digitalWrite(ledMarkPin, HIGH);
    prevMark = 1;
  } 
  else if ((bitVal == 2) && (prevMark == 1)) {
    Serial.print("\nBit Value: ");
    Serial.print("| ");
    digitalWrite(ledFramePin, HIGH);
    prevMark = 0;
  } 
  else {
    Serial.print(bitVal, DEC);
    digitalWrite(ledMarkPin, LOW);
    digitalWrite(ledFramePin, LOW);
    if (bitVal == 0) { 
      digitalWrite(ledBitPin, LOW); 
    }
    if (bitVal == 1) { 
      digitalWrite(ledBitPin, HIGH); 
    }
    prevMark = 0; 
  }
}

/*****************************************************************************
 * Time display functions
 *****************************************************************************/

void printTime() {
  Serial.print("?x00?y0?f"); // movie cursor to line 1 char 1, clear screen
}

// LCD routines to initialize LCD and clear screen
void lcdInit() {           // using P H Anderson Serial LCD driver board
  Serial.print("?G216");   // configure driver for 2 x 16 LCD
  delay(300);
  Serial.print("?BDD");    // set backlight brightness
  delay(300);
  Serial.print("?f");      // clear screen
  Serial.print("?c0");     // set cursor off
}