Brauche Hilfe bei Bitweise rechnen

Moin,

fange gerade an mit dem Arduino rumzuspielen (und bin begeistert).

Für ein Projekt möchte ich nun sehr schnell zwei digitale Eingänge einlesen und nur prüfen, ob die beiden Signale gleich sind (beide HIGH oder beide LOW, sonst Signal) (Einlesen und Auswerten sollte weniger als 0.1 Millisekunden in Anspruch nehmen).

Habe gesucht und gefunden, dass der Befehl PINB das Einlesen um den Faktor 20 (?) schneller macht.
Mein Problem: Wie kann ich jetzt einfach (und schnell) prüfen, ob die zwei Ports (=Bits) gleich sind? Dies ist doch bestimmt über einen bitweisen Vergleich machbar oder? (meine Güte ist der Physik Leistungskurs lange her ...... )

Danke für Hilfe.

Gruß aus Frankreich

Jens

Hi

Wenn du sonst keine Funktionen brauchst, könntest du auch einfach nen NAND oder AND gatter nehmen, die sind bedeutend schneller als nen Ardu :wink:
Ansonsten könntest du einfach mit digitalRead die beiden werte in ne Variable legen, und mit "if(wert 1 == wert2) { } else { } vergleichen^^

Über PINB hab ich kein plan, weiß auch nicht ob´s stimmt oder nicht.

MFG, Robdeflop®

Hi,

danke für den Tip, aber leider geht es nicht mit nem Gatter, da ich eine (einstellbare) Toleranz haben muss, d.h. eine gewisse Zeit (einige mikrosekunden, muss einstellbar und variabel sein) darf ein Unterschied vorhanden sein, bevor entweder wieder gleiches Signal vorliegt, oder ein Signal gegeben wird.

Trotzdem danke.

Hi

Nja ich weiß nicht ob das Ardu das so schnell verarbeiten kann. Diese frage muss dir wer anders beantworten^^

MFG, Robdeflop®

Ich hatte für mein MotionFreezer 2 Projekt (http://www.mafu-foto.de/projektebasteln/projektebastelnmotionfreezer2) mal ein paar Vergleichsmessungen bez. Geschwindigkeit der analogen und digitalen Ports durchgeführt.
Ich hab dazu zigtausend mal am Port gelesen und die benötigte Zeit gemessen. Damit das ganze praxisnah abläuft, habe ich in der Schleife noch ein paar Berechnungsfunktionen durchgeführt.
Für das Auslesen der digitalen Ports kam ich auf 240 Aufrufe pro Millisekunde oder andersherum 0,004 Millisekunden zum Auslesen.
Und dabei bin ich noch gar nicht über PINB gegangen sondern hab einfach das gute alte digitalRead() verwendet.

So, und jetzt frag nochmal ob der Arduino schnell genug dafür ist. :wink:

Hallo MaFu,

danke für die Info. Komme leider erst am Wochenende dazu, meine Versuche zu machen, aber werde auch mal ein paar Versuche fahren, in denen ich die Schleife ein paar tausendmal durchlaufen lasse und die Zeit messe.

Werde berichten, wenn Werte vorliegen (vor allem der Vergleich zwischen digitalRead und PINB).

Bis denn.

Jens

PS: Deine Projekte sind Klasse.

Moin,

so, ich habe jetzt mal nen schnellen Vergleich gemacht, und wenn auch der Unterschied beeindruckend ist, die wirkliche Überraschung ist die absolute Geschwindigket.

Folgende Konfiguration:

Arduino UNO.

Test Programm 1:

#define SENSOR1 2
#define SENSOR2 3

long starttime;

void setup(){
 Serial.begin(9600);
}

void loop(){
  starttime = millis();
  for (int i=0 ; i < 10000 ; i++){
    if (digitalRead(SENSOR1) != digitalRead(SENSOR2)) {
//      Hier kommt später ne Verzögerung rein, um zu prüfen, ob die Ports auch nach x Microsekunden noch unterschiedlich sind
      if (digitalRead(SENSOR1) != digitalRead(SENSOR2)) {
//        Aktion wenn auch nach x Microsekunden unterschiedliche Signale vorliegen
      }
    }
  }
  Serial.println(millis() - starttime);
}

Test Programm 2:

long starttime;

void setup(){
 Serial.begin(9600);
}

void loop(){
  starttime = millis();
  for (int i=0 ; i < 10000 ; i++){
    port = PIND;
    if (bitRead(port,2) != bitRead(port,3)) {
//      Hier kommt später ne Verzögerung rein, um zu prüfen, ob die Ports auch nach x Microsekunden noch unterschiedlich sind
      port = PIND;
      if (bitRead(port,2) != bitRead(port,3)) {
//        Aktion wenn auch nach x Microsekunden unterschiedliche Signale vorliegen
      }
    }
  }
  Serial.println(millis() - starttime);
}

Ergebnis:

Die 10000 Durchläufe schafft das erste Programm (digitalRead) in 171 Millisekunden (= 17 Mikrosekunden / Durchlauf), während das zweite Programm (PIND) die 10000 Durchläufe in nur 24 Millisekunden (2.4 Mikrosekunden / Durchlauf) schafft.

BEEINDRUCKEND!

P.S. Die 17 Mikrosekunden im ersten Programm entsprechen übrigens den 0.004 Millisekunden, die MaFu vorher genannt hat: In meinen Versuch sind 4 DigitalRead für eine Schleife nötig, d.h. der einzelne DigitalRead benötigt tatsächlich 4 Mikrosekunden.
Da im zweiten Beispiel nur zwei Auslese Befehle nötig sind, heisst dies, dass die PIND Konstellation ca um den Faktor 4 schneller ist als DigitalRead (und nicht Faktor 20 wie ich irgendwo gelesen habe).

Auf jeden Fall steht fest: Bei diesen Geschwindigkeiten brauch ich mir diesbezüglich keine Sorgen machen, und Hardwarelösungen sind auch nicht nötig.

Alles in allem: Arduino rocks! Cheers.

Wenn du es wirklich schnell haben willst, kannst du das ganze auch über den inline-Assembler machen. Dazu mußt du dich allerdings etwas mit der Machinensprache beschäftigen.
Ich habs schonmal probiert und es funktioniert. Lästig ist nur, daß man da jeden einzelnen Befehl in "" setzen muß.

Gibt es ein Beispiel oder gute Online-Ressourcen zum Einlesen für die wirklich flotte Variante?

Der Aufwand mit Inline-Assembler lohnt hier nicht! Wenn port als char oder uint8_t definiert ist, wird der Compiler bei diesem Programm einen Maschienen-Code erzeugen der "von Hand" nur schwer, wenn überhaupt, zu toppen ist!

Info für die Zweifler: bitRead ist ein Makro, demnach kein Funktionsprung, Stack-Nutzung, Cast oder volatile Variablen!

Gruß,
Lupus

Lupus:
Der Aufwand mit Inline-Assembler lohnt hier nicht! Wenn port als char oder uint8_t definiert ist, wird der Compiler bei diesem Programm einen Maschienen-Code erzeugen der "von Hand" nur schwer, wenn überhaupt, zu toppen ist!

Absolut richtig! Kann ich als jemand bestätigen, der seine Arduino-Programme im allgemeinen nicht über die Arduino-IDE kompiliert sondern über das Atmel AVR Studio, und sich daher einfach den vom AVR GCC erzeugten Assembler-Code ansehen kann (und auch manchmal tut). :wink:

Es lohnt sich in 99,9% der Fälle nicht, das letzte Quäntchen an Geschwindigkeit durch Programmierung in Assembler rauszuholen. Speziell, bei den Dingen, die wir hier mit dem Arduino machen.
Da sollte man eher überlegen, ob ein ATMega die richtige Hardware ist, wenn man höhere Geschwindigkeit benötigt.

Gruß
Wolfgang