Zeitraffer Takte

Hallo,

ich möchte mir eine Zeitraffereinheit für eine DSLR Kamera bauen, die bei jedem "Takt" ein (erstes) Foto macht, dann die Kamera bewegt, ein zweites Foto macht und dann die Kamera wieder auf die "Null" Stellung zurück bewegt.

Ich habe schon etwas herum probiert, habe aber immer das Problem, dass die einzelnen Aktionen nicht "getrennt" voneinander erfolgen. D.h. die Kamera fährt mal, bevor sie das erste Bild gemacht hat, oder macht das zweite Bild während sie noch fährt. Wie kann ich denn sicher stellen, dass die nächste Aktion erst passiert, wenn die vorherige beendet ist.

Wie ihr im Code sicher sehen könnte, habe ich schon einige Ansätze probiert, die aber alle nicht zielführend waren. Ich glaube ich muss da prinzipiell anders mit den Aktionen umgehen, aber wie.....

Danke schon mal für die Hilfe!
Christian

#include <Bounce.h>
#include <Wire.h>
#include <RTClib.h>

RTC_DS1307 RTC;

const int photoCell_PIN = 0;
const int trigger_PIN = 1;
const int focus_PIN = 2;
const int led_PIN = 3;
const int step_PIN = 4;
const int dir_PIN = 5;
const int piezo_PIN = 9;
const int button_PIN = 6;
boolean left_eye = false;
boolean right_eye = false;

const int intervall = 15;         //Zeitrafferintervall (sekunden)
const int intervall_vorw = 3;  //vorwarnungsintervall (sekunden)

int photocellReading;  //Helligkeit
int thresholdlight = 250;    //Helligkeitsschwelle für AUX Led
int auxstatus = 0;         //Status des ext. Triggers

int distanceIA = 8727;        //Interaxialabstand in Motorschritten, 1mm ca. 436 Steps
int distance = 0;      //gefahrene Distanz


unsigned long now_cycle;         //aktueller Takt
unsigned long last_cycle;        //letzter Takt
unsigned int count_cycle =0;    //Zähler Takte


void setup () {
  Wire.begin();
  Serial.begin(9600);
  RTC.begin();
  // following line sets the RTC to the date & time this sketch was compiled
  RTC.adjust(DateTime(__DATE__, __TIME__));
  pinMode (trigger_PIN, OUTPUT);
  pinMode (focus_PIN, OUTPUT);
  digitalWrite (trigger_PIN, LOW);
  digitalWrite (focus_PIN, LOW);
  pinMode (led_PIN, OUTPUT);
  digitalWrite (led_PIN, LOW);
  pinMode (step_PIN, OUTPUT);
  pinMode (dir_PIN, OUTPUT);
  digitalWrite (step_PIN, LOW);
  digitalWrite (dir_PIN, LOW);
  pinMode (piezo_PIN, OUTPUT);
  pinMode (button_PIN, INPUT);
}



void loop () {
  timeCheck();
  // Check if aux is on
  if (auxstatus == 1)
  {
    //Yes -> switch it off!
    delay(500);
    digitalWrite (led_PIN, LOW);
    auxstatus = 0;
  }

}

void timeCheck() {
  DateTime now = RTC.now();

  //Check ob erster Takt!
  if (count_cycle == 0) {
    last_cycle = now.unixtime() - intervall;
  }

  now_cycle = now.unixtime();

  if (now_cycle == last_cycle + intervall - intervall_vorw) {
    vorwarnung();
  }


  //Check ob Intervall
  if (now_cycle == last_cycle + intervall) {
    //Ja -> Takt einmal ausführen
    cycle();
  }
}

void cycle() {
  lightCheck();
  debug();
  trigger();  //Bild für erstes (linkes) Auge
  delay(1000);
  debug();
  for (int i = 0; i < 1000; i++) {
    delay(10);
    if (left_eye == true && right_eye == false) {
      break;
    }
  }
  setInterax();
  do {
    delay(10);
  } 
  while (distance < distanceIA);
  trigger(); //Bild für zweites (rechtes) Auge
  debug();
  do {
    delay (10);
  }
  while (right_eye == false);
  resetInterax();
  count_cycle = count_cycle++;  
  last_cycle = now_cycle;
  left_eye = false;
  right_eye = false;
}

void lightCheck() {
  photocellReading = analogRead(photoCell_PIN);
  if (photocellReading < thresholdlight) {
    digitalWrite (led_PIN, HIGH);
    auxstatus = 1;
  }
}

void trigger() { 
  digitalWrite (focus_PIN, HIGH);
  delay(10);
  digitalWrite (trigger_PIN, HIGH);
  delay(10);
  digitalWrite (trigger_PIN, LOW);
  delay(10);
  digitalWrite (focus_PIN, LOW);
  if (left_eye == false) {
    left_eye = true;
  }
  else if (left_eye == true) {
    right_eye = true;
  }

}

//debug Funktion
void debug() {
  Serial.print(count_cycle);
  Serial.print(" - ");
  Serial.print(left_eye);
  Serial.print(right_eye);
  Serial.print(" - ");
  Serial.println(distance);
}


//Funktion zum Fahren des Interaxials
void setInterax() {
  delay(1000);
  digitalWrite(dir_PIN, LOW);
  while (distance < distanceIA) {
    drive();
    distance = distance ++;
  }
  delay(500);
}

//Funktion zum Fahren des Interaxials auf Null zurück
void resetInterax() {
  digitalWrite (dir_PIN, HIGH);
  while (distance > 0) {
    drive();
    distance = distance --;
  }
}

//Funktion zum Fahren des Motors
void drive() {
  digitalWrite (step_PIN, HIGH);
  delayMicroseconds(25);
  digitalWrite (step_PIN, LOW);
  delayMicroseconds(25);
}


//Funktion für Vorwarnung
void vorwarnung() {
  buzz();
}

//Funktion für akustisches Signal
void buzz() {
  for (int i=0; i < 3; i++) {
    tone(piezo_PIN, 400, 200);
    delay(200);
  }
  delay(500);
}

was mir als erstes auffällt, es gibt fürchterlich viele delay in deinem Programm,
ich würde grundsätzlich versuchen, ohne delay auszukommen

...ich auch gerne, darum schreibe ich hier :wink: !

Gruß
Christian

...ich seh schon, ich muss etwas konkreter werden.

Unten findet ihr nochmal meinen Code, allerdings nur die in Frage kommenden Teile, nachdem ich etwas weiter probiert habe. Die Idee ist, zu speichern, ob das entsprechende Bild im Takt schon gemacht wurde oder nicht und auf welcher Position sich die Kamera befindet. Daraus kann man dann ersehen, ob die Kamera sich bewegen darf, oder nicht.

Über mein "debug" Funktion lasse ich mir die Werte anzeigen und die sind auch korrekt. Ich habe es einmal über eine "for" Schleife versucht und ein mal mit "do...while" und jeweils einen delay, welches so lange wiederholt wird, bis die Bedingungen erfüllt sind. Leider funktioniert das so nicht. Auch würde ich gerne (wie schon angemerkt) "delay" vermeiden. Wie kann ich denn diese gewünschte Verzögerung umsetzen?

void cycle() {
  lightCheck();
  debug();
  trigger();  //Bild für erstes (linkes) Auge
  for (int i = 0; i < 1000; i++) {
    delay(10);
    if (left_eye == true && right_eye == false) {
      break;
    }
  }
  setInterax();
  debug();
  do {
    delay(10);
  } 
  while (distance < distanceIA);
  trigger(); //Bild für zweites (rechtes) Auge
  debug();
  do {
    delay (10);
  }
  while (right_eye == false);
  resetInterax();
  count_cycle = count_cycle++;  
  last_cycle = now_cycle;
  left_eye = false;
  right_eye = false;
}

void lightCheck() {
  photocellReading = analogRead(photoCell_PIN);
  if (photocellReading < thresholdlight) {
    digitalWrite (led_PIN, HIGH);
    auxstatus = 1;
  }
}

void trigger() { 
  digitalWrite (focus_PIN, HIGH);
  delay(100);
  digitalWrite (trigger_PIN, HIGH);
  delay(100);
  digitalWrite (trigger_PIN, LOW);
  digitalWrite (focus_PIN, LOW);
  if (left_eye == false) {
    left_eye = true;
  }
  else if (left_eye == true) {
    right_eye = true;
  }

}

//debug Funktion
void debug() {
  Serial.print(count_cycle);
  Serial.print(" - ");
  Serial.print(left_eye);
  Serial.print(right_eye);
  Serial.print(" - ");
  Serial.println(distance);
}


//Funktion zum Fahren des Interaxials
void setInterax() {
  digitalWrite(dir_PIN, LOW);
  while (distance < distanceIA) {
    drive();
    distance = distance ++;
  }
}

//Funktion zum Fahren des Interaxials auf Null zurück
void resetInterax() {
  digitalWrite (dir_PIN, HIGH);
  while (distance > 0) {
    drive();
    distance = distance --;
  }
}

//Funktion zum Fahren des Motors
void drive() {
  digitalWrite (step_PIN, HIGH);
  delayMicroseconds(25);
  digitalWrite (step_PIN, LOW);
  delayMicroseconds(25);
}

Warum überhaupt selber schreiben. Gut geklaut ist besser als selber nachgedacht: http://www.openmoco.org/.