Arduino Uno-Pin-Antwortgeschwindigkeit

Wir versuchen, eine Coilgun mit mehreren Spulen zu bauen, und jede Spule muss in genauen Zeitintervallen erregt und entregt werden. Aus Kosten- (und Unerfahrenheits-)Gründen erwägen wir, für diese Aufgabe einen Arduino Uno zu verwenden. Unsere Fragen lauten wie folgt:

Wie schnell kann das Uno einen Pin zwischen Zuständen umschalten? Wie konsistent ist das Timing? Gibt es angesichts unserer Unerfahrenheit und fehlenden Mittel eine bessere Option?

1 bis 3. Noch entscheiden.
Das Umschalten kann so schnell wie ein einzelner Befehl sein und, wenn alle Interrupts deaktiviert sind, so konsistent sein wie der Kristall, der zum Takten des Mikrocontrollers verwendet wird.

Antworten (4)

Wenn Sie in regelmäßigen Abständen wiederholte Impulse benötigen, dh ein pulsweitenmoduliertes (PWM) Signal, ist die Verwendung der Hardware-Timer auf dem ATmega328 möglicherweise der richtige Weg. Dies gibt Ihnen ein sehr präzises und konsistentes Timing und ermöglicht es Ihnen, einen Stift so schnell wie möglich umzuschalten F C P U / 2 (8 MHz auf einem Arduino Uno), aber es beschränkt Ihre Wellenform ziemlich auf "hoch für X Zyklen aus Y".

Dieser Arduino-Artikel gibt einen Überblick über das Thema.

Werfen wir einen Blick darauf, was uns die CPU erlaubt. Das Folgende ist ein handelsüblicher C-Code zum schnellstmöglichen Umschalten eines Pins:

while (1) PORTA ^= 0x01;

Wenn der Compiler schlau genug wäre, würde er zu Folgendem kompilieren:

  ldi r25, 0x01    ; Load immediate

start:
  eor r24, r25     ; r24 = r24 XOR r25
  out 0x02, r24    ; Out (store) to IO location
  rjmp .-6         ; Goto start

Ich würde sagen, das ist so ziemlich die schnellste Schleife auf einem AVR, die man bekommen kann. Nehmen wir nun die Ausführungszeit jeder Anweisung:

  • AUS - 1 Zyklus
  • EOR - 1 Zyklus
  • RJMP - 2 Zyklen

Dies ergibt insgesamt 4 Zyklen. Beachten Sie, dass dies ein einzelner Pin-Schalter ist. Um die Schaltfrequenz zu erhalten, multiplizieren Sie mit 2. Unter Berücksichtigung Ihrer CPU-Geschwindigkeit von 16 MHz können Sie daher sagen, dass Sie bei einem Mega-AVR am schnellsten einen Pin umschalten können F M A X = F C P U / 8


Dies macht die Rate natürlich ziemlich unkontrollierbar, da der kleinste Schritt, um den Sie die Periode verringern können, ein einzelner CPU-Zyklus ist, zum Beispiel durch Hinzufügen einer NOP-Anweisung in die Mischung.

Für das Umschalten eines Pins gibt es wesentlich elegantere Lösungen. Ich würde vorschlagen, über den 555-Timer zu lesen. Da bekommt man bestimmt etwas Wind.

Timer würden für sehr schnelles Umschalten verwendet, nicht für Codeschleifen.
Tatsächlich gibt es in den meisten AVRs einen schnelleren Weg, Pins durch Code umzuschalten: Das Schreiben von an auf 1ein Bit im PINx-Register wird den Pin-Wert umschalten, sodass Sie auf das XOR verzichten können.

Dies begann als Kommentar, aber es gab keine schöne Möglichkeit, ihn zu formatieren ...

Ich habe (wenn auch auf einer anderen MCU - Coldfire für diejenigen, die daran interessiert sind) diese Verwendung gefunden

PORTn ^= 1;

Ist tatsächlich viel langsamer als das direkte Schreiben in die PORTnSEToder PORTnCLRRegister, da es sich um eine Lese- / Logikoperations- / Schreibsequenz handelt.

Zur Erklärung, das Mikro hat mehrere Register für jeden Port (ich weiß nicht, wie häufig dies bei allen Mikros vorkommt), aber das beliebte Allzweck-PORTn-Register (das zum Einstellen, Löschen oder Lesen des Pin-Status verwendet werden kann) sitzt "über" dem Trio der unteren Ebene von PORTnSET, CLR oder STATE, die der Reihe nach entweder den Pin SETZEN (1 = setzen, 0 = keine Änderung), CLEAR (1 = löschen, 0 = keine Änderung) oder LESEN können roher Pin-Zustand (das Lesen der anderen ist keine Garantie, da der Registerzustand möglicherweise nicht angewendet wird, wenn der Pin als Eingang konfiguriert ist usw.).

Wir fanden heraus, dass dies PORTn ^= 1zu vielen Assemblerzeilen des Compilers führte, was tatsächlich dazu führte, dass unsere Pulse viel zu lang waren.

Wenn Sie auf einen einzelnen schnellen Impuls abzielen, wäre es schneller:

PORTnCLR = 1; // Clears pin
<wait for button push or whatever>
PORTnSET = 1; // Sets pin
PORTnCLR = 1; // Clears pin

Ich weiß nicht, wie schnell Sie gehen müssen, aber es scheint mir, dass es eine einfache analoge Möglichkeit geben sollte, mit ein paar einen SEHR scharfen Triggerimpuls zu liefern (wenn die Breite des Impulses so schmal wie möglich sein muss). grundlegende Bits.

Es gibt auch bessere Optionen im Mikrobereich, wenn Sie die Sequenzierungsfunktion benötigen. STM32-Entwicklungsboards sind mit bis zu ~ 192 MHz für weniger als ein Ardunio erhältlich, und dann können Sie auch echte Programmierung lernen.

Ein guter Anfang wären die Appnote-Archive von Linear Tech, da dort einige brillante Sachen von Leuten wie Bob Pease & Jim Williams enthalten sind:

http://www.linear.com/doclist/

Das Arduino Uno verwendet einen 16-MHz-Quarz, was bedeutet, dass es 16 Millionen Anweisungen in einer Sekunde ausführen kann.

Es hängt davon ab, wie lange Ihr Skript ist, wie schnell das Arduino Ihren Stift hoch und niedrig umschalten wird.


Macht nichts, diese Antwort scheint falsch zu sein. Mein Fehler

Hinweis: 16 Millionen Anweisungen sind nur theoretisch, sie werden tatsächlich etwas niedriger sein
16 Millionen Befehlszyklen pro Sekunde: Einige Befehle benötigen mehr als einen Zyklus. Auch wenn Interrupts freigegeben sind, würden sich die produktiven Zyklen für den Vordergrundcode verringern.
Ich habe nicht Unterrichtszyklen gesagt. Nur Anweisungen. Das Einschalten einer LED ist bereits 1 Anweisung. Das Ausschalten ist eine zweite Anweisung. Die Schleife selbst ist eine Anweisung.
Genau, und das war Ihr Fehler: Ein Befehl kann mehr als einen Zyklus dauern, und dennoch liefert der Mikrocontroller mit einem 16-MHz-Quarz nur 16 Millionen Befehlszyklen pro Sekunde, nicht 16 Millionen Befehle, es sei denn, Sie gehen davon aus, dass es sich nur um Einzelzyklusbefehle handelt verwendet werden sollen - was sich, wenn man die Befehlszeiten des AtMega auch nur oberflächlich betrachtet, als unwahrscheinlich erweisen wird.
Ah ok danke für die Erklärung. Ich studiere immer noch Elektronik und hatte schlechten Unterricht an meinem College. Also musste ich die meisten Dinge selbst herausfinden. Feedback wie dieses zu bekommen wird mir helfen, die Dinge besser zu verstehen ;)