Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

Moderatoren: Sven, Heaterman, TDI, Finger

Re: Der AVR-/ARDUINO-Faden

Beitragvon Fritzler » Di 3. Okt 2017, 21:52

Deswegen nutzt man nicht son Mumpitz der alles wegabstrahiert, sondern ließt das Datenblatt.
Dort steht bei den AVRs, dass die Eingangsimpedanz zu einem ADC Pin nicht größer als 10k sein soll.
Sonst wird eben der S/H C nicht schnell genug geladen. 100k+100k sind bei weitem drüber.

Also eines der folgenden Dinge tun:
- nurnoch 10k als Vorwiderstand
- Opamp als Spannungsfolger
- 1nF an den ADC Pin, dann wird der pF große S/H C aus den 1nF geladen und nicht über die 100k
Benutzeravatar
Fritzler
 
Beiträge: 4898
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Friedrichshagen/Am Wasserwerk

Re: Der AVR-/ARDUINO-Faden

Beitragvon xoexlepox » Di 3. Okt 2017, 22:13

... zwischen den analogen Portpins den S/H-Kondensator (Sample and Hold) herumschaltet. Wenn dieser - so wie hier - aus einer hochohmigen Quelle gespeist wird, ist die erste Messung einfach Mist.

Das ist/war bei allen µCs, die ich bisher verwendet habe, so gelöst: Es gibt nur einen A/D-Wandler, und davor werkelt ein analoger Multiplexer. In den Datenblättern der Chips finden sich auch meist Formeln, mit denen sich die notwendige Wartezeit zwischen Selektierung der Portpins und Start der Wandlung berechnen lässt. Oftmals findet sich auch ein Hinweis, daß die Impedanz des zu messenden Analogsignals möglichst 10kOhm nicht überschreiten sollte. Ich vermute mal, daß in der Arduino-Lib diese Verzögerungen auch dementsprechend eingebaut sind. In meinen Programmen greife ich meist direkt auf die entsprechenden Register zu, wodurch die Selektierung des Portpins und die A/D-Wandlung zu getrennten Vorgängen werden. Und ich habe mir angewöhnt, sofort nach dem Start der A/D-Wandlung (die ja auch ein paar Takte benötigt, bis das Ergebnis vorliegt) den Analogmultiplexer auf den nächsten zu messenden Portpin umzuschalten.

Ok, Fritzler war schneller...
Benutzeravatar
xoexlepox
 
Beiträge: 4089
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitragvon berlinerbaer » Mi 4. Okt 2017, 00:31

Damit wäre das ja geklärt...

Wenn Du aus Deiner Anlage wieder ein paar Megas für andere Projekte verwenden möchtest, könntest Du auch I2C port extender verwenden oder ein Rudel nanos nehmen.

Kosten beim Chinesen einen bzw. anderthalb Euro.
berlinerbaer
 
Beiträge: 184
Registriert: Di 22. Aug 2017, 05:19
Wohnort: Berlin

Re: Der AVR-/ARDUINO-Faden

Beitragvon Sir_Death » Mi 4. Okt 2017, 08:02

berlinerbaer hat geschrieben:Damit wäre das ja geklärt...

Wenn Du aus Deiner Anlage wieder ein paar Megas für andere Projekte verwenden möchtest, könntest Du auch I2C port extender verwenden oder ein Rudel nanos nehmen.

Kosten beim Chinesen einen bzw. anderthalb Euro.


Sorry - beides völlig Sinnlos.
Schau dir mal die Kosten für Portexpander an - PWM out, analog in, digital i/o. - Einen Mega bekommst du schon unter EUR 14,- inkl. Versand.
Dann kommt da noch die Programmlaufzeit dazu - je mehr Ports abzuarbeiten, desto mehr zu tun. Und nein, ich werde nicht anfangen in Plain C oder Assembler zu programmieren. Das mögen andere machen ich nicht.

Bezüglich Nanos: und wie vernetzt du die, ohne Kopfstände mit selbst abzuarbeitenden Interrupts? - Abgesehen davon, dass ich davon auch keinerlei Ahnung habe. Bei den Megas habe ich 4 serielle Schnittstellen mit Input-buffer. Den arbeite ich ab, wenn ich im Programm Zeit habe.

Meine Programmierkentnisse stammen aus der Zeit von Borland Pascal 6.0, und diese sind nur rudementär. Ich bin froh, überhaupt so weit gekommen zu sein.

@fritzler und xoexlepox: Danke für die Tips. Wenn es so wie jetzt gelöst dauerhaft funktioniert, bleibt es so, wenn nicht werden kleinere Vorwiderstände verbaut. Ursprünglich war ich am überlegen, die gesamte Anlage entweder mit Logikgatter oder mit PIC16F84 zu bauen. Vor dem PIC hat mir so gebraut, dass ich schon begonnen hatte, Logikgatter zu sammeln. Als ich dann durch den 3D-Druck Arduino in die Hände bekam, war ich begeistert, da sich mit dem Ding selbst von Halbidioten wie mich Programme zusammenstellen lassen, die sogar irgendwie laufen.
Den Anspruch auf Perfektionismus habe ich in anderen Bereichen, aber nicht beim Programmieren. Daher wäre ich euch sehr verbunden und dankbar, wenn ihr die Arduino-Umgebung nicht ständig verteufeln würdet. Jedem steht die Wahl seiner Mittel frei.

Danke.

P.S. Jetzt ist der Text doch etwas länger als geplant geworden. ;)

Edit: Sorry xoexlepotz - der Text mit dem Verteufeln ist nur für fritzler. :oops:
Sir_Death
 
Beiträge: 1087
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » Do 16. Nov 2017, 22:59

Ich habe folgende Schaltung aufgebaut.
Das funktioniert mit dem Arduino soweit. Leider kann ich die Uhrzeit nicht einstellen.
Um das zu anderen habe ich mir mal bei Pollin ein DCF-Empfangsmodul besorgt.
Dieses soll für eine Korrekte Uhrzeit sorgen.

Wie oder Was muss ich im Code ändern, damit die Uhrzeit vom dem DCF-Empfangsmodul
für die Anzeige der Zeit verwendet wird?

Bild->zoom

Code: Alles auswählen
#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};          //SEKUNDE MINUTE STUNDE
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=2,m1=9;
int h10=2,h1=2;

unsigned long t,t0; //TIMEINIT

void INTITIME(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}

void setup()
{int i;
 for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
 for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
 for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, LOW);
 digitalWrite(A1, LOW);
 digitalWrite(A2, LOW);
}

void loop()
{int i;
 t=TIMEREAD();
 do
 {for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH);  //EINERBAND SEKUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN
  digitalWrite(A0, HIGH);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH);  //EINERBAND MINUTEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN
  digitalWrite(A1, HIGH);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH);  //EINERBAND STUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
  digitalWrite(A2, HIGH);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, LOW);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------
 s1++;                   //s++;
 if(s1>=10){s1=0;s10++;}
 if(s10>=6){s10=0;m1++;} //m1++;
 if(m1>=10){m1=0;m10++;}
 if(m10>=6){m10=0;h1++;} //h1++;
 if(h1>=10){h1=0;h10++;}
 if(h10>=2 && h1>=4){h10=0;h1=0;}
}


Schom mal danke im Vorraus.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Sir_Death » Do 16. Nov 2017, 23:10

Schon mal Tante Google mit den Worten "Arduino DCF77" befragt? - Spuckt jede Menge aus.
Sir_Death
 
Beiträge: 1087
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » Sa 18. Nov 2017, 18:14

Ja das habe ich getan. Das hat mich nur noch mehr Verwirrt. :?
Ich weiß als Anfänger nur das ich ne Bibliothek DCF brauche.
Den Code zu der Schaltung habe ich mit aus dem Netz besorgt und per Copy and Paste
einfach eingefügt.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Profipruckel » So 19. Nov 2017, 00:02

Andreas_P hat geschrieben:Ich weiß als Anfänger nur dass ich ne Bibliothek DCF brauche. Den Code zu der Schaltung habe ich mir aus dem Netz besorgt und per Copy and Paste einfach eingefügt.
Damit erfüllst Du leider das Klischeebild des "Arduinos": Irgendetwas kopieren und dann im Forum fragen, weshalb es nicht geht.

Zerlege Deine Aufgabe in kleine Teile und teste diese Stück für Stück einzeln. Erst, wenn Du diese kleinen Teile verstanden hast, füge sie zum Gesamtprojekt zusammen.

Hast Du nachgelesen, wie DCF77 funktioniert? Der Empfänger liefert jede Sekunde einen Impuls mit 100 oder 200 ms Länge, aus dem der Arduino die Uhrzeit errechnen muß - das dauert ab Einschalten mindestens zwei Minuten. In diversen Foren findet man, dass es garnicht funktioniert, Störungen durch Schaltnetzteile etc.! Die Anschaltung des Pollin-Modules ist auch nicht ganz problemfrei, es kann nur einen sehr geringen Strom treiben.
Profipruckel
 
Beiträge: 1342
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitragvon sysconsol » So 19. Nov 2017, 09:24

Ist du die Bibliothek korrekt eingebunden worden?

Hast du ein Oszilloskop? -> Signal am entsprechenden Eingang des Arduino prüfen.

Das muss nicht nur pegelmäßig stimmen, das muss auch plausibel (= nicht gestört) sein.
Eventuell mitschreiben und händisch dekodieren.
sysconsol
 
Beiträge: 819
Registriert: Fr 8. Jul 2016, 17:22

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » So 19. Nov 2017, 09:56

Meine Frage war, an welcher Stelle in dem Oben geposteten
Programmcode muß ich den Code für dem DCF Empfang
einfügen.

Ich hatte das Projekt mit der Reinturm Uhr Anfang des
Jahres entnervt zuseite gelegt. Das Pollin DCF Modul
hatte ich auf einen Steckbrett mit ein paar externen Bauteilen
aufgebaut. Was gut funktioniert hat.

Ich suche heute mal alles dafür wieder zusammen.
In dem Chaos muss das noch wo sein.
Am lebenden Objekt kann man besser ausprobieren.

sysconsol
Oszilloskop habe ich da. Ich hatte dem korrekten Empfang des
DCF mit einem Testprogramm überprüft, das die Uhrzeit und
Datum über den Seriellen Monitor Ausgabe.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Myvesdin » So 19. Nov 2017, 20:07

Jetzt mal was, wo ich wahrscheinlich einfach den Wald vor lauter Bäumen nicht seh...
Code: Alles auswählen

#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
int SRCLK = 11;
int RCLK = 12;
int SER = 4;
int counter = 1;
int nowseconds = 0;
int nowhours = 0;
int nowminutes = 0;
int numZero = 63;
int numOne = 6;
int numTwo = 91;
int numThree = 79;
int numFour  = 102;
int numFive  = 109;
int numSix   = 125;
int numSeven = 7;
int numEight = 127;
int numNine  = 111;

RTC_Millis rtc;

void setup() {
 pinMode(10, OUTPUT);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(SRCLK, OUTPUT);
 pinMode(RCLK, OUTPUT);
 pinMode(SER, OUTPUT);
 rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
 rtc.adjust(DateTime(2017, 11, 19, 19, 11, 22));
}
 
void loop () {
 DateTime now = rtc.now();
 if (counter = 1){
    nowhours = now.hour();
    int nowhours = nowhours / 10;
    if (nowhours = 0){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, 0);
        digitalWrite(RCLK, HIGH);   
    }
    if (nowhours = 1){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numOne);
        digitalWrite(RCLK, HIGH);
        }
    if (nowhours = 2){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numTwo);
        digitalWrite(RCLK, HIGH);   
    }   
    digitalWrite(10, HIGH);
    delay(1);
    digitalWrite(10, LOW);
 }

 
 if (counter = 2){
    nowhours = now.hour();
    int nowhours = nowhours % 10;
    if (nowhours = 0){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numZero);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 1){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numOne);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 2){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numTwo);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 3){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numThree);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 4){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numFour);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 5){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numFive);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 6){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numSix);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 7){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numSeven);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 8){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numEight);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 9){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numNine);
        digitalWrite(RCLK, HIGH);
    }
    digitalWrite(2, HIGH);
    delay(1);
    digitalWrite(2, LOW);
 }
 
if (counter = 6){
  counter = 1;
}
else{
  counter = counter + 1;
  }
}


Hab den restlichen Code erstmal weggekürzt.

Es soll eine Uhr werden, die aus VFD-Röhren besteht.
Problem ist jetzt aber erstmal, dass er mir bei der ersten Ziffer eine 2 rausgibt und bei der zweiten Ziffer eine 9.
Ich versteh nur einfach nicht wieso?

Grüße
Myvesdin
 
Beiträge: 27
Registriert: Sa 5. Apr 2014, 10:20

Re: Der AVR-/ARDUINO-Faden

Beitragvon andreas6 » So 19. Nov 2017, 20:38

Ohne jetzt das Umfeld genau zu kennen, fällt mir die ungewöhnliche Taktgebung auf. Normalerweise legt man Daten an, schaltet dann den Takt ein und aus und ändert dann die Daten. Ist das so gewollt?

MfG. Andreas
andreas6
 
Beiträge: 1697
Registriert: So 11. Aug 2013, 15:09

Re: Der AVR-/ARDUINO-Faden

Beitragvon Myvesdin » So 19. Nov 2017, 21:57

Oh verdammt, ganz vergessen zu kommentieren :oops: :?

Code: Alles auswählen
#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
int SRCLK = 11;
int RCLK = 12;
int SER = 4; //SRCLK,RCLK & SER sind die Pins für ein Shiftregister

int counter = 1;
int nowseconds = 0;
int nowhours = 0;
int nowminutes = 0;

int numZero = 63;
int numOne = 6;
int numTwo = 91;
int numThree = 79;
int numFour  = 102;
int numFive  = 109;
int numSix   = 125;
int numSeven = 7;
int numEight = 127;
int numNine  = 111; //Das sind die Daten entsprechend für die verschiedenen Zahlen

RTC_Millis rtc;

void setup() {
 pinMode(10, OUTPUT);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);  //Die 6 VFD-Röhren
 pinMode(SRCLK, OUTPUT);
 pinMode(RCLK, OUTPUT);
 pinMode(SER, OUTPUT); //Alle Datenpins als Output schalten
 rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
 rtc.adjust(DateTime(2017, 11, 19, 19, 11, 22)); //Realtime Clock starten und testweise einstellen
}
 
void loop () {
 DateTime now = rtc.now(); //Uhrzeit abrufen
 if (counter = 1){
    nowhours = now.hour(); //RTC Stunden in ein Integer übertragen
    int nowhours = nowhours / 10; //int durch 10 teilen, um die erste Ziffer der Stunden zu bekommen

    if (nowhours = 0){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, 0);
        digitalWrite(RCLK, HIGH);   
    }
    if (nowhours = 1){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numOne);
        digitalWrite(RCLK, HIGH);
        }
    if (nowhours = 2){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numTwo);
        digitalWrite(RCLK, HIGH);                                //Herausfinden ob die erste Ziffer eine 0,1 oder 2 ist und dementsprechend die Daten in das Shiftregister übertragen
    }   
    digitalWrite(10, HIGH);
    delay(1);
    digitalWrite(10, LOW);        //1. VFD kurz einschalten, sodass die Ziffer angezeigt wird
 }

 
 if (counter = 2){
    nowhours = now.hour();        //Int "erneuern"
    int nowhours = nowhours % 10;   //2. Ziffer der Stunden erhalten
    if (nowhours = 0){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numZero);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 1){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numOne);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 2){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numTwo);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 3){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numThree);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 4){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numFour);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 5){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numFive);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 6){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numSix);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 7){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numSeven);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 8){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numEight);
        digitalWrite(RCLK, HIGH);
    }
    if (nowhours = 9){
        digitalWrite(RCLK, LOW);
        shiftOut(SER, SRCLK, MSBFIRST, numNine);
        digitalWrite(RCLK, HIGH);     //Herausfinden was die 2. Ziffer ist und die entsprechenden Daten ins Shiftregister schieben
    }
    digitalWrite(2, HIGH);
    delay(1);
    digitalWrite(2, LOW);    //2. VFD kurz einschalten
 }
 
if (counter = 6){
  counter = 1;
}
else{
  counter = counter + 1;
  }          //Da es 6 Röhren gibt soll es pro Durchlaufs des Loops eine Aktualisierung einer Röhre geben
}
Myvesdin
 
Beiträge: 27
Registriert: Sa 5. Apr 2014, 10:20

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » So 19. Nov 2017, 22:45

Ich habe mir heute nen Wolf gesucht nach dem Pollin DCF Modul.
Etwas Doku habe ich auch noch gefunden.

Bild->zoom

Mit dieser Schaltung hatte ich Anfang des Jahres Erfolg gehabt das das Pollin DCF Modul funktionierte.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon xoexlepox » So 19. Nov 2017, 23:30

Etwas Doku habe ich auch noch gefunden.

Ach! Das braucht auch einen Vorwiderstand in der Zuleitung der Betriebsspannung? Bei einem Modul (von Reichelt) habe ich lange gebraucht, bis ich das herausgefunden hatte -> Diese Module sind m.E. oft echte "Mimosen" ;)
Benutzeravatar
xoexlepox
 
Beiträge: 4089
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » So 19. Nov 2017, 23:54

Die Doku dazu hatte ich mir damals mit ausgedruckt.
Meine Doku Unterlagen habe ich heute auch wieder gefunden. :)
So war das gemeint.

xoexlepox
Doku gibt es zum dem Thema DCF im Netz mehr als genug.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » Mi 22. Nov 2017, 18:49

So meine Testschaltung die ich schon hier weiter oben gepostet habe, funktioniert.
Dieser Code gibt über den Seriellen Monitor Uhrzeit und Datum aus.

Code: Alles auswählen
 /**
     * Arduino DCF77 decoder v0.2
     * Copyright (C) 2006 Mathias Dalheimer (md@gonium.net)
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License along
     * with this program; if not, write to the Free Software Foundation, Inc.,
     * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     */

    /**
     * Where is the DCF receiver connected?
     */
    #define DCF77PIN 2
    /**
     * Where is the LED connected?
     */
    #define BLINKPIN 13
    /**
     * Turn debugging on or off
     */
    #define DCF_DEBUG 1
    /**
     * Number of milliseconds to elapse before we assume a "1",
     * if we receive a falling flank before - its a 0.
     */
    #define DCF_split_millis 140
    /**
     * There is no signal in second 59 - detect the beginning of
     * a new minute.
     */
    #define DCF_sync_millis 1200
    /**
     * Definitions for the timer interrupt 2 handler:
     * The Arduino runs at 16 Mhz, we use a prescaler of 64 -> We need to
     * initialize the counter with 6. This way, we have 1000 interrupts per second.
     * We use tick_counter to count the interrupts.
     */
    #define INIT_TIMER_COUNT 6
    #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
    int tick_counter = 0;
    int TIMSK;
    int TCCR2;
    int OCIE2;
    /**
     * DCF time format struct
     */
    struct DCF77Buffer {
      unsigned long long prefix   :21;
      unsigned long long Min   :7;   // minutes
      unsigned long long P1      :1;   // parity minutes
      unsigned long long Hour   :6;   // hours
      unsigned long long P2      :1;   // parity hours
      unsigned long long Day   :6;   // day
      unsigned long long Weekday   :3;   // day of week
      unsigned long long Month   :5;   // month
      unsigned long long Year   :8;   // year (5 -> 2005)
      unsigned long long P3      :1;   // parity
    };
    struct {
       unsigned char parity_flag   :1;
       unsigned char parity_min      :1;
       unsigned char parity_hour   :1;
       unsigned char parity_date   :1;
    } flags;
    /**
     * Clock variables
     */
    volatile unsigned char DCFSignalState = 0;
    unsigned char previousSignalState;
    int previousFlankTime;
    int bufferPosition;
    unsigned long long dcf_rx_buffer;
    /**
     * time vars: the time is stored here!
     */
    volatile unsigned char ss;
    volatile unsigned char mm;
    volatile unsigned char hh;
    volatile unsigned char day;
    volatile unsigned char mon;
    volatile unsigned int year;
       

    /**
     * used in main loop: detect a new second...
     */
    unsigned char previousSecond;
       
    /**
     * Initialize the DCF77 routines: initialize the variables,
     * configure the interrupt behaviour.
     */
    void DCF77Init() {
      previousSignalState=0;
      previousFlankTime=0;
      bufferPosition=0;
      dcf_rx_buffer=0;
      ss=mm=hh=day=mon=year=0;
    #ifdef DCF_DEBUG
      Serial.println("Initializing DCF77 routines");
      Serial.print("Using DCF77 pin #");
      Serial.println(DCF77PIN);
      pinMode(BLINKPIN, OUTPUT);
      pinMode(DCF77PIN, INPUT);
    #endif
      pinMode(DCF77PIN, INPUT);
    #ifdef DCF_DEBUG
      Serial.println("Initializing timerinterrupt");
    #endif
      //Timer2 Settings: Timer Prescaler /64,
      TCCR2 |= (1<<CS22);    // turn on CS22 bit
      TCCR2 &= ~((1<<CS21) | (1<<CS20));    // turn off CS21 and CS20 bits   
      // Use normal mode
      TCCR2 &= ~((1<<WGM21) | (1<<WGM20));   // turn off WGM21 and WGM20 bits
      // Use internal clock - external clock not used in Arduino
      ASSR |= (0<<AS2);
      TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable
      RESET_TIMER2;
    #ifdef DCF_DEBUG
      Serial.println("Initializing DCF77 signal listener interrupt");
    #endif
      attachInterrupt(0, int0handler, CHANGE);
    }

    /**
     * Append a signal to the dcf_rx_buffer. Argument can be 1 or 0. An internal
     * counter shifts the writing position within the buffer. If position > 59,
     * a new minute begins -> time to call finalizeBuffer().
     */
    void appendSignal(unsigned char signal) {
    #ifdef DCF_DEBUG
      Serial.print(", appending value ");
      Serial.print(signal, DEC);
      Serial.print(" at position ");
      Serial.println(bufferPosition);
    #endif
      dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) signal << bufferPosition);
      // Update the parity bits. First: Reset when minute, hour or date starts.
      if (bufferPosition ==  21 || bufferPosition ==  29 || bufferPosition ==  36) {
       flags.parity_flag = 0;
      }
      // save the parity when the corresponding segment ends
      if (bufferPosition ==  28) {flags.parity_min = flags.parity_flag;};
      if (bufferPosition ==  35) {flags.parity_hour = flags.parity_flag;};
      if (bufferPosition ==  58) {flags.parity_date = flags.parity_flag;};
      // When we received a 1, toggle the parity flag
      if (signal == 1) {
        flags.parity_flag = flags.parity_flag ^ 1;
      }
      bufferPosition++;
      if (bufferPosition > 59) {
        finalizeBuffer();
      }
    }

    /**
     * Evaluates the information stored in the buffer. This is where the DCF77
     * signal is decoded and the internal clock is updated.
     */
    void finalizeBuffer(void) {
      if (bufferPosition == 59) {
    #ifdef DCF_DEBUG
        Serial.println("Finalizing Buffer");
    #endif
        struct DCF77Buffer *rx_buffer;
        rx_buffer = (struct DCF77Buffer *)(unsigned long long)&dcf_rx_buffer;
        if (flags.parity_min == rx_buffer->P1  &&
            flags.parity_hour == rx_buffer->P2  &&
            flags.parity_date == rx_buffer->P3)
        {
    #ifdef DCF_DEBUG
          Serial.println("Parity check OK - updating time.");
    #endif
          //convert the received bits from BCD
          mm = rx_buffer->Min-((rx_buffer->Min/16)*6);
          hh = rx_buffer->Hour-((rx_buffer->Hour/16)*6);
          day= rx_buffer->Day-((rx_buffer->Day/16)*6);
          mon= rx_buffer->Month-((rx_buffer->Month/16)*6);
          year= 2000 + rx_buffer->Year-((rx_buffer->Year/16)*6);
        }
    #ifdef DCF_DEBUG
          else {
            Serial.println("Parity check NOK - running on internal clock.");
        }
    #endif
      }
      // reset stuff
      ss = 0;
      bufferPosition = 0;
      dcf_rx_buffer=0;
    }

    /**
     * Dump the time to the serial line.
     */
    void serialDumpTime(void){
      Serial.print("Time: ");
      Serial.print(hh, DEC);
      Serial.print(":");
      Serial.print(mm, DEC);
      Serial.print(":");
      Serial.print(ss, DEC);
      Serial.print(" Date: ");
      Serial.print(day, DEC);
      Serial.print(".");
      Serial.print(mon, DEC);
      Serial.print(".");
      Serial.println(year, DEC);
    }


    /**
     * Evaluates the signal as it is received. Decides whether we received
     * a "1" or a "0" based on the
     */
    void scanSignal(void){
        if (DCFSignalState == 1) {
          int thisFlankTime=millis();
          if (thisFlankTime - previousFlankTime > DCF_sync_millis) {
    #ifdef DCF_DEBUG
            Serial.println("####");
            Serial.println("#### Begin of new Minute!!!");
            Serial.println("####");
    #endif
            finalizeBuffer();
            serialDumpTime();
          }
          previousFlankTime=thisFlankTime;
    #ifdef DCF_DEBUG
          Serial.print(previousFlankTime);
          Serial.print(": DCF77 Signal detected, ");
    #endif
        }
        else {
          /* or a falling flank */
          int difference=millis() - previousFlankTime;
    #ifdef DCF_DEBUG
          Serial.print("duration: ");
          Serial.print(difference);
    #endif
          if (difference < DCF_split_millis) {
            appendSignal(0);
          }
          else {
            appendSignal(1);
          }
        }
    }

    /**
     * The interrupt routine for counting seconds - increment hh:mm:ss.
     */
    ISR(TIMER2_OVF_vect) {
      RESET_TIMER2;
      tick_counter += 1;
      if (tick_counter == 1000) {
        ss++;
        if (ss==60) {
          ss=0;
          mm++;
          if (mm==60) {
            mm=0;
            hh++;
            if (hh==24)
              hh=0;
          }
        }
        tick_counter = 0;
      }
    };

    /**
     * Interrupthandler for INT0 - called when the signal on Pin 2 changes.
     */
    void int0handler() {
      // check the value again - since it takes some time to
      // activate the interrupt routine, we get a clear signal.
      DCFSignalState = digitalRead(DCF77PIN);
    }


    /**
     * Standard Arduino methods below.
     */

    void setup(void) {
      // We need to start serial here again,
      // for Arduino 007 (new serial code)
      Serial.begin(9600);
      DCF77Init();
    }

    void loop(void) {
      if (ss != previousSecond) {
        serialDumpTime();
        previousSecond = ss;
      }
      if (DCFSignalState != previousSignalState) {
        scanSignal();
        if (DCFSignalState) {
          digitalWrite(BLINKPIN, HIGH);
        } else {
          digitalWrite(BLINKPIN, LOW);
        }
        previousSignalState = DCFSignalState;
      }
        //delay(20);
    }


Das wird über den Seriellen Monitor ausgegeben:

-28402: DCF77 Signal detected, duration: 127, appending value 0 at position 55
-27411: DCF77 Signal detected, duration: 127, appending value 0 at position 56
-26419: DCF77 Signal detected, duration: 128, appending value 0 at position 57
-25427: DCF77 Signal detected, duration: 129, appending value 0 at position 58
####
#### Begin of new Minute!!!
####
Finalizing Buffer
Parity check OK - updating time.
Time: 17:46:0 Date: 22.11.2017
-23443: DCF77 Signal detected, duration: 129, appending value 0 at position 0
-22452: DCF77 Signal detected, duration: 129, appending value 0 at position 1
-21459: DCF77 Signal detected, duration: 232, appending value 1 at position 2
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » Do 23. Nov 2017, 22:16

Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon Andreas_P » Do 23. Nov 2017, 22:59

In meiner Verzweiflung ist mir eingefallen das
ich noch ein Meter Neopixel hier habe.
Mit einer Beschreibung aus dem Netz kann das wie oben
auf dem Bild heraus. Die Zeit wird per Bluetooth gestellt.
Das funktioniert noch nicht, ich habe die Zeit im Code
angepasst.
Die andere Schaltung werde ich auftrennen und sie mit
Schieberegistern ergänzen.
Benutzeravatar
Andreas_P
 
Beiträge: 958
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Vorherige

Zurück zu Allgemeine Diskussion

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], da1jo, Hacky, VorbringAir und 18 Gäste

span