Go Down

Topic: DFC77 Library on AtTiny85 (which interrupt?) (Read 942 times) previous topic - next topic

kolbenbrenner

Hello

I am not quiet new to Arduino, but new to this Forum and new to the AtTiny85.

I have programmed a simple Text-Clock using a DFC77 Module to read the Time-Signal.
Everything works fine on the Arduino, but when I transfer it to the AtTiny85, the Signal can not be read.

That I could sucessfully load store the Programm on the AtTiny85 is proved by the output LEDs. But the Signal that comes in (DFC) is not read by the DFC77.h-Library.

I have changed the PIN from 2 and the Interrupt from 0 so they have new numbers on the ATTiny.
I tried
PIN PB2 Inetrrupt 0
PIN PB2 Interrupt 2
PIN PB1 Interrupt 1

none of these worked.

Here is my sketch (unfortunately some german in it):

Code: [Select]

#include "Time.h"
#include "DCF77.h"

// ARDUINO UNO Belegung (Achtung: für den AtTiny45 neu belegen!)
/*
#define DCF_PIN           2 // Diesen Digital-PIN mit dem DCF verbinden
                            // Benutze dazu einen 10k Pull-UP Widerstand zum 5V-Anschluss.
#define DCF_INTERRUPT     0 // Interrupt zum DCF_PIN                               

#define SHIFT_DATA_PIN    8 //
#define SHIFT_RCLK_PIN    9 // LATCH (shift all data out)
#define SHIFT_SRCLK_PIN  10 // CLOCK
*/

// Hier die Modifikation für den ATTiny85. Auf dem ATTiny45 hatte
// der Sketch keinen Platz:inkl. Time und DCF-Library komme ich
// auf 5k statt 4k.

#define DCF_PIN           1 // PB1 = PIN NR 6 (to DCF data)
#define DCF_INTERRUPT     1 // PCINT1 liegt beim ATTiny auf PB1 (= pin 6)
#define SHIFT_DATA_PIN    0 // PB0 = PIN NR 5 (to 1. shift reg pin 14)
#define SHIFT_RCLK_PIN    2 // PB2 = PIN NR 7 (to 1. shift reg pin 13)
#define SHIFT_SRCLK_PIN   3 // PB3 = PIN NR 2 (to 1. shifg reg pin 12)


#define SHIFT_NUM_REGISTERS  3
#define SHIFT_NUM_PINS       (8*SHIFT_NUM_REGISTERS)
                           


#define HOUR_CHECK_DIFF      3


boolean data[SHIFT_NUM_PINS]; // 0..23 (Benutzt sind 22 Stück nämlich von 0 bis 21)

time_t time;
// Nicht invertiert, daher "true"
DCF77 DCF = DCF77(DCF_PIN, DCF_INTERRUPT, true);

void setup() {
  // PINS als "out" festlegen für die Ansteuerung des 1. Shift-Registers:
  pinMode(SHIFT_DATA_PIN , OUTPUT);
  pinMode(SHIFT_RCLK_PIN , OUTPUT);
  pinMode(SHIFT_SRCLK_PIN, OUTPUT);

// DCF77 Starte das Funkuhr Modul
  DCF.Start();
}


#define NEVER_SYNCED -1
int     lastSyncHour = NEVER_SYNCED; // Nur beim ersten Start auf NEVER_SYNCED
boolean timeValid    = false       ;

void updateTime() {
  // Prüfe erst nach HOUR_CHECK_DIFF Stunden.
  if(hasToCheckDCF()) {
    time_t dcfTime = DCF.getTime();
    if(0 != dcfTime) {
      setTime(dcfTime);
      timeValid = true;
      lastSyncHour = hour(); 
    }
  }
}

boolean hasToCheckDCF() {
  if(! timeValid)                  {return true;}
  if(NEVER_SYNCED == lastSyncHour) {return true;}

  int now = hour();
  int diff = now - lastSyncHour;
  if(diff < 0) {
    diff = diff + 12; // 1 = 13 Uhr
  }
  boolean hasToCheck = diff > HOUR_CHECK_DIFF;
  if(hasToCheck) {
    timeValid = false;
  }
  return hasToCheck;
}

void loop() {
  delay(1000);
  updateTime();
  ledShiftOut(hour(), minute());
}

// PIN Numbers starting with 0 on Shift-Register 1
#define LED_MIN_FUENF   13
#define LED_MIN_ZEHN    14
#define LED_MIN_VIERTEL 15
#define LED_MIN_ZWANZIG 16
#define LED_VOR         17
#define LED_NACH        18
#define LED_HALB        19
#define LED_PUNKT       20
#define LED_INVALID     21
#define LED_VALID        0

// not realy used, because the variable "hour" means the same
/*
#define LED_EINS         1
#define LED_ZWEI         2
#define LED_DREI         3
#define LED_VIER         4
#define LED_FUENF        5
#define LED_SECHS        6
#define LED_SIEBEN       7
#define LED_ACHT         8
#define LED_NEUN         9
#define LED_ZEHN        10
#define LED_ELF         11
#define LED_ZWOELF      12
*/

void ledShiftOut(int hour, int min) {
  clearData();
ledON(timeValid ? LED_VALID : LED_INVALID);

  // fallback: time definitive not valid
  if (year() < 2000) {
    writeData();
    timeValid = false;
    return;
  }
 
  hour = hour % 12;
  if(0 == hour) {
    hour = 12;
  }
  if(min > 23) {
    ledON((hour) % 12 + 1);
  } else {
    ledON(hour);
  }
 
  if     (zeitNaheAn(min,  5)) { ledON(LED_MIN_FUENF  );  ledON(LED_NACH);                  }
  else if(zeitNaheAn(min, 10)) { ledON(LED_MIN_ZEHN   );  ledON(LED_NACH);                  }
  else if(zeitNaheAn(min, 15)) { ledON(LED_MIN_VIERTEL);  ledON(LED_NACH);                  }
  else if(zeitNaheAn(min, 20)) { ledON(LED_MIN_ZWANZIG);  ledON(LED_NACH);                  }
  else if(zeitNaheAn(min, 25)) { ledON(LED_MIN_FUENF  );  ledON(LED_VOR ); ledON(LED_HALB); }
  else if(zeitNaheAn(min, 30)) { ledON(LED_HALB       );                                    }
  else if(zeitNaheAn(min, 35)) { ledON(LED_MIN_FUENF  );  ledON(LED_NACH); ledON(LED_HALB); }
  else if(zeitNaheAn(min, 40)) { ledON(LED_MIN_ZWANZIG);  ledON(LED_VOR );                  }
  else if(zeitNaheAn(min, 45)) { ledON(LED_MIN_VIERTEL);  ledON(LED_VOR );                  }
  else if(zeitNaheAn(min, 50)) { ledON(LED_MIN_ZEHN   );  ledON(LED_VOR );                  }
  else if(zeitNaheAn(min, 55)) { ledON(LED_MIN_FUENF  );  ledON(LED_VOR );                  }
  else    /* >=59 && <= 3 */   { ledON(LED_PUNKT      );                                    }
 
  writeData();
}


boolean zeitNaheAn(int min, int fuenfMinutenGenauigkeit) {
    return min >= fuenfMinutenGenauigkeit - 1 && min < fuenfMinutenGenauigkeit + 4;
}

void ledON(int ledShifterNr) {
  data[ledShifterNr] = true;
}

/** Lösche den data-Array (alle auf false setzen).
/*  Achtung: Diese Subroutine schreibt nur den data-Array aber
/*           die Dioden werden dabei noch nicht angesteuert!
 *           Sollen die Dioden auch angesteuert werden, dann
 *           muss explizit "writeData()" aufgerufen werden.
 */
void clearData() {
  for(int i = SHIFT_NUM_PINS - 1; i >= 0; i = i - 1) {
     data[i] = false;
  }
}

/** Schreibe alle Daten in die Shift-Register.
 *  Sobald alle Daten geschrieben sind, weise die Register an,
 *  die Daten auch anzuzeigen (SHIFT_RCLK_PIN).
 */
void writeData() {
  digitalWrite(SHIFT_RCLK_PIN, LOW);
  int val;
  for(int i = SHIFT_NUM_PINS - 1; i >=  0; i = i - 1) {
    digitalWrite(SHIFT_SRCLK_PIN, LOW);
    val = data[i];
    digitalWrite(SHIFT_DATA_PIN , val );
    digitalWrite(SHIFT_SRCLK_PIN, HIGH);
  }
  digitalWrite(SHIFT_RCLK_PIN, HIGH); // latch
}

// end sketch


Has anyone made successful tests with ATTiny85-Interrupts or even better with the DCF77.h-Library on an ATTiny?

thanks in advance


derVernichter

I did not check the attiny datasheet for external interrupts, but I suggest doing so.

Furthermore, I had problems with a module not providing enough signal power to the output such that I could not read it with an arduino nano (although the mega worked pretty fine). Try observing the dcf signal via an oscilloscope or at least let an led blink on received dcf signals. If there is none, try amplifying the signal (e.g. via a simple transistor [you might need to invert the signal by software] circuit or using an opamp [e.g. as a schmitt trigger or just open loop]).

Go Up