Abhängigkeit Delaywert und MHz-Wahl unklar

Hallo,

da ich es in keinem Buch erklärt finde, ist es wahrscheinlich so banal, dass man es gar nicht erklären muss. Aber dennoch fällt gerade nicht der Groschen und es würde mich freuen, wenn dabei wer hilft:

"delay(1000)" bewirkt, dass etwas eine Sekunde dauert bzw. wartet, ... sofern ich unter Werkzeuge/Clock: "1MHz" auswähle.

Wenn ich z.B. 8MHz auswähle verstehe ich darunter erst einmal, dass der uC das Programm 8x so schnell abarbeitet und ein Delaywert von 8000 also einer Sekunde entspräche.

Aber das genau Gegenteil ist der Fall, das Programm läuft dann 8x so langsam, ein Delaywert von 125 entspricht dann real einer Sekunde.

Wieso? Was muss ich mir denn da anders vorstellen bzw. anders nachvollziehen?

Danke!

“delay(1000)” bewirkt, dass etwas eine Sekunde dauert bzw. wartet,

So sollte es IMMER sein.

Wenn es nicht so ist (ein Delaywert von 125 entspricht dann real einer Sekunde) dann machst du was falsch!

Alle Prescalerberechnungen erfolgen anhand des F_CPU Wertes.

Wenn ich z.B. 8MHz auswähle verstehe ich darunter erst einmal, dass der uC das Programm 8x so schnell abarbeitet und ein Delaywert von 8000 also einer Sekunde entspräche.

Wenn du 8MHz im Menu auswählst, teilst du der IDE mit, dass sie F_CPU auf 8MHz setzen soll.

Der Kompiler weiß nichts von der realen Einstellung. Aber du hast ihm glaubhaft 8MHz mitgeteilt.

Jetzt liegt es an dir, den Taktgenerator/Oszillator genau so zu konfigurieren.
Richtiger Quarz, oder richtigen RC wählen.
Fuses richtig setzen.
Im Programm evtl. noch den richtigen Prescaler setzen.

Dann klappts auch mit deinem delay(1000)

marc16: "delay(1000)" bewirkt, dass etwas eine Sekunde dauert bzw. wartet, ... sofern ich unter Werkzeuge/Clock: "1MHz" auswähle.

Wenn ich z.B. 8MHz auswähle verstehe ich darunter erst einmal, dass der uC das Programm 8x so schnell abarbeitet und ein Delaywert von 8000 also einer Sekunde entspräche.

Aber das genau Gegenteil ist der Fall, das Programm läuft dann 8x so langsam, ein Delaywert von 125 entspricht dann real einer Sekunde.

Wenn dein Controller mit 1Mhz arbeitet und du beim Compilieren 1Mhz angibst, dann stimmt die Zeit. Sagst du dem Compiler 8Mhz und dein Controller läuft weiterhin nur mit 1Mhz, dann kommen 8mal längere Zeiten heraus, da der Compiler davon ausgeht, dein Controller liefe 8mal so schnell.

Deine Überlegung wäre für einen 8Mhz Controller, der ein für 1Mhz compiliertes Programm bekommt, richtig.

Welche Hardware, welcher µC?

Wenn ATtiny, dann in der IDE Werkzeuge/Bootloader brennen wählen. Dann werden die schon erwähnten Fuses gesetzt, damit auch der interne Takt (internal oszillator) mit dem übereinstimmt, den der Compiler annimmt.

Beim ATtiny kann ein Bootloader übertragen werden, er kann aber auch "leer" sein (empty). Das kan man in der IDE wählen. Meist steht dann da was von "optiboot", beispielsweise wenn Du die Dateien von https://github.com/SpenceKonde/ATTinyCore nimmst.

Danke für die Antworten. Aber ich komme jetzt nicht ganz mit. Der Sinn von Arduino im Gegensatz zu C oder anderen "richtigen" Sprachen ist doch nun genau und gerade der, dass man sich als Hobbyprogrammierer mit Stolpersteinen wie Adressen & Fuse etc. NICHT herumschlagen muss. Oder anders gesagt, dass alles, was in Arduino denn angeboten wird, auch "narrensicher" vereinfacht ist.

Und unter "Werzeuge/Clocks" wird denn nun mal angeboten: 1Mhz und 8Mhz? Wieso reicht es dann dort nicht aus, einfach an genau dieser Stelle die Auswahl zu treffen, und alles andere passiert automatisch?

(Ich nenne immer wieder 1 und 8 MHz, weil es diese Zeiten z.B beim Atmega 168 als "internal"-Auswahl gibt. Dass es sich mit Gebrauch externer Quarze nochmals ganz anders verhält, ist schon klar. )

OK, du neigst etwas zum jammern und heulen…

Natürlich nimmt dir die IDE viel ab.
Aber eben nicht alles, und schon gar nicht die Sonderfälle.

Ich kenne kein mitgeliefertes 1 vs 8MHz Menu in der IDE.
Das ist also irgendein dazu installierter Kram, welcher mit Arduino.cc nichts zu tun hat.
Also eine FremdHardwareDefinition.
Und für fremd Hardware und Software kannst du die IDE nicht verantwortlich machen.

Wenn das Menu 1 und 8 MHz anbietet, dann sollten in der boards.txt auch die Fuses Einträge passend gesetzt sein. Damit die IDE diese auf den ATMega brennen kann, musst du “Bootloader brennen” drücken.

Den Schritt, hast du wohl übersehen/vergessen…

Wenn du originale Arduinos verwendest, ist das bei denen schon bei der Auslieferung gemacht worden.

Jetzt alle Klarheiten beseitigt?

1 bzw. 8 MHz wird defaultmäsig erstmal überhaupt nicht angeboten (jedenfalls bei meiner Version 1.8.5 gibt es keinen Menüpunkt "Werkzeuge/Clock"). Auch wenn du deine Boards erweiterst, kannst du "narrensicher" das Teil auswählen, das du auch verwendest. Evtl. kannst du auch per "Bootloader Brennen" die Fuses verstellen, so dass dein Arduino mit einem "falschen" Takt läuft. Das ist aber jenseits eines "narrensicheren" Einstiegs.

delay(1000) soll auf jeden Fall 1000 ms warten, ohne dass du dir beim Sketch schreiben Gedanken machen musst, mit welcher Taktfrequenz dein Arduino läuft. (Soll auch narrensicher sein)

Wenn deine Board-Auswahl nicht mit der Realität übereinstimmt, kann es sein, dass ein Upload leider trotzdem funktioniert. Dann passiert natürlich evtl. irgendwas unverhergesehenes, u.U. stimmen die Zeiten von delays nicht, oder Serielle Geschwindigkeiten passen nicht. Kann aber auch sein dass "gar nichts" geht. Oder das Upload klappt nicht und du siehst "avrdude thank you" statt eines fetten Fehlers.

Alles nicht komplett narrensicher, ok, aber wenn delay(1000) nicht 1 sec wartet, wäre es sicher falsch, den Sketch zu ändern.

Wenn Du einen ATmega mit 1 Mhz Takt hast (interner Taktgenerator oder externer Quarz) und den Sketch für 1Mhz kompilierst dann ist funktioniert delay() mit 1mS. Wenn Du den Sketch für 8Mhz kompilierst aber die Hardware auf 1Mhz läuft dann läuft delay() 8 mal schneller.

Die Taktquelle kannst Du nur über ISP durch setzen von Fuses ändern, nicht durch upload über USB.

Die Taktfrequenz in der IDE muß mit der Taktfrequenz der Hardware übereinstimmen damit Zeitabhängige Funktionen mit der richtigen Zeit arbeiten. Außer delay() sind das auch analogWrite(), tone(), pulseIn(), shiftIN(), shiftout(), delayMicroseconds(), micros(), millis(), analogRead(), serial. Aber auch Bibliotheken wie FastSPI, Servo und viele mehr.

Einige der zeitabhängigen Funktionen funktionieren bei falscher Taktfrequenz falsch, andere gar nicht und bei wieder anderen hängt es von der angeschlossenen Hardware ab ob sie (korrekt) funktionieren. (zB funktioniert FastSPI mit WS2812 nicht, mit WS2801 schon)

Grüße Uwe