Hab mal paar "Experiemte" mit dem Arduino Mega gemacht.
Dabei interessierte mich, wie schnell ein Portpin in Software zu toggeln
ist.
Ein einfacher "Sketch" brachte es auf 78,7 KHz.
Bei 16MHz viel zu wenig.
Vergleichsweise schafft man es in Assembler auf 2,6667MHz, in C ebenso.
Hier der Arduino "Pseudocode":
//Ardurino Pin 12 so schnell wie möglich in Software toggeln
int port = 12;
void setup() {
pinMode(port, OUTPUT);
}
void loop() {
digitalWrite(port, HIGH);
digitalWrite(port, LOW);
}
Dafür braucht die CPU 630.400 Zyklen?????
In Assembler:
.INCLUDE "m2560def.inc"
rjmp main
main:
ldi R16,0xFF
out DDRB,R16
ldi R16,0xFF
out PORTB,R16
sbi portb,6
cbi portb,6
rjmp PC-2
Ein Durchlauf benötigt 6 Zyklen.
Benutz man stattdessen in der Schleife nur "SBI PINB,6" (der Mega 2560
kann das, dann sind es 8, also genau 2 MHz.
Was bremst den Arduino-Code so aus? Was macht "DigitalWrite" alles noch?
Kuck doch einfach mal rein in digitalWrite(). Ist ja OpenSource.
Hatte es neulich gemacht. Kann mich noch dran erinnern, dass der Pin
auch als PWM Pin und anderes benutzt werden kann.
Daniel schrieb:> Ein einfacher "Sketch" brachte es auf 78,7 KHz.> Bei 16MHz viel zu wenig.
Nicht für einen Arduino.
> Was bremst den Arduino-Code so aus? Was macht "DigitalWrite" alles noch?
feststellen welcher Pin zu '12' gehört und den dann je nachdem ob du
High oder Low haben willst, schalten.
Danach: den return aus loop() machen.
Beim Aufrufer dann die Buchhaltung durchführen, loop() wieder aufrufen
und den nächsten digitalWrite machen.
... oder anders ausgedrückt: Die Wolle, der eierlegenden Wollmilchsau,
ist nicht die Feinste und die Eier könnten etwas größer sein.
Auch ohne je in die Bibliotheken geschaut zu haben, sollte das obige
Ergebnis eigentlich vorhersehbar sein - wenn auch vielleicht nicht in
der aufgezeigten Größenordnung.
Daniel schrieb:> Sind natürlich bei 78,8KHz "nur" ca 101 Zyklen für einen> Umschaltvorgang. Das ist ja irre...
Nö. Nicht für einen Umschaltvorgang.
Für einen kompletten Turnaround von einem Aufruf von loop() zum
nächsten, vergehen 203 Takte.
Und das ist dann ein bischen was anderes.
Oder denkst du, dass du zb eine Systemuhr gratis kriegst?
ein Umschaltvorgang ist doch von 0->1 oder umgekehrt. Dabei vergehen
101 Take. 2 Umschaltvorgänge sind dann ein (kompletter)Zyklus.
Oder was meinst du mit Systemuhr?
Wenn man aber von, oft sehr unrealistischen Megaherzphantasien
herunterkommt: Ist das wirklich zu langsam?
Oder anders ausgedrückt: Wie realistisch ist die obige Schleife mit,
völlig unrealistischen 6 bzw. 8 Taktzyklen?
Das Minimum der obigen Schleife enthält eine - wie auch immer geartete -
Zählerabfrage. Also nix mit 6/8 Taktzyklen.
Meine Aktivitäten in Sachen Pin setzten folgten bisher immer dem Chema:
...
Grübel, grübel
Pin an
Grübel, grübel
Pin aus
...
Das Minimum war das Abholen von Messwerten und einfache Vergleiche. Das
Maximum waren komplexe Rechnungen und Spaziergänge quer durch die
Fließkommabibliotheken.
Irgendwann werden dann plötzlich zusätzliche 203 Takte zu einem Nichts,
oder man stellt fest, dass der Prozessor ungeeignet ist.
>Irgendwann werden dann plötzlich zusätzliche 203 Takte zu einem Nichts,
Mach mal ein Software SPI oder PWM. Dann wird ganz schnell klar
warum das nichts taugt.
Mir ging es primär gar nicht darum irgendwelche MHz Orgien zu
veranstalten.
Dafür gibt es Fast PWM & Co.
Wollte einfach nur wissen, ob der so unschuldig aussehende
"DigitalWrite" Befehl wirklich nur den Pin - so wie im
Assembler-Beispiel - ohne weitere Verzögerung umschaltet. Tut er nicht,
ok.
Damit ist er ungeeignet, wenn es mit dem Timing mal wirklich knapp
zugeht. Möchte garn nicht wissen, was die anderen Adruino Makros so
alles veranstalten.
Schon die kompilierte Codegröße hat mich stutzig gemacht.
@Holger
>Mach mal ein Software SPI oder PWM. Dann wird ganz schnell klar>warum das nichts taugt.
Stimmt, aber ...
@Daniel
>Damit ist er ungeeignet, wenn es mit dem Timing mal wirklich knapp>zugeht. Möchte garn nicht wissen, was die anderen Adruino Makros so>alles veranstalten.
Macht’s wie ich. Bisher habe ich drei Arduinos verwendet. Bei Zweien
habe ich, wenn auch aus anderen Gründen, die Entwicklungsumgebung
beiseitegeschoben und das "normale" Studio rangelassen. ISP bringt’s.
Ein Grund für den Arduino blieb nämlich: Es ist ein relativ günstiges
und gut dokumentiertes Stück Elektronik, welches in zwei Fällen, die
gesamte benötigte Elektronik enthielt. Im dritten Fall war der Micro
ein, die gesamte Schaltung vereinfachendes, "IC".
holger schrieb:>>Irgendwann werden dann plötzlich zusätzliche 203 Takte zu einem Nichts,>> Mach mal ein Software SPI oder PWM. Dann wird ganz schnell klar> warum das nichts taugt.
Warum sollte man SPI oder PWM mit digitalWrite() machen? Schließlich ist
das ja eine der (har har) Stärken von Arduino, daß man SPI und PWM als
Fertigteil bekommt, das man nur noch einstöpseln muß.
Dein Argument ist in etwa auf dem Niveau, daß sich Ytong-Steine schlecht
als Bauklötze eignen, weil die damit gebauten Projekte so schlecht ins
Kinderzimmer passen.
XL
Daniel schrieb:> ein Umschaltvorgang ist doch von 0->1 oder umgekehrt. Dabei vergehen> 101 Take. 2 Umschaltvorgänge sind dann ein (kompletter)Zyklus.> Oder was meinst du mit Systemuhr?
Nein. Ich meine, dass das Arduino System(!) im Hintergrund auch noch
andere Sachen macht. Deine Endlosschleife ist eben nicht dasselbe, wie
die Funktion loop(). Denn da gibt es auch noch einen Aufrufer, der
loop() ständig aufruft und zwischen den Aufrufen auch noch Dinge
erledigt. Ich würde durchaus soweit gehen und dem Arduino System bereits
Eigenschaften eines kleines Betriebssystems zusprechen.
Kurz gesagt: du vergleichst in einem gewissen Sinne Äpfel mit Birnen.
Ist zwar langsam, dafür ist es einfach.
Wenn ich vergleiche, was da sonst für Bitfriemeleien notwendig sind,
(30% der Post hier gehen ja um solche Probleme beim Ansprechen eines
Ports)
So ist das halt im Leben:
-- schnell, und es wird hart
-- einfach, und es dauert eben.
Für die meisten Anwendungen reichen die 70 KHz doch aus.
Meine Fresse, da ist ja sogar Java (ohne JIT Compiler) besser. Ich habe
bisher noch nie mit der Arduino Software gearbeitet, aber spätestens
jetzt ist sicher, dass ich es auch niemals tun werde.
Falls da mal ein Job-Angebot kommt: Nein Danke.
PittyJ schrieb:> Ist zwar langsam, dafür ist es einfach.> Wenn ich vergleiche, was da sonst für Bitfriemeleien notwendig sind,
Wenn man weiß wie, geht es auch schnell und einfach:
Beitrag "Re: Makros versus Funktionen"
Timmo H. schrieb:> void digitalWrite(uint8_t pin, uint8_t val)
Warum werden dann in den Arduino-Beispielen immer 16 Bit (int)
übergeben?
Wozu diese Verschwendung auf nem 8-Bitter?
Timmo H. schrieb:> uint8_t timer = digitalPinToTimer(pin);> uint8_t bit = digitalPinToBitMask(pin);> uint8_t port = digitalPinToPort(pin);> ...> if (timer != NOT_ON_TIMER) turnOffPWM(timer);> out = portOutputRegister(port);
Schonmal 5 Unterfunktionsaufrufe, kein Wunder, daß da heftig Laufzeit
zustande kommt.
Da gibts aber noch mehr tücken beim Arduino Sketch:
kopiert von:
http://vpapanik.blogspot.gr/2012/08/arduino-thank-you-and-bye-bye.html
digitalWrite() takes 56 cycles to execute (well, I measured 400). At
least it is easy to find out why and switch to direct port access (the
second thing to change, after the IDE). Generally, Arduino is not very
friendly for time-efficient coding.
You cannot (at least, easily) disable the default hardware serial
library, in order to take over the TX and RX interrupts, no matter if it
has been started or not !
There's a overflow timer ISR firing every 16K clock cycles in the
background. This is for servicing millis() and micros() functions, even
when they're not used at all !
An empty Arduino project takes 466 bytes on an Arduino UNO and 666 bytes
on an Arduino Mega 2560. I dislike overheads a lot. I also dislike
seeing warnings during compiling of the above.
Mal wieder viel Beitraege zu denen man nur sagen kann: "Wenn man keine
Ahnung hat, einfach mal Fresse halten!". Immer wieder erschreckend, wie
viel Energie in's Bashing und wie wenig in's KnowHow gesteckt wird.
>> Meine Fresse, da ist ja sogar Java (ohne JIT Compiler) besser.>Dann lass mal Java auf ner 16MHz CPU laufen ...
Bei Lego Mindstorms klappt das ganz gut mit 32Mhz.