www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Reaktionszeit I/O


Autor: jason123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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:
loop: 
  in PINA     1 Takt
  out PORTB   1 Takt
  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

Autor: Sloomy .. (sloomy)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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.

Autor: HA (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: SamplePoint (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sloomy .. (sloomy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: SamplePoint (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sloomy .. (sloomy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm interrapts wollte ich einbauen, aber die Funktion eines Interrupt 
habe ich nicht so richtig verstanden, glaube ich. :/
//Simulation µC Reaktionstest

//Eingänge

int Eingang_1 = 24;         // Eingang  1
int Eingang_2 = 26;         // Eingang  2
int Eingang_3 = 28;         // Eingang  3
int Eingang_4 = 30;         // Eingang  4

int Eingang_5 = 32;         // Eingang 5
int Eingang_6 = 34;         // Eingang 6
int Eingang_7 = 36;         // Eingang 7

int Eingang_8 = 38;         // Eingang 8

int Eingang_9 = 40;         // Eingan 9

int Sensor_1 = 0;           // Sensor 1
int Sensor_2 = 1;           // Sensor 2






// Ausgänge
//int wertsensor1, wertsensor2;          // Wert der Sensor 1 und Sensor 2
int limitsensor1, limitsensor2;          // Grenzwerte Sensor 1 und Sensor 2
int toltsensor1, toltsensor2;            // Toleranzen  


int Ausgang_1 =   33;      // Ausgang 1
int Ausgang_2 = 35;        // Ausgang 2
int Ausgang_3 = 37;        // Ausgang 3

int Ausgang_4 = 39;        // Ausgang 4

int Ausgang_5 = 43;        // Ausgang 5

int ledrot = 50;                 // rote LED
int ledgruen = 51;               // grüne LED
int ledgelb = 10;                // gelbe LED





void setup()

{
  //Serial.begin( 115200 );
  

  
  DDRA |= (0<<2);  // Pin 24  pinMode ( Eingang_1, INPUT );
  DDRA |= (0<<4);  // Pin 26  pinMode ( Eingang_2, INPUT );
  DDRA |= (0<<6);  // Pin 28  pinMode ( Eingang_3, INPUT );
  DDRC |= (0<<7);  // Pin 30  pinMode ( Eingang_4, INPUT );
  
  DDRD |= (0<<7);  //pinMode ( Eingang_8, INPUT );
  
  DDRL |= (0<<5);  //pinMode ( Eingang_9, INPUT );
  
  DDRB |= (1<<3);  //pinMode ( ledrot, OUTPUT );
  DDRB |= (1<<2);  //pinMode ( ledgruen, OUTPUT );
  DDRK |= (1<<2);  //pinMode ( ledgelb, OUTPUT) ;
  
  DDRC |= (1<<4);  //pinMode ( Ausgang_1, OUTPUT );
  DDRC |= (1<<2);  //pinMode ( Ausgang_2, OUTPUT );
  DDRC |= (1<<0);  //pinMode ( Modulator_Aus, OUTPUT );          
  DDRG |= (1<<2);  //pinMode ( Ausgang_4, OUTPUT );
  
  DDRL |= (1<<6);  //pinMode ( Ausgang_5, OUTPUT );
  
  
  
  
}

void loop ()

{ 
  
  limitpd1 = 550;
  tolpd1 = 25;
  limitpd2 = 550;
  tolpd2 = 25; 
  
  int wertpd1 = analogRead ( Sensor_1 );
  int wertpd2 = analogRead ( Sensor_2 );
  
  int wert_Eingang_8 = digitalRead ( Eingang_8 );
  int wert_Eingang_9 = digitalRead ( Eingang_9 );
  
  int wert_Eingang_1 = digitalRead ( Eingang_1 );
  int wert_Eingang_2 = digitalRead ( Eingang_2 );
  int wert_Eingang_3 = digitalRead ( Eingang_3 );
  int wert_Eingang_4 = digitalRead ( Eingang_4 );
  
  /*
  Serial.print ( "der Wert von Sensor 1 ist " );
  Serial.println ( wertpd1 );
  Serial.println ();
  Serial.print ( "der Wert von Sensor 2 ist " );
  Serial.println ( wertpd2 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang_8 ist " );
  Serial.println ( wert_Eingang_8 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang_9 ist " );
  Serial.println ( wert_Eingang_9 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang 1 ist " );
  Serial.println ( wert_Eingang_1 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang 2 ist " );
  Serial.println ( wert_Eingang_2 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang 3 ist " );
  Serial.println ( wert_Eingang_3 );
  Serial.println ();
  
  Serial.print ( "der Wert von Eingang 4 ist " );
  Serial.println ( wert_Eingang_4 );
  Serial.println ();
  */
  

    if 
    ( 
      ( wertpd1 <= limitpd1+tolpd1 )
    &&( wertpd1 >= limitpd1-tolpd1 )
    &&( wertpd2 <= limitpd2+tolpd2 )
    &&( wertpd2 >= limitpd2-tolpd2 )
    &&( wert_Eingang_8 == 0 )
    &&( wert_Eingang_9 == 1)
    &&( wert_Eingang_1 == 1)
    &&( wert_Eingang_2 == 1)
    &&( wert_Eingang_3 == 0)
    &&( wert_Eingang_4 == 0)
    
    )
  
    {

    betriebmodus ();   
      
    }
    
    
    else 
    
    fehlermodus ();
    
    

     
 
   
}

void betriebmodus ()
{
  
  
  //Serial.print("Betriebmodus! ");
  //Serial.println();
  PORTB |= (1<<2);  //digitalWrite ( ledgruen, HIGH );
  PORTB &= ~(1<<3);  //digitalWrite ( ledrot, LOW );
  //digitalWrite (ledgelb, LOW );
  PORTC |= (1<<4);  //digitalWrite ( Ausgang_1, HIGH );
  PORTC |= (1<<2);  //digitalWrite ( Ausgang_2, HIGH );
  PORTG |= (1<<2);  //digitalWrite ( Ausgang_4, HIGH );
  PORTL |= (1<<6);  //digitalWrite ( Ausgang_5, HIGH );
  //delay(2000);
  
}


void fehlermodus ()

    {
      
     
     //Serial.print ( "Fehlermodus!" );
     //Serial.println();
     PORTB |= (1<<3);  //digitalWrite ( ledrot, HIGH );
     PORTB &= ~(1<<2);  //digitalWrite ( ledgruen, LOW );
     //digitalWrite ( ledgelb, LOW );
     PORTC &= ~(1<<4);  //digitalWrite ( Ausgang_1, LOW );
     PORTC &= ~(1<<2);  //digitalWrite ( Ausgang_2, LOW );
     PORTG &= ~(1<<2);  //digitalWrite ( Ausgang_4, LOW );
     PORTL &= ~(1<<6);  //digitalWrite ( Ausgang_5, LOW );
     //delay(2000);
     
    }

  



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

Autor: SamplePoint (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sloomy .. (sloomy)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sloomy .. (sloomy)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.