yaDCF77 Yet another DCF77 Sketch.

Nothing exciting.

Just because I bought a "DCF-Empfänger BN 641138", I wrote a sketch for my Duemilanove.

To keep it simple I wanted to do it without the "The DCF77 Library" and without interrupts.
I followed this
http://thijs.elenbaas.net/2012/04/arduino-dcf77-radio-clock-receiver-hardware-2/
wiring diagram. I used the 10k pull-up resistor but had no capacitor to decouple from noise. So I do compensate noise by software.

The sketch is optimized for lines of code not for a small HEX file.

#define DCF77PIN 2

long t0, lastTick;
int dataSignal, bitCount;
int lastSignal;
int minute, hour, day, dow, month, year;
int parity, error;

void setTime(int bitCount, int bitValue) {
  Serial.print(bitValue);
  switch(bitCount) {
    case 0:  error=bitValue;    Serial.print(error?"!": "-"); break;
    case 14:
    case 19: Serial.print("-"); break;
    case 20: error|=bitValue^1; Serial.print((bitValue^1)?"!": "-"); break;
    
    case 21: minute =   bitValue; parity =bitValue; break;
    case 22: minute+= 2*bitValue; parity^=bitValue; break;
    case 23: minute+= 4*bitValue; parity^=bitValue; break;
    case 24: minute+= 8*bitValue; parity^=bitValue; break;
    case 25: minute+=10*bitValue; parity^=bitValue; break;
    case 26: minute+=20*bitValue; parity^=bitValue; break;
    case 27: minute+=40*bitValue; parity^=bitValue; break;
    case 28: parity^=bitValue; error|=parity; Serial.print(parity?"!": "-"); break;
    
    case 29: hour   =   bitValue; parity =bitValue; break;
    case 30: hour  += 2*bitValue; parity^=bitValue; break;
    case 31: hour  += 4*bitValue; parity^=bitValue; break;
    case 32: hour  += 8*bitValue; parity^=bitValue; break;
    case 33: hour  +=10*bitValue; parity^=bitValue; break;
    case 34: hour  +=20*bitValue; parity^=bitValue; break;
    case 35: parity^=bitValue; error|=parity; Serial.print(parity?"!": "-"); break;
    
    case 36: day    =   bitValue; parity =bitValue; break;
    case 37: day   += 2*bitValue; parity^=bitValue; break;
    case 38: day   += 4*bitValue; parity^=bitValue; break;
    case 39: day   += 8*bitValue; parity^=bitValue; break;
    case 40: day   +=10*bitValue; parity^=bitValue; break;
    case 41: day   +=20*bitValue; parity^=bitValue; Serial.print("-"); break;
     
    case 42: dow    =   bitValue; parity ^= bitValue; break;
    case 43: dow   += 2*bitValue; parity ^= bitValue; break;
    case 44: dow   += 4*bitValue; parity ^= bitValue; Serial.print("-"); break;
     
    case 45: month  =   bitValue; parity^=bitValue; break;
    case 46: month += 2*bitValue; parity^=bitValue; break;
    case 47: month += 4*bitValue; parity^=bitValue; break;
    case 48: month += 8*bitValue; parity^=bitValue; break;
    case 49: month +=10*bitValue; parity^=bitValue; Serial.print("-"); break;
     
    case 50: year   =   bitValue; parity^=bitValue; break;
    case 51: year  += 2*bitValue; parity^=bitValue; break;
    case 52: year  += 4*bitValue; parity^=bitValue; break;
    case 53: year  += 8*bitValue; parity^=bitValue; break;
    case 54: year  +=10*bitValue; parity^=bitValue; break;
    case 55: year  +=20*bitValue; parity^=bitValue; break;
    case 56: year  +=40*bitValue; parity^=bitValue; break;
    case 57: year  +=80*bitValue; parity^=bitValue; break;
    case 58: parity^=bitValue; error|=parity; Serial.print(parity?"! ": "  "); break;
  }
}

void printTime(int error) {
  char * dowName[] = {"????", "Mon  ", "Tues ", "Wed  ", "Thurs", "Fri  ", "Sat  ", "Sun  "};
  Serial.print(dowName[dow]); Serial.print(" "); 
  Serial.print(day);  Serial.print("."); Serial.print(month); Serial.print("."); Serial.print(year); Serial.print(" "); 
  Serial.print(hour); Serial.print(":"); Serial.print(minute);
  Serial.println(error?" (error)": " (ok)");
}
 
void setup(void) {
  Serial.begin(9600);
  while (!Serial) {};
  pinMode(DCF77PIN, INPUT);
  Serial.println("DCF77");
}

void loop(void) {
  int signal = digitalRead(DCF77PIN);
  if (lastSignal != signal) {
    long t1 = millis();

    if (signal == 0) {
      dataSignal += (int) (t1 - t0);
    } else {
      if (t1 - lastTick > ((bitCount == 58)?1900:900)) {
        setTime(bitCount, dataSignal / 160);

        bitCount++;
        if (bitCount > 58 || t1 - lastTick > 1500) {
          printTime(error||bitCount<=58);
          bitCount = 0;
        }
        dataSignal = 0;

        lastTick = t1;
      }
    }
    
    t0 = t1;
    lastSignal = signal;
  }
}