Forum: Mikrocontroller und Digitale Elektronik DCF77-Signalauswertung mit ATmega32


von Jens K. (mister232)


Lesenswert?

Hallo Leute,

versuche mich gerade daran das Signal eines DCF77-Moduls von Reichelt 
auszuwerten und die aktuelle Zeit per serielle Schnittstelle an einen 
Computer zu senden. Am PC empfange ich auch etwas, nur leider nicht die 
aktuelle Zeit. Er zählt einfach die Sekunden hoch und zeigt mir den 
aktuellen Stand an. Hier mal die main-Datei und die Datei in welcher das 
Signal ausgewertet wird:
1
/*
2
 * main.c
3
 *
4
 * Created: 27.02.2014 13:27:29
5
 *  Author: Jens
6
 *
7
 * This program receives the DCF77 signal from a DCF77-Module from Reichelt and evaluates the
8
 * received data. The calculated time will be transmitted to a computer via UART. The program
9
 * is written for an ATmega32 device
10
 *
11
 */ 
12
13
#include "global.h"
14
#include "uart.h"
15
#include "DCF77.h"
16
#include <avr/io.h>
17
#include <avr/interrupt.h>
18
#include <util/delay.h>
19
#include <stdio.h>
20
#include <string.h>
21
22
int main(void)
23
{
24
  char msgBuffer[100];
25
  
26
  // Initialize the UART-Interface with 4800 baud
27
  init_UART(4800);
28
  strcpy(msgBuffer, "*********** DCF77-Clock **************\n");
29
  uart_write_msg(msgBuffer,strlen(msgBuffer));
30
  
31
  // Enable global interrupts
32
  sei();
33
  
34
  // Start DCF77 clock
35
  strcpy(msgBuffer, "Starting clock...");
36
  uart_write_msg(msgBuffer,strlen(msgBuffer));
37
  Start_Clock();
38
  strcpy(msgBuffer, "Done\n");
39
  uart_write_msg(msgBuffer,strlen(msgBuffer));
40
  
41
  while(1)
42
  {
43
    // Transmit actual time to the computer
44
    sprintf(msgBuffer, "Time: %i:%i:%i \n", hh, mm, ss);
45
    uart_write_msg(msgBuffer,strlen(msgBuffer));
46
    
47
    // Wait
48
    _delay_ms(1000);
49
  }
50
  
51
  return 0;
52
}
1
/*
2
 * DCF77.c
3
 *
4
 * Created: 27.02.2014 00:10:17
5
 *  Author: Jens
6
 *
7
 * This file includes control functions for the use of a DCF77 module from Reichelt
8
 *
9
 */ 
10
11
#include "DCF77.h"
12
#include "global.h"
13
#include <avr/io.h>
14
#include <avr/interrupt.h>
15
16
volatile unsigned char ss   = 0;   // Seconds
17
volatile unsigned char mm   = 0;   // Minutes
18
volatile unsigned char hh   = 0;   // Hours
19
20
// Bit-counter for RX bit
21
volatile unsigned char rx_bit_counter = 0;
22
23
// 64 Bit, for DCF77 used 59 Bits
24
volatile unsigned long long dcf_rx_buffer = 0;
25
26
// Help-counter for seconds
27
volatile unsigned int h_ss = 0;
28
29
// Help-variable for hour-change
30
volatile unsigned int h_hh = 0;
31
32
// Timer1 overflow Interrupt, triggered by 59. second or no received DCF77 signal
33
ISR(TIMER1_OVF_vect)
34
{
35
  struct  DCF77_Bits *rx_buffer;
36
  rx_buffer = (struct DCF77_Bits*)(char*)&dcf_rx_buffer;
37
  
38
  // Reset timer
39
  TCNT1 = 65535 - (F_CPU / 1024);
40
  
41
  // If all 59 Bits and the parity's are correctly received, set clock to DCF77 signal
42
  if ((rx_bit_counter == 59) && (flags.parity_P1 == rx_buffer->P1) && (flags.parity_P2 == rx_buffer->P2) && (flags.parity_P3 == rx_buffer->P3))
43
  {
44
    // Calculate minutes BCD to HEX
45
    mm = rx_buffer->Min - ((rx_buffer->Min / 16) * 6);
46
    
47
    if(mm != 0)
48
    {
49
      mm--;
50
    }
51
    else
52
    {
53
      mm = 59; 
54
      h_hh = 1;
55
    }
56
    
57
    // Calculate hours BCD to HEX
58
    hh = rx_buffer->Hour - ((rx_buffer->Hour / 16) * 6);
59
60
    if(h_hh)
61
    {
62
      hh--;
63
      h_hh = 0;
64
    }
65
66
    // Reset seconds to zero
67
    ss = 59;
68
    flags.dcf_sync = 1;
69
  }
70
  else
71
  {
72
    // Manually set the clock 
73
    Add_one_Second();
74
    flags.dcf_sync = 0;
75
  }
76
  
77
  // Reset the RX Bit-Counter
78
  rx_bit_counter = 0;
79
  // Clear the RX buffer
80
  dcf_rx_buffer = 0;
81
}
82
83
// Interrupt on INT0, DCF77 Module receives time information
84
ISR(INT0_vect)
85
{
86
  // Evaluate pulse width
87
  if(INT0_CONTROL == INT0_RISING_EDGE)
88
  {
89
    flags.dcf_rx ^= 1;
90
    
91
    // Calculate second help-counter
92
    h_ss = h_ss + TCNT1 - (65535 - (F_CPU / 1024));
93
    // Reset timer
94
    TCNT1 = 65535 - (F_CPU / 1024);
95
    
96
    // Check if a second is over
97
    if(h_ss > (F_CPU / 1024 / 100 * 90)) //90% from 1 second
98
    {
99
      Add_one_Second();
100
      // Reset second help-counter
101
      h_ss = 0;
102
    }
103
    
104
    // Next interrupt with falling edge
105
    INT0_CONTROL = INT0_FALLING_EDGE;
106
  }
107
  else
108
  {
109
    // Read pulse width from rising edge to falling edge
110
    unsigned int pulse_wide = TCNT1;
111
    // Reset timer
112
    TCNT1 = 65535 - (F_CPU / 1024);
113
    // Calculate second help-counter
114
    h_ss = h_ss + pulse_wide - (65535 - (F_CPU / 1024));
115
    
116
    //Safe parity:
117
    // Begin area P1/P2/P3
118
    if((rx_bit_counter ==  21) || (rx_bit_counter ==  29) || (rx_bit_counter ==  36))
119
    {
120
      flags.parity_err = 0;
121
    }
122
    // Safe P1
123
    if(rx_bit_counter ==  28)
124
    {
125
      flags.parity_P1 = flags.parity_err;
126
    }
127
    //Safe P2
128
    if(rx_bit_counter ==  35)
129
    {
130
      flags.parity_P2 = flags.parity_err;
131
    }
132
    //Safe P3
133
    if(rx_bit_counter ==  58)
134
    {
135
      flags.parity_P3 = flags.parity_err;
136
    }
137
    
138
    // Check if a 0 or 1 is received
139
    //0 = 100 ms
140
    //1 = 200 ms
141
    // > 150ms (15% from 1 second -> 150ms)
142
    if(pulse_wide > (65535 - (F_CPU / 1024) / 100 * 85))
143
    {
144
      // Write a 1 into the dcf_rx_buffer at position rx_bit_counter
145
      dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) 1 << rx_bit_counter);
146
      //Toggle Help-Parity
147
      flags.parity_err = flags.parity_err ^ 1;
148
    }
149
    
150
    // Next interrupt with rising edge
151
    INT0_CONTROL = INT0_RISING_EDGE;
152
    // Inkrement RX Bit-Counter
153
    rx_bit_counter++;
154
  }
155
}
156
157
// Function to add a second to the actual time value
158
void Add_one_Second (void)
159
{
160
  ss++;
161
  
162
  // Check if a minute is done
163
  if (ss == 60)
164
  {
165
    ss = 0;
166
    mm++;
167
    
168
    // Check if a hour is done
169
    if (mm == 60)
170
    {
171
      mm = 0;
172
      hh++;
173
      
174
      // Check if the day is finished
175
      if (hh == 24)
176
      {
177
        hh = 0;
178
      }
179
    }
180
  }
181
};
182
183
// Function to initialize and start the timer
184
void Start_Clock (void)
185
{
186
  // Enable interrupt on DCF77 with rising edge
187
  DCF77_INT_ENABLE();
188
  INT0_CONTROL = INT0_RISING_EDGE;
189
  
190
  // Interrupt overflow enable
191
  TIMSK1 |= (1 << TOIE1);
192
  // Set prescaler to 1024
193
  TCCR1B |= (1<<CS10 | 0<<CS11 | 1<<CS12);
194
  TCNT1 = 65535 - (F_CPU / 1024);
195
}

Und der Header zur Signalauswertung:
1
/*
2
 * DCF77.h
3
 *
4
 * Created: 27.02.2014 10:20:46
5
 *  Author: Jens
6
 */ 
7
8
9
#ifndef DCF77_H_
10
#define DCF77_H_
11
12
volatile unsigned char ss;  // Seconds
13
volatile unsigned char mm;  // Minutes
14
volatile unsigned char hh;  // Hours
15
16
extern void Start_Clock (void); // Function to start the DCF77-Clock
17
extern void Add_one_Second (void); // Function to add one second to the actual time
18
19
// 64 Bit, for DCF77 used 59 Bits
20
volatile unsigned long long dcf_rx_buffer;
21
// RX Pointer (Counter)
22
volatile extern unsigned char rx_bit_counter;
23
// Help-Counter for seconds
24
volatile unsigned int h_ss;
25
26
// INT0 Interrupt definitions
27
#define DCF77_INT_ENABLE()  GICR |= (1<<INT0);
28
#define INT0_CONTROL    MCUCR
29
#define INT0_FALLING_EDGE  0x02
30
#define INT0_RISING_EDGE  0x03
31
#define TIMSK1         TIMSK
32
33
//Structure of the dcf_rx_buffer
34
struct  DCF77_Bits {
35
  unsigned char M          :1  ;
36
  unsigned char O1      :1  ;
37
  unsigned char O2      :1  ;
38
  unsigned char O3      :1  ;
39
  unsigned char O4      :1  ;
40
  unsigned char O5      :1  ;
41
  unsigned char O6      :1  ;
42
  unsigned char O7      :1  ;
43
  unsigned char O8      :1  ;
44
  unsigned char O9      :1  ;
45
  unsigned char O10      :1  ;
46
  unsigned char O11      :1  ;
47
  unsigned char O12      :1  ;
48
  unsigned char O13      :1  ;
49
  unsigned char O14      :1  ;
50
  unsigned char R          :1  ;
51
  unsigned char A1      :1  ;
52
  unsigned char Z1      :1  ;
53
  unsigned char Z2      :1  ;
54
  unsigned char A2      :1  ;
55
  unsigned char S          :1  ;
56
  unsigned char Min      :7  ;// 7 Bits for minutes
57
  unsigned char P1      :1  ;// Parity minutes
58
  unsigned char Hour      :6  ;// 6 Bits for hours
59
  unsigned char P2      :1  ;// Parity hours
60
  unsigned char P3      :1  ;// Parity from P2
61
};
62
63
struct
64
{
65
  volatile char parity_err        :1  ;// Help Parity
66
  volatile char parity_P1          :1  ;// Calculated Parity P1
67
  volatile char parity_P2          :1  ;// Calculated Parity P2
68
  volatile char parity_P3          :1  ;// Calculated Parity P3
69
  volatile char dcf_rx          :1  ;// A impulse is received
70
  volatile char dcf_sync          :1  ;// The clock was synchronized in the last minute
71
}flags;
72
73
#endif /* DCF77_H_ */

Ich hoffe ihr könnt mir weiterhelfen ;)

Gruß
Mister232

von Karl H. (kbuchegg)


Lesenswert?

Du hast eine UART und die funktioniert auch.
Da würde ich doch glatt mal anfangen, den Mega nicht die aktuelle Zeit 
ausgeben zu lassen, sondern an strategisch günstigen Positionen ein paar 
der ermittelten Kennwerte in der ISR.
Anfangen würde ich damit, mir die ermittelten Pulslängen ausgeben zu 
lassen, bzw. ob der Mega überhaupt in die ISR reinkommt.

Du hast eine UART. Benutze sie!
Man kann und darf die benutzen um sich nicht nur die Endergebnisse 
ausgeben zu lassen, sondern auch Zwischenergebnisse bzw. auch mal ein 
oder 2 Sonderzeichen, mit denen man verfolgen kann, ob bestimmte 
Programmpfade genommen werden oder nicht.

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

Also ich habe gerade mal ausprobiert eine LED blinken zu lassen wenn ich 
in die INT0 ISR rein gehe. Beim einschalten blinkt sie einmal, dann 
nicht mehr. Könnte es sein das ich keinen Empfang habe? Habe es schon an 
verschiedenen Positionen ausprobiert, mit dem selben Ergebnis.

von Martin S. (tungl)


Lesenswert?

Ohne jetzt deinen Code genauer angeschaut zu haben: Hast du den Ausgang 
Deines Reichelt-Moduls direkt an den Mega32 gehängt? Hatte ich naemlich 
damals auch zuerst so gemacht, aber das Teil ist mega-empfindlich, 
sodass es direkt gar nicht funktioniert hat.

von Jens K. (mister232)


Lesenswert?

Ja, ist direkt damit verbunden. Wie hast du es denn dann gemacht?

von Martin S. (tungl)


Lesenswert?

Ok, so ging's bei mir auch nicht. Anscheinend ist das Modul sogar dazu 
zu schwach, genug Strom fuer den internen Pull-Up des ATMega zu liefern. 
Hatte da damals einen Transistor dazwischen gesetzt, danach ging es. 
Genaue Schaltung bzw. Dimensionierung hab ich leider nicht mehr im Kopf.

von Stefan F. (Gast)


Lesenswert?

>  Könnte es sein das ich keinen Empfang habe?

Das kannst Du mit einer LED direkt am DC-Modul (eventuell über einen 
Transistor zur Verstärkung) ganz schnell herausfinden. Die Kontroll-LED 
würde ich für immer an der Schaltung dran lassen, kann immer mal 
nützlich sein. Man sieht sofort, ob Empfang vorhanden ist und ob er gut 
genug ist. Bei schlechtem Empfang flackert die LED unregelmäßig.

von Jens K. (mister232)


Lesenswert?

So: Ich habe das Reichelt-Modul jetzt durch ein wesentlich stabileres 
Modul von ELV ausgetauscht. Nun blinkt die LED, welche mir signalisiert 
das ein INT0 Interrupt aufgetreten ist, etwa im Sekundentakt.

Ich lasse mir nun im Terminal die Pulslänge ausgeben, doch leider 
erscheinen immer nur Werte um 6300 rum (+/- 150). Das heißt also das ich 
nur 1sen empfange?

von Jens K. (mister232)


Lesenswert?

Hat vielleicht jemand nen Link zu nehm funktionierenden Code?

von Karl H. (kbuchegg)


Lesenswert?

Nimms wie ein Mann.
Du hast viel zu viel Code auf einmal geschrieben und weisst jetzt nicht, 
wo du mit Fehlersuche anfangen sollst.

Daher zurück an den Anfang und noch mal von vorne.
Aber diesmal mit weniger Aufwand.

Erste Version
Interrupt auf beide Flanken, Timer durchlaufen lassen und in der ISR die 
Timerwerte ausgeben
1
ISR(INT0_vect)
2
{
3
  static uint16t last;
4
  uint16_t difference;
5
6
  difference = last - TCNT1;
7
  last = TCNT1;
8
9
  uart_put_uint( difference );
10
}

(100ms sollten eigentlich reichen, dass du in der ISR einen uint in 
ASCII Form ans Terminal schicken kannst, auch wenn man normalerweise 
keine Ausgaben in einer ISR macht. Das darf hier nicht zu lange dauern, 
denn die ISR muss fertig sein, ehe die nächste Flanke kommt)


Und dann siehst du dir mal die ermittelten Werte an.


Schlimmsten Falls müsste man sich die Grenzwerte ausrechnen und durch 
ein paar Vergleiche mit diesen Grenzwerten dann nur ein Kenn-Zeichen 
ausgeben
1
    if( difference < Border_for_Low )
2
       uart_putc( '0' );
3
    else if( difference < Border_for_Second_Marker )
4
       uart_putc( '1' );
5
    else
6
       uart_putc( '\n' );
Die tatsächlichen Werte wären allerdings besser. Kein zusätzlicher 
Schnickschnack. Da muss kein Text dabei stehen. Zahl und ein 
Leerzeichen, damit du die Zahlen richtig lesen kannst - das muss 
reichen. Du hast hier nicht die Zeit um da einen halben Roman 
hinzuschreiben.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> reichen. Du hast hier nicht die Zeit um da einen halben Roman
> hinzuschreiben.

Alternativ ginge noch, den Portpin abzufragen (nur weil der einen 
Interrupt auslöst, heißt das ja nicht, das man den nicht per PINx 
Register abfragen kann).

Die Ausgabe findet nur dann statt, wenn der Pin einen 0 Pegel hat (*). 
Denn dann ist der Puls vorbei und du hast theoretisch im schlimmsten 
Fall mindestens 0.8 Sekunden bis der nächste Puls beginnt. Und das 
sollte dann dicke reichen.

(*) unter der Annahme, dass das Modul active High Pulse liefert. Aber 
das müsstes du an der LED schon gesehen haben, ob die active High oder 
active Low sind.

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

Habe jetzt mal ne abgespeckte Version gebaut:
1
/*
2
 * main.c
3
 *
4
 * Created: 11.03.2014 18:56:52
5
 *  Author: Jens
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
#include <stdio.h>
12
#include <string.h>
13
#include "global.h"
14
#include "uart.h"
15
#include <util/delay.h>
16
17
char msgBuffer[100];
18
19
ISR (INT0_vect)
20
{
21
  // Show timer value
22
  sprintf(msgBuffer, "TCNT1: %u \n\r", TCNT1);
23
  uart_write_msg(msgBuffer,strlen(msgBuffer));
24
25
  // Reset timer counting register
26
  TCNT1 = 0x00;
27
}
28
29
30
31
int main(void)
32
{
33
  // Init uart
34
  init_UART(9600);
35
36
  // enable INT0
37
  GICR |= (1<<INT0);  
38
39
  // INT0 for both, rising and falling edge
40
  MCUCR |= (0<<ISC11) | (1<<ISC10);
41
  // Prescaler 1024
42
  TCCR1B |= (1<<CS12) | (1<<CS10);
43
44
  // Global enable interrupts
45
  sei();
46
47
  while(1);
48
  {
49
50
  }
51
  
52
  return 0;
53
}

Als Ausgabe kommt nur sehr schnell hintereinander 0 und manchmal 1. Ich 
habe zusätzlich noch eine LED direkt an den Ausgang des DCF-Moduls 
gehängt, diese blinkt nun im Sekundentakt (Signal scheint also okay zu 
sein)

von Karl H. (kbuchegg)


Lesenswert?

Dann schaltest du jetzt erst mal den Pin auf Eingang.

Nur weil du dein INT0 aktiviert hast, heisst das noch lange nicht, dass 
der entsprechende Pin damit automatisch auf Input gestellt ist.

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

Noch keine Veränderung:

TCNT1: 0 und manchmal 1

von Bernd (Gast)


Lesenswert?

Hallo Jens,
da Du den Zaehlerwert des Timer1 ausgibst, und der der nur 0 oder 1 ist,
würde ich mal testen, was rauskommst , wenn Du den Teilerfaktor von 
Timer1 änderst (z.B. 64). Dann muss der Zaehler doch weiterlaufen als 
bis 1.
Wie hoch ist denn Dein Mikrocontrollertakt ?.

Das DCF-Signal auswerten ist nicht das Problem, sonder ein ungestörtes 
Signal aus dem DCF Modul hin zu bekommen, wenn der Controller daran 
angeschlossen ist. Mit LED kann man es manchmal nicht sehen, besser mit 
Oszi.
Schau Dir mal hier die Info zu DCF von der WORDCLOCK an.

Gruß
Bernd

von André C. (clausi)


Lesenswert?

Hallo,

ich habe mal aus einer meiner Rollosteuerungen die relevanten Teile zur 
DCF-Zeit rausgeholt. Ich hoffe ich habe nichts vergessen. Lief 
eigentlich sehr gut mit einem Atmega8.

Habe gerade keine Zeit mich weiter reinzulesen, ich hoffe es reicht 
erstmal.

PS: das stammt noch aus meinen µC Anfangszeiten, also sorry für 
eventuelle Formfehler und sonstiges... ;-)






bool clock[60];
int clock_bit;
int cnt_clock;
bool first_clock=0;
bool clock_ok;

unsigned long uhrzeit;



//negative Flanke
  bool fl_neg(bool Variable, bool* flankenmerker)
  {
    int return_val=0;

    if (Variable==1)
    {
      (*flankenmerker)=1;
    }

    if ((Variable==0) && ((*flankenmerker)==1))
    {
      return_val=1;
      (*flankenmerker)=0;
    }

    return return_val;
  }






int main(void)
{

  DDRB=0xFE;
  PORTB=0x01;

  DDRD = 0x00;
  PORTD = 0xFF;

// Timer 1 konfigurieren
  TCCR1B = (1<<WGM12);
  TCCR1B |= (1<<CS11) | (1<<CS10); // CTC Modus
  // ((8000000/64)/1000) = 125
  OCR1A = 125-1;

  // Compare Interrupt erlauben
   TIMSK |= (1<<OCIE1A);

  // Global Interrupts aktivieren
  sei();


//Zyklisches Programm
    while (1)
  {

    if ((PINB & 0x01)>0)
    {
      PORTB |= (1<<PB1);
    }
    else
    {
      PORTB &= ~(1<<PB1);
    }

    if (first_clock)
    {
      PORTB &= ~(1<<PB2);
    }
    else
    {
      PORTB |= (1<<PB2);
    }

    if (clock_ok)
    {
      PORTB &= ~(1<<PB4);
    }
    else
    {
      PORTB |= (1<<PB4);
    }


/Uhrzeit decodieren
    if (clock_ok==1)
    {
      sekunde=0;
      minute=0;
      stunde=0;
      wochentag=0;


      for (int i=0; i<4; i++)
      {
        minute=minute+((clock[21+i])*(pot(2,i)));
        stunde=stunde+((clock[29+i])*(pot(2,i)));
      }

      for (int i=0; i<3; i++)
      {
        minute=minute+(((clock[25+i])*(pot(2,i)))*10);
        wochentag=wochentag+((clock[42+i])*(pot(2,i)));
      }

      for (int i=0; i<2; i++)
      {
        stunde=stunde+(((clock[33+i])*(pot(2,i)))*10);
      }

      clock_ok=0;
      cnt_clock=0;
      first_clock=0;

      wochentag--;

      time_to_long(&uhrzeit,stunde, minute, sekunde);
    }
  }
}




//Interrupt für Zeit
ISR (TIMER1_COMPA_vect)
{


//Funkzeit
  if (clock_ok==0)
  {
    cnt_clock++;

    if (fl_neg((PINB & 0x01)==1, &flanke.clock_input))
    {
      if (cnt_clock>1200)
      {
        if (first_clock)
        {
          clock_ok=1;
        }

        clock[0]=1;
        clock_bit=0;
        first_clock=1;
      }
      else
      {
        if (first_clock)
        {
          if (clock[clock_bit-1]==0)
          {
            if (cnt_clock<1050)
            {
              clock[clock_bit]=0;
            }

            if (cnt_clock>1050)
            {
              clock[clock_bit]=1;
            }
          }

          if (clock[clock_bit-1]==1)
          {
            if (cnt_clock>950)
            {
              clock[clock_bit]=1;
            }

            if (cnt_clock<950)
            {
              clock[clock_bit]=0;
            }
          }
        }
      }

      cnt_clock=0;
      clock_bit++;

    }

    if (clock_bit>60)
      {
        clock_bit=0;
      }
    }

}

von Jens K. (mister232)


Lesenswert?

Wenn ich den prescaler auf 64 setze dann kommt er bis 2 mit dem Zählen. 
Der ATmega arbeitet mit einem externen 8MHz Quarz. Am Oszi sehen die 
einkommenden Signale ganz ordentlich aus, ich kann sie aber nicht 
vernünftig anschauen, da mein Oszi kaputt ist und nicht richtig 
triggert.

von Jens K. (mister232)


Lesenswert?

Es lebt!
Ich habe im Internet den Tipp gefunden, dass das ELV DCF-Modul wohl ein 
invertiertes Signal liefert. Nun habe ich die steigende und fallende 
Flanke in meinem Code umgedreht und... tada... alles funktioniert. Er 
synchronisiert sich und liefert die aktuelle Zeit.

Danke für eure Hilfe!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.