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: 5100
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: 4171
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: 336
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: 1280
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: 1056
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: 1280
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: 1056
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: 1357
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: 967
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: 1056
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: 33
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: 1771
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: 33
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: 1056
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: 4171
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: 1056
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: 1056
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: 1056
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: 1056
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Gemünden am Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon atno » Fr 24. Nov 2017, 12:51

Myvesdin hat geschrieben:Oh verdammt, ganz vergessen zu kommentieren :oops: :?


Naja du hast deine Vergleiche in so ziemlich allen if Bedingungen falsch.

if (nowhours=9) weißt der Variablen nowhours den Integer 9 zu und das if prüft dann ob nowhours wahr ist.

Alles was nicht 0 ist, ist in c wahr. Damit sind alle deine if Abfragen wahr und die letzte wird für dich sichtbar.
Alle anderen davor sind aber genau so ausgeführt worden, nur eben direkt wieder überschrieben.

Was du schreiben wolltest ist if (nowhours==9).

Das betrifft übrigens auch alle deine counter Vergleiche.

Wenn du am Anfang sicherstellen möchtest dass der Kompiler dich dafür anmeckert kannst du den Vergleich umdrehen, also so etwas wie
if (9==nowhours) schreiben. Als Vergleich funktioniert das wunderbar, vergisst du das zweite = wird darauf (9=nowhours). Der Kompiler wird
dich dann darauf hinweisen das er einem Wert keine Variable zuweisen kann.
atno
 
Beiträge: 9
Registriert: Mo 18. Nov 2013, 12:50

Re: Der AVR-/ARDUINO-Faden

Beitragvon barclay66 » Di 6. Feb 2018, 14:45

Hi,

im Rahmen eines neuen Projektes taucht gerade eine Aufgabenstellung auf, zu der ich gerne fachlichen Rat hätte:

Ich will über einen Arduino Mega 2650 insgesamt vier Heimkino-Geräte (einen Video-Prozessor, einen AV-Receiver, einen Röhrenprojektor und einen Digitalprojektor) über RS232 steuern und zusätzlich ein paar Relais für deren Besaftung. Die Daten und Kommandos, die jeweils verstanden werden sind bekannt sowie auch evtl. Rückmeldungen. Ziel ist es, mit einem Tastendruck eine Sequenz von Einschalt- und Konfigurationsbefehlen loszutreten. Z.B.:

Taste "Analog TV" -> Saft an für Kabelreceiver, Blu Ray Player, Apple-TV, Video-Prozessor, AV-Receiver -> Saft an für Röhrenprojektor -> Pause bis Video-Prozessor hochgefahren ist -> Kommando "720p50 von Eingang 1 in 720p100 an Ausgang" an Video-Prozessor -> Pause bis Kabelreceiver hochgefahren ist -> Kommando "Aufwachen aus Standby" an Röhrenprojektor -> Kommando "Settings für 720p100 abrufen" an Röhrenprojektor -> Fertig

oder

Taste "Digital Blu Ray" -> Saft an für Kabelreceiver, Blu Ray Player, Apple-TV, Video-Prozessor, AV-Receiver -> Saft an für Digitalprojektor -> Pause bis Video-Prozessor hochgefahren ist -> Kommando "1080p24 von Eingang 1 in 1080p24 an Ausgang" an Video-Prozessor -> Kommando "Aufwachen aus Standby" an Digitalprojektor -> Fertig

oder

Taste "Ausschalten" -> Saft aus für Kabelreceiver, Blu Ray Player, Apple-TV, Video-Prozessor, AV-Receiver -> Wenn Röhrenprojektor an -> Saft aus für Röhrenprojektor -> Wenn Digitalprojektor an -> Kommando "Standby" an Digitalprojektor -> Warten bis Nachlaufzeit der Lüfter vorbei ist -> Saft aus für Digitalprojektor -> Fertig

Die Kommunikation muss dabei nicht gleichzeitig erfolgen sondern kann schrittweise eines der Geräte nach dem anderen abklappern.
Ich stehe jetzt vor der Frage, ob ich mit der entsprechenden Anzahl an I/O-Pins vier RS232-Schnittstellen mit jeweils z.B. einem MAX3232 aufbaue und für jede der Schnittstellen entsprechende Routinen vorsehe oder ob ich das nur einmal mache und die Ausgänge mittels bidirektionaler Mosfet-Schalter auf vier Sub-D Buchsen verteile. Dann könnte ich in die jeweilige Schleife zu einer Befehlskette einfach ein "Wähle Schnittstelle x" einbauen und bräuchte das ganze serielle Gedöns nur einmal im Code anzuwerfen.

Wie würdet Ihr das tun?

Gruß
barclay66

P.S.: Bitte keine alternativen Hardwarevorschläge ("der Super-Seriell-Kontrollör"), da ich die Arduinos schon rumliegen habe und mich auch nicht in die x-te IDE einarbeiten mag. Danke!
Benutzeravatar
barclay66
 
Beiträge: 413
Registriert: Di 13. Aug 2013, 04:12

Re: Der AVR-/ARDUINO-Faden

Beitragvon sysconsol » Di 6. Feb 2018, 14:56

Ich habe das so ähnlich mal an einer größeren Installation gemacht.
Alle RS232 auf RS485 bzw. RS422.
Und dann kommen alle Geräte an den Bus.
Voraussetzung: Jeder reagiert nur auf seine Kommandos.

Ansonsten würde ich vom Kontroller nur den Hardware-UART nutzen und per Logikgatter auf Schnittstellen-Treiber umschalten.
Oder hinter dem Schnittstellentreiber, wenn das sicher funktioniert.
Kommt auch drauf an, was man an Bauteilen so herumliegen hat ;)
sysconsol
 
Beiträge: 967
Registriert: Fr 8. Jul 2016, 17:22

Re: Der AVR-/ARDUINO-Faden

Beitragvon Matt » Di 6. Feb 2018, 16:31

Meine Vorschlag: I2C und Watchdog ( Arduino hat I2C und Watchdog auch )



Grüss
Matt
Benutzeravatar
Matt
 
Beiträge: 1955
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitragvon Christian Knüll » Di 6. Feb 2018, 16:54

Hallo,

der Arduino mega hat praktischerweise exakt 4 UARTs eingebaut - einfach für jedes Gerät einen verwenden - fertig.

Christian
Christian Knüll
 
Beiträge: 18
Registriert: So 2. Nov 2014, 19:45

Re: Der AVR-/ARDUINO-Faden

Beitragvon Heaterman » Di 13. Feb 2018, 07:58

Ich will einen Sekundenzähler in eine Uhrzeitanzeige (Breite 128 Pixel) einbinden, der mit fortlaufenden Punkten die Sekunden 1-60 zeigt.

Bisher geht das so:

if (s == 1)
{
display.setCursor(0, 15);
display.print(" . ");
}

if (s == 2)
{
display.setCursor(0, 15);
display.print(" . . ");
}

usw.

//alle 15 s einen Marker:

if (s == 15)
{
display.setCursor(32, 15);
display.print(" | ");
}

if (s == 30)
{
display.setCursor(64, 15);
display.print(" | ");
}

usw.

Die Sekundenzählung kann man doch sicher in einer Funktion abfertigen? Hat jemand eine Idee?
Benutzeravatar
Heaterman
 
Beiträge: 2776
Registriert: Fr 28. Jun 2013, 10:11
Wohnort: Am Rand der Scheibe, 6 m unter NN

VorherigeNächste

Zurück zu Allgemeine Diskussion

Wer ist online?

Mitglieder in diesem Forum: Google [Bot], Lebakas, Schneewittchen und 17 Gäste

span