Hallo zusammen, wer kann mir sagen, wie ich die I/O-Reaktionszeit eines AVR bestimmen kann, bzw. wie ermittelt man die schnellste Reaktionszeit ein Eingangssignal zu erkennen und einen Ausgang zu schalten (in Abhängigkeit des Takts)? Wie lang muss das Eingangssignal mindestens sein? Bestenfalls einen Eingang direkt auf einen Ausgang routen!
Hallo, die nötigen Zeilen Code schreiben, die nötigen Taktzyklen aus dem Datenblatt suchen und zusammenrechen, den AVR-Takt berücksichtigen und fertich... ;-) Alle Pins von PortA zu PortB tragen:
1 | loop: |
2 | in PINA 1 Takt |
3 | out PORTB 1 Takt |
4 | rjmp loop 2 Takte |
Macht natürlich nur im realen Umfeld des Programms Sinn, das zu ergründen. Der AVR soll ja vermutlich noch mehr erledigen, sonst würde es ja ein Stück Draht auch tun. Gruß aus Berlin Michael
Moin zusammen, ich habe die Suchfunktion genutzt und dabei zu diesem Topic gekommen. Folgende Frage habe ich: Ich nutze Arduino Mega als eine logische Interlockzentrale. Wenn bestimmte Signale am Eingang der Arduino nicht anliegen sollten ( TTL HIGH oder TTL LOW Signale) soll Arduino dies schnell wie möglich erkenen und TTL HIGH oder LOW Signale als Ausgang geben. Wenn ich dann das Eingangsingnal als Triggersignal für eine Oszi-Messung nehme und den Pegelwechsel mit Ausgangssignal zusammen darstelle, sollte ich mit der Zeitdifferenz doch die reale Reaktions- und Bearbeitungszeit für Arduino rausbekomme, oder?( Ist diese Überlegung überhaupt richtig?) Dann kamen folgende Messungen zur Stände: http://www.abload.de/gallery.php?key=j8zlocjz Da sind vier mit Oszi aufgenommene Screenshots. Leider habe ich immer verschiedene Zeiten festegestellt? Die Reaktionszeit variiert sich von 120µs bis 240µs. Ist dies normall? Oder hat dies mit Taktfrequenz usw. zu tun? Detaillierte Rückmeldung wäre super. Schöne Grüße, s.
sloomy .. schrieb: > Da sind vier mit Oszi aufgenommene Screenshots. Dann zeig' die Screenshots doch mal hier im Forum unter Berücksichtigung der Bildformate und wo du schon dabei bist - häng auch gleich dein Programm mit dran.
sloomy .. schrieb: > Reaktionszeit variiert sich von 120µs bis 240µs. Ist dies normall? Oder Viel zu lang. Die Zeiten müssten weit unter 1 µs liegen. Anscheinend hast Du da noch jede Menge Programmschritte zwischen Erkennung und Reaktion.
Wolfgang schrieb: > häng auch gleich dein Programm mit dran. Ja das ist doch viel interessanter. Ich mein die Flanken auf dem Oszi sind stink langweilig.
116us, bei 16 MHz grob geschätzt 1800 takte, scheint schon ordentlich was zu erledigen davor. Dunkel kann ich mich erinnern dass Arduino hinter digitalWrite() oder digitalRead() "etwas" mehr verbirgt als man vermutet und daher nicht so flott ist wie man hofft. Poste mal den Code damit man weiss was da genau vor sich zu gehen hat.
danke für die Rückmeldungen. Die Screenshots habe ich gerade hochgeladen. Kann es an Arduino Mega liegen? Programmcode ist eigentlich sehr simple. Eine If-Schleife guckt ob die Werte an vorher definierten Eingängen liegt, wenn ja, schaltet er bestimmte Eingänge z.b. auf HIGH, wenn nicht, dann werden sie auf LOW geschaltet. Ich habe absichtlich Ein- und Ausgänge definieren und HIGH / LOW Schalten unter Arduino aber mit AVR Befehle gemacht. Vorher dauerte das Umschalten 6-7ms. ich werde den Code bald hochladen.
>ich werde den Code bald hochladen.
Wenn das ganz grob so aussieht:
if(PINA & (1<<PORTA2))
PORTA |= (1<<PORTA3);
Und über 100us braucht läuft da ganz viel falsch. Mal grob gefragt, du
hast nicht zufällig irgendwelche Interrupts die durch die Änderung an
dem Pin triggern und ewig brauchen?
Oder hast du zum Prüfen des Pins digitalRead() genommen?
Hmm interrapts wollte ich einbauen, aber die Funktion eines Interrupt habe ich nicht so richtig verstanden, glaube ich. :/
1 | //Simulation µC Reaktionstest
|
2 | |
3 | //Eingänge
|
4 | |
5 | int Eingang_1 = 24; // Eingang 1 |
6 | int Eingang_2 = 26; // Eingang 2 |
7 | int Eingang_3 = 28; // Eingang 3 |
8 | int Eingang_4 = 30; // Eingang 4 |
9 | |
10 | int Eingang_5 = 32; // Eingang 5 |
11 | int Eingang_6 = 34; // Eingang 6 |
12 | int Eingang_7 = 36; // Eingang 7 |
13 | |
14 | int Eingang_8 = 38; // Eingang 8 |
15 | |
16 | int Eingang_9 = 40; // Eingan 9 |
17 | |
18 | int Sensor_1 = 0; // Sensor 1 |
19 | int Sensor_2 = 1; // Sensor 2 |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | // Ausgänge
|
27 | //int wertsensor1, wertsensor2; // Wert der Sensor 1 und Sensor 2
|
28 | int limitsensor1, limitsensor2; // Grenzwerte Sensor 1 und Sensor 2 |
29 | int toltsensor1, toltsensor2; // Toleranzen |
30 | |
31 | |
32 | int Ausgang_1 = 33; // Ausgang 1 |
33 | int Ausgang_2 = 35; // Ausgang 2 |
34 | int Ausgang_3 = 37; // Ausgang 3 |
35 | |
36 | int Ausgang_4 = 39; // Ausgang 4 |
37 | |
38 | int Ausgang_5 = 43; // Ausgang 5 |
39 | |
40 | int ledrot = 50; // rote LED |
41 | int ledgruen = 51; // grüne LED |
42 | int ledgelb = 10; // gelbe LED |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | void setup() |
49 | |
50 | {
|
51 | //Serial.begin( 115200 );
|
52 | |
53 | |
54 | |
55 | DDRA |= (0<<2); // Pin 24 pinMode ( Eingang_1, INPUT ); |
56 | DDRA |= (0<<4); // Pin 26 pinMode ( Eingang_2, INPUT ); |
57 | DDRA |= (0<<6); // Pin 28 pinMode ( Eingang_3, INPUT ); |
58 | DDRC |= (0<<7); // Pin 30 pinMode ( Eingang_4, INPUT ); |
59 | |
60 | DDRD |= (0<<7); //pinMode ( Eingang_8, INPUT ); |
61 | |
62 | DDRL |= (0<<5); //pinMode ( Eingang_9, INPUT ); |
63 | |
64 | DDRB |= (1<<3); //pinMode ( ledrot, OUTPUT ); |
65 | DDRB |= (1<<2); //pinMode ( ledgruen, OUTPUT ); |
66 | DDRK |= (1<<2); //pinMode ( ledgelb, OUTPUT) ; |
67 | |
68 | DDRC |= (1<<4); //pinMode ( Ausgang_1, OUTPUT ); |
69 | DDRC |= (1<<2); //pinMode ( Ausgang_2, OUTPUT ); |
70 | DDRC |= (1<<0); //pinMode ( Modulator_Aus, OUTPUT ); |
71 | DDRG |= (1<<2); //pinMode ( Ausgang_4, OUTPUT ); |
72 | |
73 | DDRL |= (1<<6); //pinMode ( Ausgang_5, OUTPUT ); |
74 | |
75 | |
76 | |
77 | |
78 | }
|
79 | |
80 | void loop () |
81 | |
82 | {
|
83 | |
84 | limitpd1 = 550; |
85 | tolpd1 = 25; |
86 | limitpd2 = 550; |
87 | tolpd2 = 25; |
88 | |
89 | int wertpd1 = analogRead ( Sensor_1 ); |
90 | int wertpd2 = analogRead ( Sensor_2 ); |
91 | |
92 | int wert_Eingang_8 = digitalRead ( Eingang_8 ); |
93 | int wert_Eingang_9 = digitalRead ( Eingang_9 ); |
94 | |
95 | int wert_Eingang_1 = digitalRead ( Eingang_1 ); |
96 | int wert_Eingang_2 = digitalRead ( Eingang_2 ); |
97 | int wert_Eingang_3 = digitalRead ( Eingang_3 ); |
98 | int wert_Eingang_4 = digitalRead ( Eingang_4 ); |
99 | |
100 | /*
|
101 | Serial.print ( "der Wert von Sensor 1 ist " );
|
102 | Serial.println ( wertpd1 );
|
103 | Serial.println ();
|
104 | Serial.print ( "der Wert von Sensor 2 ist " );
|
105 | Serial.println ( wertpd2 );
|
106 | Serial.println ();
|
107 |
|
108 | Serial.print ( "der Wert von Eingang_8 ist " );
|
109 | Serial.println ( wert_Eingang_8 );
|
110 | Serial.println ();
|
111 |
|
112 | Serial.print ( "der Wert von Eingang_9 ist " );
|
113 | Serial.println ( wert_Eingang_9 );
|
114 | Serial.println ();
|
115 |
|
116 | Serial.print ( "der Wert von Eingang 1 ist " );
|
117 | Serial.println ( wert_Eingang_1 );
|
118 | Serial.println ();
|
119 |
|
120 | Serial.print ( "der Wert von Eingang 2 ist " );
|
121 | Serial.println ( wert_Eingang_2 );
|
122 | Serial.println ();
|
123 |
|
124 | Serial.print ( "der Wert von Eingang 3 ist " );
|
125 | Serial.println ( wert_Eingang_3 );
|
126 | Serial.println ();
|
127 |
|
128 | Serial.print ( "der Wert von Eingang 4 ist " );
|
129 | Serial.println ( wert_Eingang_4 );
|
130 | Serial.println ();
|
131 | */
|
132 | |
133 | |
134 | if
|
135 | (
|
136 | ( wertpd1 <= limitpd1+tolpd1 ) |
137 | &&( wertpd1 >= limitpd1-tolpd1 ) |
138 | &&( wertpd2 <= limitpd2+tolpd2 ) |
139 | &&( wertpd2 >= limitpd2-tolpd2 ) |
140 | &&( wert_Eingang_8 == 0 ) |
141 | &&( wert_Eingang_9 == 1) |
142 | &&( wert_Eingang_1 == 1) |
143 | &&( wert_Eingang_2 == 1) |
144 | &&( wert_Eingang_3 == 0) |
145 | &&( wert_Eingang_4 == 0) |
146 | |
147 | )
|
148 | |
149 | {
|
150 | |
151 | betriebmodus (); |
152 | |
153 | }
|
154 | |
155 | |
156 | else
|
157 | |
158 | fehlermodus (); |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | }
|
166 | |
167 | void betriebmodus () |
168 | {
|
169 | |
170 | |
171 | //Serial.print("Betriebmodus! ");
|
172 | //Serial.println();
|
173 | PORTB |= (1<<2); //digitalWrite ( ledgruen, HIGH ); |
174 | PORTB &= ~(1<<3); //digitalWrite ( ledrot, LOW ); |
175 | //digitalWrite (ledgelb, LOW );
|
176 | PORTC |= (1<<4); //digitalWrite ( Ausgang_1, HIGH ); |
177 | PORTC |= (1<<2); //digitalWrite ( Ausgang_2, HIGH ); |
178 | PORTG |= (1<<2); //digitalWrite ( Ausgang_4, HIGH ); |
179 | PORTL |= (1<<6); //digitalWrite ( Ausgang_5, HIGH ); |
180 | //delay(2000);
|
181 | |
182 | }
|
183 | |
184 | |
185 | void fehlermodus () |
186 | |
187 | {
|
188 | |
189 | |
190 | //Serial.print ( "Fehlermodus!" );
|
191 | //Serial.println();
|
192 | PORTB |= (1<<3); //digitalWrite ( ledrot, HIGH ); |
193 | PORTB &= ~(1<<2); //digitalWrite ( ledgruen, LOW ); |
194 | //digitalWrite ( ledgelb, LOW );
|
195 | PORTC &= ~(1<<4); //digitalWrite ( Ausgang_1, LOW ); |
196 | PORTC &= ~(1<<2); //digitalWrite ( Ausgang_2, LOW ); |
197 | PORTG &= ~(1<<2); //digitalWrite ( Ausgang_4, LOW ); |
198 | PORTL &= ~(1<<6); //digitalWrite ( Ausgang_5, LOW ); |
199 | //delay(2000);
|
200 | |
201 | }
|
Kann es sein, da ich void loop() und selber funktionen wie void Fehlerfunktion oder BEtriebfunktion definiert habe? Wie kann diese in AVR Codes schreiben? Wenn ich void loop() nicht schreiben würde, dann meckert arduino beim compalieren, dass void loop fehlt. -- Oberhalb des Texteingabefeldes dieses Forums steht, wie C-Code zu formatieren ist -- [QUOTE] kennt dieses Forum nicht. Habe das mal korrigiert. -rufus
1) Um ein einziges Bit zu speichern brauchts keine ints. int x = digitalRead() ist unnötiger Speicherverbrauch. Unsigned char tuts auch. 2) Im schlimmsten Falle braucht der MC 2 analog und 6 digitalRead() bis er überhaupt mal zum Check der Variablen kommt, da verstreicht schon einiges an Zeit. Ein analogRead braucht laut arduino doc 100usec. digitalRead braucht wohl so 4,5 usec. Alles gesamt kommt man im worst case so auf ~230msec nur durchs pin lesen. 3) Wie schnell die 10 compares dann sind kann man mal mit Portwackeln testen, aber mehr als eine gerade zweistellige Anzahl an usec würden mich schon wundern. >Kann es sein, da ich void loop() und selber funktionen wie void >Fehlerfunktion oder BEtriebfunktion definiert habe? Also nur weil du selber ein paar Funktionen definierst wird der nicht langsamer ;). Und void loop() braucht arduino, sonst hat das Geraffel ist dessen "main loop" die es kontinuierlich wieder abarbeitet. In normalem C hat man statt void loop() halt void main() und darinn dann mal eine while(1) als Endlosschleife. Das was du im setup() Teil hast läuft dann in main vor der while() ab.
sloomy .. schrieb: > Wenn ich void loop() nicht schreiben würde, dann meckert arduino beim > compalieren, dass void loop fehlt. Geh von diesem Arduino Zeugs weg! Das frisst dir doch jede Menge Takte. Das Ardino Zeugs ist großartig, damit Künstler ihre Lichter und Motoren in der richtigen Reihenfolge ein/aus schalten können. Aber wenn es darum geht, dass du eine sehr schnelle Reaktion brauchst, dann kannst du dir diesen ganzen Overhead nicht leisten. Da musst du schon direkt an 'der Maschine' programmieren. Was genau wundert dich da jetzt? Deine loop() Funktion wird alle heiligen Zeiten mal aufgerufen, weil die Arduino Basis-Lib seine komplette Buchhaltung da dazwischen machen muss. Du selbst rufst in der loop() eine Menge Funktionen auf, die haufenweise viele zu viel machen und dann knallst du den Code auch noch in eine Monsterabfrage rein. Klar ist das vergleichsweise langsam! Was erwartest du eigentllich? Und PS: eine 'if-Schleife' gibt es nicht. Das Wesen einer Schleife besteht darin, dass etwas wiederholt wird. Darum heißt es Schleife. Bei einem if wird aber nichts wiederholt. Ein if trifft eine Unterscheidung zwischen 2 Alternativen. Das hat genau gar nichts mit einer Schleife zu tun.
Oh ja, danke für die wertvollen Tipps!!! Karl Heinz Buchegger schrieb: > Geh von diesem Arduino Zeugs weg! > Das frisst dir doch jede Menge Takte. Das werde ich abe jetzt versuchen! Also ich soll alles mit AVR Codes ersetzen. Wie soll ich dann am schlausten rangehen? ich bin an jeden Hinweis, Tipp, Vorschlag usw. dankbar. Warum messe ich da aber verschiedene Reaktionszeiten und nicht immer eine gleiche / konstante?
sloomy .. schrieb: > Warum messe ich da aber verschiedene Reaktionszeiten und nicht immer > eine gleiche / konstante? Weil du durch das Arduino Framework deinen µC nicht komplett unter Kontrolle hast. Oder denkst du, die Pulse kommn nur rein, während dein Programm sich in der loop() abspielt? Nein. Die Eingangssignale können zu jeder Zeit auftreten, auch dann wenn dein Programm gerade wieder mal aus dem loop() draussen ist, das Arduino Framework sein 'Hausaufgaben' macht, ehe es dann wieder mal deine loop() Funktion aufruft. AVR-GCC-Tutorial AVR-Tutorial
sloomy .. schrieb: > Warum messe ich da aber verschiedene Reaktionszeiten und nicht immer > eine gleiche / konstante? Weil dein Programm mal auf dem linken und mal auf dem rechten Fuß von der Eingangssignaländerung erwischt wird.
Danke danke danke! Dann wird heute eine lange nacht sein :) Ich ziehe mir mal die Tutorials rein. Vielen Dank noch einmal für die Antworten!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.