Tausende von 5V-Flankenwechseln mit Arduino konsumieren, wie geht das?

Hallo und danke für's Lesen!

Ich habe eine Kamera, die mit 1000 fps und mehr filmen kann und die mir ein Taktsignal ausgibt. Sie liefert für jeden Frame 5Volt und fällt dann ab.

Mein Arduino Mega 2560 soll dieses Signal verarbeiten, so dass ich bei jedem einzelnen Frame beispielsweise eine andere LED einschalten kann. Ich würde gerne bis zu 6000 fps kommen, oder so.

Ich hatte das mit analogRead() versucht, aber das scheint zu langsam? Und mit digitalRead() kann man diese Art Signal gar nicht verarbeiten, richtig?

Mein nächster Schritt wäre nun, das Signal der Kamera dazu zu nutzen, um einen Optokoppler zu feeden, so dass das Signal dann in ein on/off verwandelt wird, das ich digital verarbeiten kann. Ist das eine gute Idee?

Wenn nicht, wie würde ich das angehen? Ich bin absolut kein Elektroniker, das mit dem Optokoppler bekäme ich wahrscheinlich noch hin, aber viel weiter komme ich nicht.

Fällt jemandem eine einfache Lösung ein? Wäre sehr dankbar!

Gruß! Martin

Was verstehst Du unter "fällt dann ab"? Wenn das nicht zu flach erfolgt, was ich mir bei 1000 fps nicht vorstellen kann, kannst Du das auch digital einlesen.
Wenn die Cam 1000 fps bringt, wie willst Du dann auf 6000 fps kommen?

Gruß Tommy

Hallo Tommy! Vielen Dank!

Die Kamera macht bei höchster Auflösung 1000 fps, kann aber bis zu 24.000, dann bekommt man aber nur noch Thumbnails.

Das Signal der Kamera ist extra dazu gedacht, anderes Equipment dazu zu synchronisieren.

Ich habe keine Ahnung, wie ich das Signal technisch beschreiben kann, hier ist das Manual zur Kamera. Seite 47 ist wohl die relevante Spezifikation.

Vielen Dank!

Dann würde ich vorschlagen, dass Du mal den digitalen Input probierst.
Einfach mal eine Sekunde lang zählen und schauen, wie weit Du kommst.

Gruß Tommy

Ok danke!

Ich habe die Kamera so konfiguriert, dass sie genau 200 Frames filmt, dann automatisch wieder aufhört. Ich schaffe es nicht, alle 200 Frames zu bekommen, ich lande bei 70 oder so, es variiert allerdings. Ist das hier die richtige Grundstruktur?


int analogPin = A3;
int val = 0; 
int valPrev = 0; 
int iCounter = 0;

void setup() {
}

void loop() {

	while(true)
	{
		valPrev = val;
		val = digitalRead(analogPin);
		if(val != valPrev)
		{
			if(val == 0)
			{
				iCounter++;
			}
		}
	}
}

Du könntest mit pulsein arbeiten.

Du brauchst zwar nicht die zurück gegebene Länge, könntest es aber als true missbrauchen und einen Counter hochzählen lassen.

Ansonsten über Interrupt eine Variable zählen

Nein, das wird nichts, das dürfte zu langsam sein.
Die beiden Geräte brauchen einen gemeinsamen GND.
Und Du solltest eine Schutzbeschaltung am Arduino-Pin ansetzen.
Dann kannst das mit einem Interruptpin und einem Zähler in der ISR lösen.

Wofür brauchst Du while(true)? Du hast doch loop.
Irgendwo brauchst Du auch noch die Zeit in millis().

Gruß Tommy

Hmmm, okay, vielen Dank.

Ich habe gerade pulseIn() versucht. Auch dabei komme ich auf nur 65 Signale.

Ich habe die Vermutung, dass Serial.println einige verschluckt. Ich probiere es mal, die Ausgabe erst mit Abschluss des Signal-Bursts zu machen, oder eben interrupt, ja.

Vielen Dank!

Ausgabe immer erst nach dem Ende, wenn es schnell sein soll.

Gruß Tommy

Warum die Zeit in millis()? Der Takt kommt ja von der Kamera. Immer wenn das Signal sich ändert (val != valPrev) soll es weitergehen.

Danke!

Und woher willst Du dann wissen, wann eine Sekunde vorbei ist? Einfach nur aus der Anzahl? Oder 1000 Impulse zählen und dann schauen, wie lange das gedauert hat. Ohne Zeit dürfte das schief gehen.

Gruß Tommy

Nö. Der Buffer wird nicht schnell genug geleert.
Du kannst Serial.begin versuchen mit 250000 zu setzen um mehr zu sehen...

Zunächst erzeuge ich ein Signal von 1000 Hz, welches ich mit einem Mega2560 messe und auf einen Ausgang ausgebe:

const byte kameraPin = 2;
const byte ledPin = 13;

void setup() {
  Serial.begin(250000);
  Serial.println("\nStart");
  pinMode(ledPin, OUTPUT);
}

void loop() {
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  const uint32_t messzeit = 1000;
  static bool valAlt = 0;
  static uint16_t zaehler = 0;

  bool valNeu = digitalRead(kameraPin);
  if (valNeu != valAlt)
  {
    digitalWrite(ledPin, valNeu);
    valAlt = valNeu;
    zaehler++;
  }

  if (jetzt - vorhin >= messzeit)
  {
    vorhin = jetzt;
    Serial.println(zaehler / 2);
    zaehler = 0;
  }
}

Ausgabe:

Start
1000
1001
999
1001
999
1001
1000
1000
1001
999
1001
1000

grafik

Oberes Signal Mega2560 Ausgang, unteres Eingang.

Grundsätzlich läßt sich das also machen. Wenn es bei Dir nicht funktioniert, liegt es vermutlich am Kamerasignal.

Ein Optokoppler alleine produziert dir kein Digitalsignal. Dafür nimmt man Logikgatter mit Schmitt-Trigger Funktion. Wobei das auch die Arduino-Eingänge für sich schon machen. Einfach weil die Pegel ab der High und Low erkannt werden festgelegt sind.

Hallo und lieben Dank euch allen. Das ist ja so ein krasses Forum hier, beinahe wie ein Chat! Sensationell. Echt vielen Dank.

Ich habe jetzt die "pulseIn(pin, HIGH);"-Variante benutzt, und tatsächlich, ohne Ausgabe kein Problem, auch bei 6200fps. Super!

Die Variante von agmue funktioniert auch. Vielen Dank euch allen!

Als nächstes werde ich versuchen, da nun LEDs mit zu switchen.

Wenn du in deinem Code Serial nicht zeigst, können wir dir auch nicht sagen, was du falsch machst.

Das stimmt, da war noch jede Menge mehr drin, mir war nicht klar, dass es daran liegen könnte...

Du solltest dabei berücksichtigen, dass pulseIn() blockiert - bei 6000fps vielleicht kein Problem. Aber wenn es (sehr) langsam wird, kann man in der Wartezeit auf die nächste Flanke vielleicht was anderes mit der CPU anstellen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.