Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Tizi
Beiträge: 476
Registriert: Mo 12. Aug 2013, 20:27
Wohnort: 74572 Gammesfeld
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Tizi »

FRAGE:

Ich nutzte das myAVR MK2-Board mit ISP Schnittstelle zum Programmieren.
Habe mir nun ein Adapterkabel von ISP auf offene Enden (Steckbrett) gelötet.
Die Stromversorgung scheint zu gehen und auch beim Durchgangsprüfen geht alles.
Noch jemand eine Idee wieso das myAVR Progtool den Atmega8 nicht erkennt=?
Benutzeravatar
Heaterman
Beiträge: 3990
Registriert: Fr 28. Jun 2013, 10:11
Wohnort: Am Rand der Scheibe, 6 m unter NN

Re: Der AVR-/ARDUINO-Faden

Beitrag von Heaterman »

Das myAVR ProgTool ist manchmal zickig beim Erkennen von Chips. Oft hilft es, einfach mal in der Chipliste eine andere Chipvariante einzustellen und nach einem Ausleselauf wieder mit der richtigen Chipversion zu starten. Oder einen anderen Chip des gleichen Typs probieren, führt auch manchmal zum Erfolg.
Tizi
Beiträge: 476
Registriert: Mo 12. Aug 2013, 20:27
Wohnort: 74572 Gammesfeld
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Tizi »

hab ich schon probiert.
komisch: info Fenster wird Grün aber ohne Chip-Typ und Auslesen kommt rot...

weiss evtl. jemand wie ich es im Bascom testen kann? hatte da den Programmer schon mal am laufen aber weiss die einstellungen nimmer
Benutzeravatar
Chrissy
Beiträge: 1078
Registriert: So 11. Aug 2013, 16:46
Wohnort: Dresden JO61ua
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Chrissy »

Ich bin ja meistens jemand, der es mit Bob Pease hält: "My favourite programming language is: solder", aber ab und an kommt man halt doch nicht drumherum, irgendwas mit Digital zu machen. Ich möchte gerade meine selbst gebastelte Nixie Uhr testen. Dazu möchte ich eigentlich nur die Röhren dazu bringen, irgendetwas anzuzeigen.

Mein Setup sieht etwa so aus: ESP8266 (Modul ESP12e) treibt zwei HV5812, also Schieberegister mit 20 Ausgängen, die die Hochspannung der Nixies direkt schalten können. Beide Schieberegister hängen hintereinander. Der Datenpin ist die GPIO5, Der Clockpin ist die GPIO4 und dann gibt es noch den Latchpin, GPIO9.

Mittels der Funktion ShiftOut sollte man ja eigentlich in das Schieberegister Daten pumpen können. Die Funktion gestattet es auch explizit jeden digitalen Ausgang für die jeweiligen Signale zu verwenden, man ist also nicht auf das SPI Interface angewiesen. Ich war bei meinem Design natürlich dumm genug, nicht das SPI Interface für die Verbindung zum Schieberegister zu verwenden, sondern irgendwelche GPIO Pins.

Wenn ich also nun in meiner Funktion meine Pins definiere und den Code hochlade, passiert etwas interessantes: Der ESP macht meistens nichts und manchmal kotzt er die Daten aus dem SPI Interface, aber nicht aus den Pins, die ich vorher definiert habe.

Ich kann mir das gerade nicht erklären. Jemand eine Idee, was da schief gelaufen sein könnte?

Edit: Im Endeffekt habe ich den im obigen Link angegebenen Beispielcode verwendet und da meine Pinnummern angepasst. Das sollte ja erst mal reichen, um irgendwelche nicht näher definierten Ziffern auf den Röhren anzuzeigen.
Benutzeravatar
Sunset
Beiträge: 1498
Registriert: Fr 6. Dez 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sunset »

Kannst Du mal Deinen Code posten bitte?!

Sind die Pin Mode gesetzt nachdem die Pins definiert sind?
Benutzeravatar
Chrissy
Beiträge: 1078
Registriert: So 11. Aug 2013, 16:46
Wohnort: Dresden JO61ua
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Chrissy »

Code: Alles auswählen

  
 const int latchPin = 9;  //Pin connected to ST_CP(pin 12) of 74HC595
   const int clkPin = 4; //Pin connected to SH_CP(pin 11) of 74HC595
   const int dataPin = 5;  //Pin connected to DS(pin 14) of 74HC595
   
   void setup() {    
      pinMode(latchPin, OUTPUT);
      pinMode(clkPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(10,OUTPUT);
      digitalWrite(10,LOW);
 
    }

void loop() {
  digitalWrite(latchPin,HIGH);
  shiftOut(dataPin, clkPin, MSBFIRST, 0xFFFFFFFFFA); 
  digitalWrite(latchPin, LOW);
}
Das ist der Code mit dem ich testen wollte, ob das Teil überhaupt irgendwie mit dem Beinchen wackelt. Sollte nichts sinnvolles tun, sondern nur ein paar Daten in die Schiebegegister schieben.

Mittlerweile ist auf den esp aber ein micropython gewandert, da mir die Arduino IDE auf die Nerven ging. Ich versuche jetzt mein Glück mal mit Python.

Allerdings habe ich mittlerweile in den Untiefen des Internets gelesen, dass man die GPIO9 und GPIO10 gar nicht nutzen sollte, da der Flash an den gleichen Pins hängt und sich deswegen der Controller ständig aufhängt. Das könnte das komische Verhalten des Controllers erklären.

In der Dokumentation zu dem ESP12 Modul steht davon aber natürlich nichts :evil:
bestfakeaccount
Beiträge: 23
Registriert: Mi 7. Jun 2017, 00:14

Re: Der AVR-/ARDUINO-Faden

Beitrag von bestfakeaccount »

Das mit den Pins GPIO9 und 10 kann ich bestätigen. Das sind die zusätzlichen Datenleitungen für den SPI Flash. Du kannst probieren diese zu nutzen, dafür müssen die dazugehörigen Pins am Flash auf Vcc gezogen werden und der Flash Mode auf QIO umgestellt. Durch den verringerten Durchsatz läuft dein Programm dementsprechend langsamer. Alle oberen Angaben beziehen sich auf das Modul ESP201 sollten aber für alle Module gelten.

In allen Fällen ist es natürlich einfacher den Pin umzulegen, hierzu vllt. noch die folgende Übersicht: http://www.esp8266.com/wiki/lib/exe/fet ... ctions.png
Ich würde ESP Module nur in good old C mit dem FreeRTOS Port (siehe https://github.com/SuperHouse/esp-open-rtos) programmieren.
Matt
Beiträge: 6084
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

Sehr spezielle Frage:

2 umstände ist geschuldet: einer kann NUR 1200 Baud, daran kann ich nicht ändern, und andere kann ich nur bis runter auf 2400 Baud einstellen.

Ich habe AVR so geschrieben, dass der in Empfängsmodus in Baud 2400 läuft, nur wenn der AVR sendet möchtet, wird es auf Baud 1200 umgestellt..
aber da tut senden. (keine Aufhängen, nur eben mit andere Baudrate tut es nichts)
Geht wirklich Baud-Rate Umstellung per schreiben des UBRR0 Registers in mitte des Code eigentlich nicht, oder ?
Benutzeravatar
ange12lo
Beiträge: 521
Registriert: Mo 12. Aug 2013, 22:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von ange12lo »

Ich hole mal diesen Post hoch um keinen neuen zu erstellen.

Ich beschäftige mich aktuell mit den Arduino Pro Mini und Drucksensoren welche circa drei Jahre im Batteriebetrieb laufen sollte.
Nun Aktuell habe ich die Schaltung und das Programm so konstruiert das die Werte einmal in der Stunde übertragen werden, der rest der Zeit legt sich der Arduino, I2C Sensor, und das sende Modul schlafen.
Der Aktuelle Standby Verbrauch liegt bei 42µA mit einer 3.3V Speisung. Im Betrieb gönnt sich die Schaltung 40mA für circa 1-1.5 Sekunden.
Nun meine dilemma. Die Schaltung sollte Batteriebetrieben möglichst lange Laufen. Der Arduino könnte ich auch noch bis 1.8v runter betreiben die I2C Geräte wollen aber von 3-3.3V sehen.

Soll ich nun einen sparsamen Step-Up suchen wie z.b dieser Hier? https://www.digikey.ch/products/de/powe ... k=%20R-78S
Oder Lieber einen Low-Drop Linearregler ala TPS78233.

Beim Linearregler bräuchte ich dann aber wiederum vier Batterien was das ganze dann wieder unhandlicher macht.

hat jemand einen besseren Vorschlag?
Oder kennt einer einen Schaltregler mit einem geringeren Eigenverbrauch als der oben verlinkte?
Finde es Schade 240µW im Schaltregler zu verbraten.
Anse
Beiträge: 2278
Registriert: Mo 12. Aug 2013, 21:30
Wohnort: Bühl (Baden)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Anse »

Normale Linearregler haben eine hohen Querstrom. Beim 87L05 sind es wenn ich mich richtig erinnere ca. 3,5mA.
Es gibt noch low quiescent current Regler. z.B. LM2936Z mit 15µA im Leerlauf.
Läuft der Arduino eigentlich auf 16MHz?
Benutzeravatar
ange12lo
Beiträge: 521
Registriert: Mo 12. Aug 2013, 22:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von ange12lo »

Anse hat geschrieben: Läuft der Arduino eigentlich auf 16MHz?
Es ist die 8MHz 3.3V Version.

Als Linearregler hätte ich die TPS78233 Version gewählt, Die hat einen eigenverbrauch ohne Last von 1,3µA.
Ich wollte jedoch vermeiden vier Batterien zu nutzen.
Benutzeravatar
ferdimh
Beiträge: 9379
Registriert: Fr 16. Aug 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von ferdimh »

Das sollte doch einwandfrei mit einer Lithium-Ionen-Zelle gehen.
45µA (42+Regler) * 3 Jahre sind gerade mal 1,2Ah.
Da bleibt eine einzelne 18650 (neu, vollgeladen) sicher über deutlich über 3,5V.
Wenn es AA-Format sein muss, müsste man dann wohl zwei parallel nehmen.
Dass man einen Akku hier nicht sinnvoll als Akku nutzt, halte ich bei den Preisen für verschmerzbar.
Benutzeravatar
ange12lo
Beiträge: 521
Registriert: Mo 12. Aug 2013, 22:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von ange12lo »

ich würde ansonst normale Lithium Batterien Kaufen im AA format mit 3.6V habe jedoch keine entladekurve dazu gefunden, wann ist eine Lithium Batterie (nicht Akku) den wirklich leer?
Benutzeravatar
Bastelbruder
Beiträge: 11481
Registriert: Mi 14. Aug 2013, 18:28

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bastelbruder »

Eine Lithium-Primärzelle ist leer (unter 1%) wenn die angegebene Leerlaufspannung unterschritten wird.
Entweder 3,0 V oder 3,6 V.
andreas6
Beiträge: 4149
Registriert: So 11. Aug 2013, 15:09

Re: Der AVR-/ARDUINO-Faden

Beitrag von andreas6 »

Per Spannungsmessung ist da kaum eine verlässliche Aussage zu bekommen. Bei Messen immer einen Lastwiderstand parallel schalten! An z.B. 100 Ohm zeigt sich sehr schnell der Unterschied zwischen benutzbar oder leer. Die leere Zelle hat fast die Nennspannung, aber einen hohen Innenwiderstand. Es gibt übrigens auch 1,5V-Li-Zellen, die fast am Ende der Kapazität unbelastet immer noch 1,7V zeigen.

MfG. Andreas
Benutzeravatar
ferdimh
Beiträge: 9379
Registriert: Fr 16. Aug 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von ferdimh »

Wenn du die Anwendung gelesen hättest, wäre dieser Text hinfällig.
Weder 50µA noch 50mA sind für eine 2,5A-Zelle eine Li-Ion-Zelle eine Last von einer Intensität, dass man den Spannungseinbruch berücksichtigen müsste.
Bei Primärzellen kann das anders aussehen (die sind möglicherweise nur für Speichererhaltung gedacht), ich würde aber keine Primärzelle verwenden (weil Akkus nicht schlechter, nicht teurer und besser verfügbar sind).
Eine Google-Bildersuche nach "Li-Ion Entladekurve" gibt einem auch massig Bilder, wie das aussieht...
berlinerbaer
Beiträge: 1062
Registriert: Di 22. Aug 2017, 05:19
Wohnort: Berlin

Re: Der AVR-/ARDUINO-Faden

Beitrag von berlinerbaer »

Ansonsten kannst Du auch prismatische LiPo-Zellen aus dem Modellbaubereich nehmen.

5 Ah sind gar nicht mal so teuer:
https://hobbyking.com/de_de/turnigy-500 ... -cell.html

Vielleicht ist der Formfaktor fürs Gehäuse ja auch vorteilhafter.

Jedenfalls solltest Du damit Laufzeiten hinkriegen, bei denen dann die Akku-Kapazität wahrscheinlich nicht mehr der limitierende Faktor ist.
andreas6
Beiträge: 4149
Registriert: So 11. Aug 2013, 15:09

Re: Der AVR-/ARDUINO-Faden

Beitrag von andreas6 »

Bei Primärzellen kann das anders aussehen
Da sieht es definitiv anders aus. Nur auf Primärzellen bezog sich der Messhinweis.

MfG. Andreas
Till
Beiträge: 1162
Registriert: Di 13. Aug 2013, 16:00

Re: Der AVR-/ARDUINO-Faden

Beitrag von Till »

Moin Moin in die Runde.

Ich habe aktuell folgendes Problem bei dem ich nicht so recht weiter komme
da mir aktuell noch ein wenig das Verständnis für die ganze Programmierung fehlt.

Ich habe eine serielle Schnittstelle auf der ein Arduino mithorchen soll, diese enthält Daten
welche eine Waage an eine Anzeige sendet.

Diese Daten habe ich auch so weit mit dem Oskar sichtbar machen können, sie werden als ASCII übertragen.
So sieht das dann aus wenn einfach nur das Gewicht dort steht:

Bild->zoom


Es wird immer ein Byte übertragen, welches dann von CR abgeschlossen wird.
Jetzt soll der Arduino sobald folgendes auf der Schnittstelle empfangen wird einen Ausgang setzen:
Bild->zoom

Die abgebildeten Daten werden regelmäßig im Abstand von ca. 500-700ms gesendet,
Das W.OK steht dann auch etwa für 5 Sekunden dort.
Ansonsten kann es auch schon mal vorkommen das Warte oder Error gesendet wird,
dies soll allerdings ignoriert werden.

Leider werde ich aus den Befehlen für die serielle Schnittstelle nicht so richtig schlau,
vor allem nicht mit den verschiedenen Datentypen und dem Buffer.

Kann mir da von euch jemand ein bisschen Starthilfe geben?

Gruß Till.
Till
Beiträge: 1162
Registriert: Di 13. Aug 2013, 16:00

Re: Der AVR-/ARDUINO-Faden

Beitrag von Till »

.
Benutzeravatar
ange12lo
Beiträge: 521
Registriert: Mo 12. Aug 2013, 22:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von ange12lo »

Bin nun seit einiger Zeit am entwickeln einer Schaltung die extrem Energie sparend ist.
Nun ich messe mehrmals pro stunde einen Wert über einen I2c Sensor, dann legt sich der Mega wieder schlaffen.
Aktuell läuft der I2c Sensor direkt am Mega und das ohne Pullup Wiedererstände.
Da die Messung mehrere Sekunden dauert und das mehrmals pro Stunde, wird mein Stromverbrauch durch die Pullup Wiederstände erheblich gesteigert.
Habe in diversen Foren gelesen das mindestens 2mA und noch besser 3mA fliessen sollte.
Das liegt aber bei meiner Anwendung mit einer AA Batterie und mindestens drei Jahre Laufzeit nicht drin.
Wer kann mir eine alternative nennen, oder was sind die Risiken wenn der Strom durch die Pullups um einiges kleiner ist?
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

na wenn es jetzt ohne externe Pullups funktioniert, hast du wahrschienich die internen aktiviert. Warum willst du dann noch extra externe setzen? - Wer verzapft solchen Blödsinn?

EDIT: Risiko bei kleinen Pullups: Störanfälliger gegen Einstreuungen. Auf Platinen verwende ich - wo notwendig - üblicherweise (je nach Lagerstand) 10-20k an 5V --> ergibt zwischen 250 und 500µA - bisher keine Probleme.
Matt
Beiträge: 6084
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

I²C Abschlusswiderstand ist üblichweise 4,7k , aber höhere Werte ist kein Problem, nur wenn du Geschwindigkeit davon verlangsamert (denn es ist Open Collector_Schaltung, da begrenzt Pullup ihre Anstiegsgeschwindigkeit.)

Prüfmal, ob Sensor auch mit kleinere Spannung klarkommt. (es gibt welcheres I²C Device der mit 2,7V läuft, spezifizert ! (AD7417 ))
Benutzeravatar
Weisskeinen
Beiträge: 3942
Registriert: Di 27. Aug 2013, 16:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von Weisskeinen »

Wenn es denn schon externe Pull-up-Widerstände sein müssten, dann kann man die auch schaltbar machen. Besser für's Stromsparen wäre allerdings, die Messzeit zu verkürzen...
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

Neues Thema zum Arduino: - Just for Information

Eigentlich würde ich es fast in Ärgernis der Woche einstellen, aber lieber hier, dann kann man das vielleicht mal finden / nachlesen.

Wie vor einigen Wochen im "fertiggestellte Projekte" berichtet, habe ich ja eine Modellbahnanlage gebaut, wo 10 Arduino Mega miteinander reden müssen, da ich soviele Portpins brauche.
Die Erkennung, wo sich gerade ein Zug befindet, funktioniert über eine in den Massepfad eingeschliffene Diode, an der der Mega mit seinen Analogpins die Spannung misst.
Leider litt diese Erkennung unter sporadischen ausfällen, bzw. Erkennungen von Zügen, wo keine waren.
Ärgernis der Woche deshalb, da ich inzwischen ca. 30-40 Stunden mit der Fehlersuche verbracht habe.

Fehlerursache war folgendes:
1.) damit die Diode sauber auf Masse liegt, wenn kein Zug da ist, gibt es parallel zur Diode einen hochohmigen Widerstand (100k) gegen Masse, sowie einen 100k als Überbrückung über den MOSFET. Deshalb so hochohmig, damit die Bahn mit der Messspannung sicher nicht losfährt.
2.) Habe ich vor Urzeiten mal gelernt, meine Programme nach dem "EVA"-Modell zu schreiben. (EVA = Eingabe Verarbeitung Ausgabe) sprich schön hintereinander, nicht durcheinander - sonst tut man sich meist beim erweitern des Programms sehr schwer.
3.) Deshalb stehen als erstes die "digitalRead" schön nacheinander, und dann die "analogRead" eins nach dem anderen.

Und dann sind die analog eingelesenen Werte nur noch Mist.
Ursache ist, dass der Mega - soweit ich das verstanden habe - 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.

Abhilfe: entweder vor jeder analogen Messung ein "delay(1);" oder einfach das gleiche "analogRead" 2 x hintereinander ausführen. Schon geht der Mist.
Details auch nachzulesen hier: https://forum.arduino.cc/index.php?topic=69675.0

Ich hoffe, ich kann jemandem damit ein paar Stunden Fehlersuche ersparen.
Benutzeravatar
Fritzler
Beiträge: 12579
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

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
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

... 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...
berlinerbaer
Beiträge: 1062
Registriert: Di 22. Aug 2017, 05:19
Wohnort: Berlin

Re: Der AVR-/ARDUINO-Faden

Beitrag von berlinerbaer »

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.
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

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:
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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.
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

Schon mal Tante Google mit den Worten "Arduino DCF77" befragt? - Spuckt jede Menge aus.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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.
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitrag von Profipruckel »

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.
sysconsol
Beiträge: 4059
Registriert: Fr 8. Jul 2016, 17:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von sysconsol »

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.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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.
Myvesdin
Beiträge: 45
Registriert: Sa 5. Apr 2014, 10:20

Re: Der AVR-/ARDUINO-Faden

Beitrag von Myvesdin »

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
andreas6
Beiträge: 4149
Registriert: So 11. Aug 2013, 15:09

Re: Der AVR-/ARDUINO-Faden

Beitrag von andreas6 »

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
Myvesdin
Beiträge: 45
Registriert: Sa 5. Apr 2014, 10:20

Re: Der AVR-/ARDUINO-Faden

Beitrag von Myvesdin »

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
}
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

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
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Andreas_P »

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.
atno
Beiträge: 14
Registriert: Mo 18. Nov 2013, 12:50

Re: Der AVR-/ARDUINO-Faden

Beitrag von atno »

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.
Benutzeravatar
barclay66
Beiträge: 1066
Registriert: Di 13. Aug 2013, 04:12
Wohnort: im Speckgürtel Münchens

Re: Der AVR-/ARDUINO-Faden

Beitrag von barclay66 »

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!
sysconsol
Beiträge: 4059
Registriert: Fr 8. Jul 2016, 17:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von sysconsol »

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 ;)
Matt
Beiträge: 6084
Registriert: So 24. Aug 2014, 21:22

Re: Der AVR-/ARDUINO-Faden

Beitrag von Matt »

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



Grüss
Matt
Benutzeravatar
Christian Knüll
Beiträge: 39
Registriert: So 2. Nov 2014, 19:45
Wohnort: Höpfingen
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Christian Knüll »

Hallo,

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

Christian
Benutzeravatar
Heaterman
Beiträge: 3990
Registriert: Fr 28. Jun 2013, 10:11
Wohnort: Am Rand der Scheibe, 6 m unter NN

Re: Der AVR-/ARDUINO-Faden

Beitrag von Heaterman »

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?
Antworten