Arduino - zeitkritische Signale

OP #7490023
Lesenswert?

Hallo liebes Forum,

Ich habe auf der Arbeit ein Problem mit einem Arduino. Die Aufgabe des Arduino soll es sein, ein Signal für eine bestimmte vorher eingestellte Zeit auszugeben, am besten sehr genau. Dass die delay()-Funktion dafür nicht gut geeignet ist, ist mir bekannt, also habe ich es mit der millis()-Funktion versucht, aber auch hier ist das Ergebnis nicht viel genauer. (Beispiel: 500ms Soll-Schalten, 634ms Ist-Schalten). Beim Vermessen des Signals mit dem Oszi habe ich das Gefühl bekommen, dass die Zeiten rein zufällig sind, teils genau 500ms, dann aber auch mal 680ms. Hinzukommen andere komische Verhaltensweisen bei der Verwendung von Millis, zum Beispiel dass sich das ganze nicht wiederholen lässt, sondern der Arduino in einer "unsichtbaren" Schleife hängt. Ich habe vor etwas längerer Zeit schon mal etwas mit Timer-Interrupts gemacht. Die waren dann auch ziemlich genau, aber das scheint mir hier irgendwie ungeeignet.

Jetzt zu meiner eigentlichen Frage: Gibt es eine andere Möglichkeit, den Arduino zeitlich genauer zu nutzen oder ist er für zeitkritische Signale schlicht nicht gemacht?

Ich freue mich auf Eure Antworten, vielen Dank schonmal.

Moderator (Firma: Titel) Persönliche Seite #7490029
Lesenswert?

Johannes schrieb:

andere komische Verhaltensweisen bei der Verwendung von Millis

millis() verhält sich nicht "komisch", denn es ist lediglich ein Millisekundenzähler. Wenn du bei dessen Verwendung Probleme mit Abweichungen und Jitter hast, dann liegt das konkret allein an deinem Programm.

Ich habe vor etwas längerer Zeit schon mal etwas mit Timer-Interrupts gemacht. Die waren dann auch ziemlich genau, aber das scheint mir hier irgendwie ungeeignet.

Worauf basiert dieser Schein? millis() basiert auch auf einem Timer-Interrupt: vereinfacht kommt jede ms ein Interrupt, der den millis-Timer hochzählt.

Johannes schrieb:

ein Signal für eine bestimmte vorher eingestellte Zeit auszugeben, am besten sehr genau.

Quantifiziere "sehr genau" in Zahlen. Ich verstehe unter "sehr genau" Zeiten im ns-Bereich.

Timer-Interrupts gemacht. Die waren dann auch ziemlich genau

Wenn man ein Signal "sehr genau" high und low schalten will, dann nimmt man nicht mal einen Timerinterrupt, sondern man lässt den Timer per Compare-Register den Pin direkt toggeln.

#7490038
Lesenswert?

Johannes schrieb:

Ich habe auf der Arbeit ein Problem mit einem Arduino. Die Aufgabe des Arduino soll es sein, ein Signal für eine bestimmte vorher eingestellte Zeit auszugeben, am besten sehr genau.

Wie genau? Siehe Netiquette!

"Das Problem in Zahlen fassen! Nicht einfach schreiben "so schnell wie möglich", "so stromsparend wie möglich" etc, sondern mal ein paar Zahlen nennen. X MHz, Y ms, Z µA etc. Wenn man keine exakte Vorstellung davon hat, sollte wenigstens eine Größenordnung angegeben werden (1..5 MHz, <1mA etc.)"

Dass die delay()-Funktion dafür nicht gut geeignet ist, ist mir bekannt,

Das stimmt so allgemein nicht.

also habe ich es mit der millis()-Funktion versucht, aber auch hier ist das Ergebnis nicht viel genauer. (Beispiel: 500ms Soll-Schalten, 634ms Ist-Schalten).

Dann hast du maximalen Murks programmiert oder gemessen. millis() ist auf 1ms genau mit max. 1ms Jitter.

Beim Vermessen des Signals mit dem Oszi habe ich das Gefühl bekommen, dass die Zeiten rein zufällig sind, teils genau 500ms, dann aber auch mal 680ms.

Siehe oben.

Hinzukommen andere komische Verhaltensweisen bei der Verwendung von Millis, zum Beispiel dass sich das ganze nicht wiederholen lässt, sondern der Arduino in einer "unsichtbaren" Schleife hängt.

Siehe oben.

Ich habe vor etwas längerer Zeit schon mal etwas mit Timer-Interrupts gemacht. Die waren dann auch ziemlich genau, aber das scheint mir hier irgendwie ungeeignet.

So ein Unsinn!

Jetzt zu meiner eigentlichen Frage: Gibt es eine andere Möglichkeit, den Arduino zeitlich genauer zu nutzen

Sicher.

oder ist er für zeitkritische Signale schlicht nicht gemacht?

Quark.

Moderator #7490042
Lesenswert?

Johannes schrieb:

Dass die delay()-Funktion dafür nicht gut geeignet ist, ist mir bekannt, also habe ich es mit der millis()-Funktion versucht, aber auch hier ist das Ergebnis nicht viel genauer.

Weder delay noch millis erzeugen für sich gesehen ein Signal. Auf das Drumherum kommt es an, und da hast du offensichtlich Käse gebaut. Beseitige diesen Käse, und das Ganze wird funktionieren.

#7490088
Lesenswert?

Falk B. schrieb:

Yalu X. schrieb:

und da hast du offensichtlich Käse gebaut. Beseitige diesen Käse, und das Ganze wird funktionieren.

Nein Quark! Käse wird erst draus, wenn man den zu lange liegen läßt! ;-)

Dann sollten wir uns auf Milch einigen! Denn Milch ist die Grundlage allen Quarks und Käses!

Und wie ein Vorschreiber schon schrub, mit millis() kommt man auf eine Genauigkeit von einer Millisekunde +1ms Toleranz.

#7490131
Lesenswert?

Johannes schrieb:

Ich habe vor etwas längerer Zeit schon mal etwas mit Timer-Interrupts gemacht. Die waren dann auch ziemlich genau, aber das scheint mir hier irgendwie ungeeignet.

Warum sollten die ungeeignet sein, sind sie doch grade für zeitkritische Aktionen unumgänglich? millis() arbeitet IMHO auch mit Timerinterrupts aber das wurde ja schon erwähnt. Ich tippe darauf, dass das Problem zwischen Stuhl und Tastatur zu suchen ist ;)

#7490181
Lesenswert?

Johannes schrieb:

Gibt es eine andere Möglichkeit, den Arduino zeitlich genauer zu nutzen oder ist er für zeitkritische Signale schlicht nicht gemacht?

Um Ergebnisee wie die von Dir beschriebenen zu erzielen, muß man irgendwo granatenmäßig danebenliegen. Respekt!

Zum Erfolg könnte beitragen, die zwei Blinkprogramme in den Beispielen auszuprobieren. Einmal in Beispiele-01.Basics-Blink und einmal in Beispiele-02.Digital-Blinkwithoutdelay. Dort wird die millis-Funktion korrekt verwendet.

Beide Beispiele arbeiten sehr genau, wie man mit einer Stoppuhr (Smartphone reicht) leicht selber nachmessen kann.

Gruß Klaus (der soundsovielte)

#7490814
Lesenswert?

Ich habe einen Kollegen, der hat das gleiche Problem. Nur konnte ich da mal auf den Sourcecode schauen. Alles lief prima, bis die Details mit serial.printf() ausgegeben wurden. Und da hat diese Funktion eben eine ganze Zeit dafür benötigt. Ist halt ein Uart.

Irgendein Code von Johannes gibt's anscheinend nicht. Mehr ein Freitagstroll?

#7490828
Lesenswert?

Er ist immerhin schon mehr als einen Monat hier angemeldet. Den Echten Troll erkennt man an zeitnaher Anmeldung, und ward nie wieder gesehen.

Die Arduino-Welt versteckt ja alles was den jungen Anwender verwirren könnte. Interrupts sind viel zu kompliziert. https://de.wikipedia.org/wiki/Ad_usum_Delphini

Wenn man das Timing in Assembler oder C programmiert sind Impulse <1µs kein Problem. Der Arduino hat einen 16 MHz-Quarz, ein Takt dauert also 1/16 µs.

#7490850
Lesenswert?

Für zeitkritische Aufgaben haben Microcontroller idR Timer-Einheiten. Aber so lange Du die Aufgabe nicht genauer spezifizieren kannst, kann man auch keine vernünftige Antwort darauf geben. Was verstehst du unter "Signal genau ausgeben"? Ein Signal in der Nachrichtentechnik kann alles sein. Ein Puls, ein Ton, ein Lichtsignal, eine Radiosendung, ein Radar-Chirp, eine Gravitationswelle... Was ist dein "Signal"? Soll ein Rechteckpuls oder eine Folgen von Pulsen oder nur eine Flanke ausgegeben werden? Falls es ein Rechteckpuls sein soll, wie breit und mit welchen Toleranzen. Ist es egal, WANN er ausgegeben werden soll oder soll das Signal durch irgendwas getriggert werden. Wie soll der zeitliche Zusammenhang zum Trigger sein? Welcher Arduino soll verwendet werden oder ist das offen? Es gibt zig Arduinos mit den unterschiedlichsten Microcontrollern mit sehr verschiedenen Möglichkeiten, genaue Signale zu erzeugen. Deine Frage gleicht der Frage: ich möchte etwas schweres transportieren. Geht das mit einem Gabelstapler?

#7491225
Lesenswert?

Christoph db1uq K. schrieb:

Er will ja anscheinend in der Arduino-Entwicklungsumgebung programmieren. Da muss er nehmen was die anbietet.

Nö; man kann auch in der Arduino-Entwicklungsumgebung direkt mit den Timern arbeiten, und man kann sogar eigene Interruptroutinen dafür schreiben.

Man sollte nur nicht den Timer verwenden, der für das ganze delay() und millis-Gehampel verwendet wird, aber die meisten µCs haben ja mehrere davon ...

#7491234
Lesenswert?

Christoph db1uq K. schrieb:

Weiß man, welche davon belegt sind?

https://forum.arduino.cc/t/ubersicht-moglichkeiten-timer/193803

Timer gehen auf allen Prozessoren, aber der Mega hat mehr. Timer0 wird von millis() belegt. Timer2 ist sehr beliebt weil er sehr flexibel mit den einstellbaren Zeiten ist (durch die vielen Prescaler Optionen).

Gute deutsche Erklärung http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR 15

#7491244
Lesenswert?

Christoph db1uq K. schrieb:

mehrere davon Eins, zwei oder viele? Der Atmega328 hat drei. CNT0 bis 2

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

Kapitel 14-18. Weiß man, welche davon belegt sind?

Christoph, deine Anmerkungen zu den Zitaten werden bei mir hier immer an das Zitat angehängt. Da ist es schwierig, zu sehen, was du geschrieben hast ...

LG, Sebastian

#7491248
Lesenswert?

Christoph db1uq K. schrieb:

Weiß man, welche davon belegt sind?

https://forum.arduino.cc/t/ubersicht-moglichkeiten-timer/193803

Timer gehen auf allen Prozessoren, aber der Mega hat mehr. Timer0 wird von millis() belegt. Timer2 ist sehr beliebt weil er sehr flexibel mit den einstellbaren Zeiten ist (durch die vielen Prescaler Optionen).

Gute deutsche Erklärung http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR

bevor die Antwort im Grundrauschen untergeht

#7491321
Lesenswert?

Christoph db1uq K. schrieb:

benutzen im Hintergrund vermutlich auch die Timer, vielleicht sogar Interrupts, aber für den Anwender bleibt das verborgen.

... jedenfalls solange der Anwender sich standhaft weigert, in den Arduino Core Code zu gucken.

Dort steht z.B. in wiring.c, wie als Zeitbasis Timer0 mit Overflow-Interupt genutzt wird und wie millis() auf diese Zeitbasis zugreift.

#7491346
Lesenswert?

Timer0 mit Overflow-Interupt

Ok das ist eine Aussage. Aber dass man dazu tief im Quelltext wühlen muss, halte ich für einen Mangel. Klar, das wird alles zur Vereinfachung für Einsteiger getan. Aber irgendwann will sich jemand weiterbilden. Dann geht die Sucherei los.

Für zeitkritische Anwendungen könnte der Interrupt schon stören, wenn er vor dem eigenen Programm privilegiert ist.

Wenn man wirklich die Mikrosekunden optimiert, darf man keine Systemroutine benutzen, die unkontrolliert Rechnerzeit kostet.

Aber wir kennen ja die Anforderungen des TO immer noch nicht.

Gast #7491354
Lesenswert?

Christoph db1uq K. schrieb:

Aber dass man dazu tief im Quelltext wühlen muss,

Nicht tief. Schau dir mal die HAL von ST an!

Das Arduino Framework verbirgt viele Details mit Absicht. Direkte Registerzugriffe sind nicht vorgesehen. Schließlich sollen die Sketche im Idealfall auf allen Arduino Boards kaufen können.

Wer das blöd findet, kann ja gerne am Framework vorbei Programmieren. Doch wer halb Arduino und halb auf Registerebene kombiniert programmieren will, profitiert von den frei zugänglichen Quelltexten. Da muss man dann schon selbst wissen was man tut. Arduino hat eine andere Zielgruppe.

#7491379
Lesenswert?

kein Leerzeichen

Ich habe jetzt schon eine Leerzeile eingefügt, und dachte, dass damit jeder Browser zurechtkommt. Ich finde es nur nervig, wenn andere einen ganzen Text zitieren, und dann mit einer Zeile darauf antworten. Also werde ich noch ein Leerzeichen einfügen, danke für die Belehrung.

Den Bootloader ignoriere ich auch, früher war es PonyProg, danach Benedikts USBProg, bis die Entwicklung einschlief. Heute ist es ein USB..easy..blahblah, egal, für 16,95 von Conrad. Alles mit dem Atmel-Studio 4.19, das den für ein originales Atmel Eval-Board hält. Hauptsache Nachbauer können das ohne Hardwareprobleme nutzen.

#7491391
Lesenswert?

Wenn man init() und main() statt setup() und loop() verwendet, kann man die ganze Arduino-IDE verwenden und man ist Herr über alle Timer. Sogar Serial.begin und pinMode funktionieren, nur das delay() geht halt nicht mehr. Dafür kann man mit Timer 0, 1 und 2 herumprogrammieren, wie es einem beliebt!

#7491418
Lesenswert?

Helmut -. schrieb:

Wenn man init() und main() statt setup() und loop() verwendet, kann man die ganze Arduino-IDE verwenden und man ist Herr über alle Timer. Sogar Serial.begin und pinMode funktionieren, nur das delay() geht halt nicht mehr. Dafür kann man mit Timer 0, 1 und 2 herumprogrammieren, wie es einem beliebt!

Dieser Sachverhalt ist natürlich gut zu wissen. Andrerseits finde ich die Arduino-Framework-Beanspruchung der uC Ressourcen als nicht zu störend um nicht nutzbringend die Arduino Framework "Vorarbeit" nicht einsetzen zu wollen.

Augenscheinlich wird ja nur der Timer0 und die USART HW vom Arduino Framework beansprucht. Timer1 und 2 sind vollkommen frei und können in der üblichen Weise "Bare Metal" konfiguriert werden.

Für gewisse Anwendungsfälle kann man einen zusätzlich Interrupt für Timer0 sinnvoll hinzufügen, um eigene Zusatzfunktionen mit hineinzuzwängen.

Abgesehen davon meckert der Compiler ohnehin gleich, Wenn man dem Arduino Framework ins Gehege kommt.

Was meine üblichen Anwendungen betrifft, empfinde ich die Arduino Framework Ressourcen-Beanspruchung eigentlich nicht als wirklich störend.

Die SERIAL und Timer0 Services sind ja in vielen Fällen ohnehin nützlich und fallen nur sehr selten störend auf. Und wenn es wirklich nicht geht, dann kann man ohne Framework auskommen.

Was mich betrifft, verläuft die Framework Belastung des uC nur in mässigen Bahnen.

Gerhard

#7491434
Lesenswert?

Gerhard O. schrieb:

Augenscheinlich wird ja nur der Timer0 und die USART HW vom Arduino Framework beansprucht. Timer1 und 2 sind vollkommen frei und können in der üblichen Weise "Bare Metal" konfiguriert werden.

Arduino ist für mich primär ATMega328. Da ist schon auffällig, dass die PWM-Ausgänge zwei unterschiedliche Frequenzen haben.

Mal kurz G* gefragt und da gelandet: https://nerd-corner.com/de/arduino-timer-interrupts-arduino-register-programmieren/#Arduino_Uno_Mikrocontroller_ATMEGA328P

8 Bit-Timer0: wird genutzt für die Funktionen millis(), micros(), delay() und für PWM an Pin D5 und D6

16 Bit-Timer1: wird z. B. für die Bibliothek Servo, VirtualWire, TimerOne und für PWM an Pin D9 und D10 genutzt

8 Bit Timer2: wird genutzt für Funktion tone() und für PWM an Pin D3 und D11

Das heißt, dass jegliche Fingerei an den Timern zu Kollisionen mit Arduino-Funktionen führen kann.

Aber sein Problem wird im Gesamtablauf liegen, meinem Datenlogger ist der 1-Sekunden-Zyklus zu Beginn auch aus dem Ruder gelaufen.

Sebastian W. schrieb:

teils genau 500ms, dann aber auch mal 680ms

Das liegt an den anderen delay() oder ähnlichen Warteschleifen die in deinem Code (oder in von deinem Code benutzten Bibliotheken) noch irgendwo drin sind. Solange der Arduino in so einem delay() hängt kommt er nicht zu den millis() zurück!

Das muß nicht unbedingt "das böse delay" sein: Ich habe in der Hauptschleife meiner Anwendung(en) mehrere Abfragen auf millisec(). Wenn da gerade z.B. die Aktualisierung des Displays angestoßen wurde und diese 80ms dauert, erwische ich die nächste Abfrage erst entsprechend verzögert, das ist nicht kalkulierbar.

Wenn die 500ms zuverlässig sein sollen, darf in loop() keine weitere Aktion stattfinden, was ich für wenig realistisch halte.

#7491439
Lesenswert?

Moin,

"Das heißt, dass jegliche Fingerei an den Timern zu Kollisionen mit Arduino-Funktionen führen kann."

Gut, daß Du das hier klar gestellt hast. Was aber meine meisten Anwendungen betrifft, programmiere ich alles andere selber und ich lasse nur das USART und T0 in Ruhe. Auf alles andere habe ich dann unbehinderten Zugang. So meinte ich das in meinen Ausführungen.

T1 und T2 werden ja erst bei Einsatz der besagten Bibliotheken beansprucht und liegen sonst brach.

Gerhard

#7491465
Lesenswert?

Johannes schrieb:

Gibt es eine andere Möglichkeit, den Arduino zeitlich genauer zu nutzen oder ist er für zeitkritische Signale schlicht nicht gemacht?

"Den Arduino" gibt es nicht. Es gibt eine ganz Reihe von Arduino Boards, die z.T. deutlich unterschiedliche Mikrocontroller verwenden. "Arduino" bezeichnet ein Softwareframework und eine (abgespeckte) IDE, die versucht, alle diese Boards unter eine Haube bringen. Das ist teilweise mit eingeschränkter Nutzung der HW verbunden. Wenn du ein genaues Timing erzeugen willst, kannst du bspw. direkt einen der nicht genutzten Timer benutzen. Welche bei dir frei sind, hängt von deinem Programm und von deinem Controller ab. Lediglich Timer0 ist IMHO normalerweise immer durch durch die Zeitfunktionen (millis(), delay () usw. belegt. s. verlinkte GitHub Doku zur Timerinterrupt-Library https://www.arduino.cc/reference/en/libraries/timerinterrupt/

Bei 500ms ist ein eigener Timer allerdings nicht nötig, falls die Zeit nicht auf die Mikrosekunden stimmen muss. Du könntest dich dafür in den Timerinterrupt reinhängen und direkt dort deinen Pin kontrollieren. Dann bist du weitgehend unabhängig von blockierenden Programmen in deiner Hauptschleife - so keines boshafter-/ungeschickterweise den Timerinterrupt sperrt - und gibst aber möglicherweise die direkt Nutzbarkeit deiner SW auf anderen Arduino-Boards auf.

#7491483
Lesenswert?

Alle die hier scheinbar Scheuklappen auf haben: der TO hat sich letzten Freitag (Trolltag) gemeldet und seitdem nicht mehr. Demnach ist alle Liebesmüh um das Thema vergeblich bzw. für die Katz. Nur wenn hier ein Dialog zwischen TO und der Community entstehen würde, würde der Thread hier noch irgendwie Sinn machen, ausser dass hier auf den TO geschimpft wird und die Forums-Teilnehmer sich profilieren.

#7491593
Lesenswert?

zielführenden Antworten

Ja, das war interessant. In Interruptprogrammen musste man schon immer auf Konflikte mit dem Hauptprogramm achten, das ist ja nichts neues.

Noch eine kleine Frage: Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen, oder brauche ich unbedingt irgendeinen USB-Programmer? Es geht um das Problem, wenn ich eine Binärdatei veröffentliche, kann man die auch ohne Zusatzhardware flashen, oder kauft sich ein Nachbauer besser einen Programmer. Mein letzter hat <20€ gekostet, früher war das wesentlich teurer.

#7491597
Lesenswert?

Christoph db1uq K. schrieb:

Noch eine kleine Frage: Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen,

Sicher.

oder brauche ich unbedingt irgendeinen USB-Programmer?

Nein.

Es geht um das Problem, wenn ich eine Binärdatei veröffentliche, kann man die auch ohne Zusatzhardware flashen,

Sicher. Man braucht dann halt avr dude & Co.

#7491606
Lesenswert?

Danke Falk

https://github.com/avrdudes/avrdude/releases https://www.nongnu.org/avrdude/

Die Info zum Arduino Bootloader ist recht knapp: "The Arduino (which is very similar to the STK500 1.x) is supported via its own programmer type specification “arduino”. This programmer works for the Arduino Uno Rev3." "Following programmer types are currently implemented: arduino - Arduino programmer ..."

Aber hier in der Artikelsammlung steht es besser: https://www.mikrocontroller.net/articles/AVRDUDE#AVRDUDE_mit_Arduino_Bootloader_benutzen in der Kommandozeile "beispielsweise avrdude -c arduino -p m168 -P usb -U flash:w:<filename>"

Das kann man auch einem Nachbauer irgendeiner Hardware zumuten, wenn er nichts anderes hat. Einen Funktionsgenerator, Messender oder ein Amateurfunkgerät dessen PLL über SPI eingestellt wird könnte man damit betreiben.

#7491636
Lesenswert?

Christoph db1uq K. schrieb:

Noch eine kleine Frage: Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen, oder brauche ich unbedingt irgendeinen USB-Programmer?

Vielleicht diskutierst du das in einem separazen Thread. Mit der Erzeugung zeitkritischer Signale durch einen Arduino hat das doch nun wirklich herzlich wenig zu tun.

#7491665
Lesenswert?

Christoph db1uq K. schrieb:

Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen

Natürlich. Der Bootloader ist einfach nur ein Programm im Flash, das vor dem Hauptprogramm abgearbeitet wird. Sobald das Hauptprogramm abgearbeitet wird, macht der nichts mehr. Außer Flash zu belegen.

Allerdings ist der Arduino Bootloader weder besonders klein noch bietet er besondere Features. Er wird halt nur gerne genommen, weil er standardmäßig auf den meisten [1] Arduinos vorinstalliert ist. Du kannst genausogut einen anderen Bootloader verwenden.

Allerdings hat das Programmieren per Bootloader ein paar Macken. So kannst du z.B. keine Fuses setzen. Und der Bootloader verändert i.d.R. einige Hardware-Register, die stehen dann nicht mehr auf den Reset-Defaults.

[1] allerdings lassen einige Billiganbieter den Bootloader auch gerne mal weg. Das erwischt dann die Arduino-Fraktion kalt. Deswegen ist es immer ratsam, einen ISP-Programmer griffbereit zu haben.

#7491687
Lesenswert?

War auch nur so eine Idee für den Hardcore-Hardwaremenschen ohne AVR-Programmer. Das Elektronikhobby ist seit langem in das Lager der Software- und Hardwareleute gespalten, man meidet meistens das andere, kann den Kontakt aber nicht immer verhindern.

z.B. keine Fuses setzen

Für drei Fuses braucht man sogar einen speziellen "Hochspannungs"-Programmer, das geht auch nicht mit einem einfachen USB-Programmer: https://www.mikrocontroller.net/articles/AVR_Fuses#SPIEN,_DWEN_und_RSTDISBL

einen anderen Bootloader

das klassische Henne-Ei-Problem, wenn noch keiner drin ist brauche ich einen externen Programmer um den reinzubekommen.

#7491772
Lesenswert?

Christoph db1uq K. schrieb:

das klassische Henne-Ei-Problem, wenn noch keiner drin ist brauche ich einen externen Programmer um den reinzubekommen.

Der Trend geht ganz klar zum Zweitboard.

Arduino hat das Problem dahingehend gelöst, dass sich in den Beispielen der Sourcecode findet, um temporär einen in einen ISP-Programmer zu verwandeln - Henne-Ei-Problem gelöst. Nimm einfach einen Arduino als Programmer.

Gast #7491787
Lesenswert?

Rainer W. schrieb:

Der Trend geht ganz klar zum Zweitboard.

Arduino hat das Problem dahingehend gelöst, dass sich in den Beispielen der Sourcecode findet, um temporär einen in einen ISP-Programmer zu verwandeln - Henne-Ei-Problem gelöst. Nimm einfach einen Arduino als Programmer.

Das gilt dann, und nur dann, wenn Du einen AVR-Arduino benutzt. Die Boot-Loader der neuen Boards (z.b. Arduino Uno Rev 4(!)) kannst Du so einfach nicht mehr programmieren, Du brauchst einen Programmer (Renesas Flash Programmer).

Gruesse

Turbine

(Firma: Gast) #7491789
Lesenswert?

Rainer W. schrieb:

Henne-Ei-Problem gelöst.

Einige Arduino AVR Boards haben eine 16U2 als USB-Serial Adapter on Board. Diesen kann man per Flip zum ISP Programmer machen.

Auch so kann man das Henne Ei Problem geschickt umschiffen, selbst wenn nur 1 einziges Board zur Verfügung steht.

Axel S. schrieb:

Allerdings ist der Arduino Bootloader weder besonders klein

Der UNO Bootloader hat 512 Byte. Ist auch problemlos auf dem Nano verwendbar.

Christoph db1uq K. schrieb:

Die Info zum Arduino Bootloader ist recht knapp:

Alle Arduino Bootloader liegen im Quellcode in der Arduino AVR Boarddefinition vor incl. Makefile.

Gast #7491795
Lesenswert?

Aber noch einmal zum Problem des TOs zurueckzukommen: Er benutzt einen Arduino (nehmen wir mal an, AVR mit 16MHz) und moechte 500ms (=0.5s) "abwarten". Das ist eine halbe Ewigkeit fuer den ATMEGA328P! Oder habe ich mich ein paar Zehnerpotenzen verrechnet?

-> Entweder Troll oder BWLer.

Gruesse

Turbine

#7491808
Lesenswert?

Moin,

Es ist mir bewußt, daß ihr mich für das Folgende verhauen werdet:-)

Diese ganze Fragen um die Zeitpräzision von uC Prozessen mit HW liegen m.A. darin begründet, daß man versucht durch besondere Programmiertechniken genaue Zeitabläufe zu erzwingen um HW aus falschem Ehrgeiz zu ersparen. Das ist ähnlich wie jemanden in eine Zwangsjacke stecken zu wollen.

Ich finde aber, dass gerade dies, falsches Denken ist.

Genaue Zeitabläufe sollte man auschließlich mit entkoppelter spezifischen HW realisieren. Die uC FW sollte nur für Parametrisierung und Überwachung und Bedienung zuständig sein und mit der entsprechenden HW nur bei Änderungen der Aufgaben eingreifen. So funktionieren bekanntlich auch die Timer/Capture/Compare Ressourcen, wo man beträchtlichen Aufwand treibt, um Registerzugriffe zu entkoppeln.

Damit wären dann Steuerung, Bedienung und Communication weitgehend entkoppelt. Bei komplexen Anwendungen ohnehin zwingend notwendig um Latenzen zu verringern. Das würde auch vermeiden, Jitterprobleme mit unregelmäßigen ISR Abläufen oder zeitweisen ISR Sperrungen im Main-Line Prozess zu haben. Das Anwendungsprogramm sollte idealerweise hauptsächlich als "großer Ccordinator" dienen, aber sonst die "Underlinge" in Ruhe lassen.

Das Einzwängen des Programms in das Timing-Gefüge führt oft typisch notwendigerweise zu vielen unbequemen Kompromissen.

Das Einzwängen der FW in Timing Prozessen führt notwendigerweise auch zu erheblichen Erweiterungsschwierigkeiten.

Jedenfalls ziehe ich HW intensive Realisierung kritischer HW vor, um viele dieser Kompromisse von vornherein auszuschließen. Das Resultat eines solchen Vorgehens ist dann ein robustes, gleichmässig funktionierendes Gerät.

Gerhard

#7491820
Lesenswert?

Gerhard O. schrieb:

Genaue Zeitabläufe sollte man auschließlich mit entkoppelter spezifischen HW realisieren. Die uC FW sollte nur für Parametrisierung und Überwachung und Bedienung zuständig sein

Genau dafür sind z.B. die Timer im uC vorhanden - werden durch die Software konfiguriert und laufen dann unabhängig. In Zeiten von Mikroprozessoren hattest du die Komponenten noch einzeln auf dem Board, jetzt sind sie auf einem Chip in den uC integriert.

#7491937
Lesenswert?

Christoph db1uq K. schrieb:

Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen, oder brauche ich unbedingt irgendeinen USB-Programmer?

Es geht sogar auch andersherum. Ich habe zum Beispiel einen CAN-Bootloader für AVR geschrieben, der per Arduino-IDE generierte HEX-Dateien über eine MQTT-CAN-Brücke entgegennimmt und flasht.

LG, Sebastian

Beitrag #7491939 wurde von einem Moderator gelöscht.
#7491945
Lesenswert?

Gerhard O. schrieb:

Genaue Zeitabläufe sollte man auschließlich mit entkoppelter spezifischen HW realisieren.

Diese Ausschließlichkeit halte ich aus meiner Erfahrung heraus für falsch. Man kann sehr wohl auf einem uC vielfältige Aufgaben abarbeiten, und dennoch zeitkritische Anforderungen erfüllen. Natürlich braucht es dafür ein gutes Konzept, so zum Beispiel eine Analyse und dann Zusicherung maximaler Verarbeitungszeiten von Einzelaktionen. Wenn dann die Aktualisierung des Displays 80ms dauert, dann muss diese Aktualisierung halt in eine Vielzahl kleinere Updates zerlegt werden, zwischen denen dann Aktionen höherer Priorität stattfinden können. Für jede Aufgabe separate Hardware vorzusehen führt dagegen u.U. sogar zu noch weniger deterministischem Zeitverhalten ...

LG, Sebastian

#7492034
Lesenswert?

Christoph db1uq K. schrieb:

Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen, oder brauche ich unbedingt irgendeinen USB-Programmer?

Ja, Nein, Vielleicht - suche es Dir aus.

Zuerst muß eine Datei erzeigt werden, deren Lage im Speicher und deren Resetvektor den vorhandenen Bootloader berücksichtigt.

Und dann muß ein Programm her, was den Bootloader füttert. Die Arduino-IDE löst einen Reset aus, der µC meldet sich - und nun liefert die A*-IDE die Daten. Das musst Du wohl irgendwie nachbauen.

Axel S. schrieb:

Christoph db1uq K. schrieb:

Wenn ich das Arduino Softwarebiotop komplett vermeide, kann ich trotzdem den Bootloader benutzen um eine "Binärdatei" zu flashen

Natürlich. Der Bootloader ist einfach nur ein Programm im Flash, das vor dem Hauptprogramm abgearbeitet wird. Sobald das Hauptprogramm abgearbeitet wird, macht der nichts mehr. Außer Flash zu belegen.

Das gilt für jeden Bootloader, nicht nur Arduino.

Allerdings ist der Arduino Bootloader weder besonders klein noch bietet er besondere Features.

Doch: Ein Bootloader bietet das Feature, ein fertiges Gerät ganz einfach über eine eh vorhandene Schnittstelle updaten zu können, ohne spezielle Hardware zu brauchen.

Allerdings hat das Programmieren per Bootloader ein paar Macken. So kannst du z.B. keine Fuses setzen.

Das ist egal, die werden einmal gesetzt und nicht mehr verändert.

Und der Bootloader verändert i.d.R. einige Hardware-Register, die stehen dann nicht mehr auf den Reset-Defaults.

Warum glaube ich das nicht? Das macht die A*-IDE bei der Erzeugung des Binärfiles.

#7492100
Lesenswert?

Manfred P. schrieb:

Axel S. schrieb:

Der Bootloader ist einfach nur ein Programm im Flash, das vor dem Hauptprogramm abgearbeitet wird. Sobald das Hauptprogramm abgearbeitet wird, macht der nichts mehr. Außer Flash zu belegen.

Das gilt für jeden Bootloader, nicht nur Arduino.

Deswegen schrieb ich auch "Der Bootloader". Und nicht "der Arduino-Bootloader".

Allerdings ist der Arduino Bootloader weder besonders klein noch bietet er besondere Features.

Doch: Ein Bootloader bietet das Feature, ein fertiges Gerät ganz einfach über eine eh vorhandene Schnittstelle updaten zu können, ohne spezielle Hardware zu brauchen.

Nun, dieses Feature hätte man auch kaum weglassen können, ohne den Anspruch auf die Bezeichnung "Bootloader" zu verlieren. Aber ich schrieb ja auch "besondere Features". Etwa einen Prüfsummencheck. Oder eine Verschlüsselung der Firmware.

Allerdings hat das Programmieren per Bootloader ein paar Macken. So kannst du z.B. keine Fuses setzen.

Das ist egal, die werden einmal gesetzt und nicht mehr verändert.

Das ist keineswegs egal. Dir vielleicht, dem Rest der Welt nicht. Und schon gar nicht, wenn es (wie hier) um die Verwendung von nicht-Arduino Code geht.

Und der Bootloader verändert i.d.R. einige Hardware-Register, die stehen dann nicht mehr auf den Reset-Defaults.

Warum glaube ich das nicht? Das macht die A*-IDE bei der Erzeugung des Binärfiles.

Hast du überhaupt verstanden, was ich gesagt habe? Wenn der Arduino-Bootloader den UART initialisiert, dann haben dessen Register nicht mehr den Zustand wie nach dem Reset. Zwar könnte der Bootloader den Zustand wie nach den Reset wiederherstellen, aber ich weiß nicht ob er es tut.

Und weil ich auch diesmal nicht "Arduino-Bootloader" geschrieben habe: bei einem anderen Bootloader weiß ich es auch nicht. Deswegen kann mein Programm sich auch nicht darauf verlassen (ohne Bootloader aber schon).

Im Idealfall steht das in der Dokumentation des Bootloaders. Im schlimmsten Fall muß ich den Bootloader dafür sezieren.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren