Forum: Mikrocontroller und Digitale Elektronik AVR Reaktionszeit I/O


von jason123 (Gast)


Lesenswert?

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!

von Michael U. (amiga)


Lesenswert?

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

von Sloomy .. (sloomy)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von Albert M. (Firma: Bastler aus Mönchengladbach) (albertm) Benutzerseite


Lesenswert?

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.

von HA (Gast)


Lesenswert?

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.

von SamplePoint (Gast)


Lesenswert?

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.

von Sloomy .. (sloomy)


Angehängte Dateien:

Lesenswert?

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.

von SamplePoint (Gast)


Lesenswert?

>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?

von Sloomy .. (sloomy)


Lesenswert?

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

von SamplePoint (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Sloomy .. (sloomy)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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

von Werner (Gast)


Lesenswert?

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.

von Sloomy .. (sloomy)


Lesenswert?

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
Noch kein Account? Hier anmelden.