• Herzlich willkommen im "neuen" DSLR-Forum!

    Wir hoffen, dass Euch das neue Design und die neuen Features gefallen und Ihr Euch schnell zurechtfindet.
    Wir werden wohl alle etwas Zeit brauchen, um uns in die neue Umgebung einzuleben. Auch für uns ist das alles neu.

    Euer DSLR-Forum-Team

  • In eigener Sache!

    Liebe Mitglieder, liebe Besucher und Gäste
    ich weiß, es ist ein leidiges Thema, aber ich muss es ansprechen: Werbung, Werbeblocker und Finanzierung des Forums.
    Bitte hier weiterlesen ...

  • DSLR-Forum Fotowettbewerb neu erfunden!
    Nach wochenlanger intensiver Arbeit an der Erneuerung des Formates unseres internen Fotowettbewerbes ist es Frosty als Moderator
    und au lait als Programmierer gelungen, unseren Wettbewerb auf ein völlig neues Level zu heben!
    Lest hier alle Infos zum DSLR-Forum Fotowettbewerb 2.0
    Einen voll funktionsfähigen Demowettbewerb kannst du dir hier ansehen.
  • Neuer Partner: AkkuShop.de
    Akkus, Ladegeräte und mehr (nicht nur) für Digitalkameras und Drohnen
  • Neuer Gutscheincode unseres Partners Schutzfolien24:
    DSLR-Forum2024
    Dauerhaft 10% Rabatt auf alle Displayschutzfolien der Eigenmarken "Upscreen", "Brotec", "Savvies".
    Der Code ist für alle Geräteklassen gültig.
  • Stimmt ab über die Sieger des DSLR-Forum Fotowettbewerbs April 2024.
    Thema: "Sprichwörtlich"

    Nur noch bis zum 30.04.2024 23:59!
    Jeder darf abstimmen!
    Zur Abstimmung und Bewertung hier lang
WERBUNG

Bastelanleitung: Arduino-basierter Lichtschranken-Trigger

Und? Funktionierts oder nicht?
 
Hallo,
hier mal fix ein Bild von meinem Versuchsaufbau. Magnetventil noch von Hand gesteuert- ich warte noch auf den Leistungstransistor. Lichtschranke nicht mit IR-LED, da ich nur eine habe, 12 V Netzteil für das Magnetventil und rechts unten das "Gehirn". Der Auffangbehälter wird zu gegebener Zeit ausgetauscht;))
Meine Frau hat schon gefragt, ob ich nichts sinnvolles zu tun hätte...
Viele Grüße
Ralf
 
Ich spüre ein Fieber in mir....
nicht spektakulär, aber für die ersten Versuche ausbaufähig- oder?
In Niggohs Programm habe ich den IR-Auslöser eingebaut:
Code:
// KONSTANTEN
const int lichtschranken_pin = A0;
const int ventil_pin = 12;
const int kamera_pin = 13;
const int ircontrol_pin = 11;

// VARIABLEN
// Alle Zeiten in Millisekunden angegeben

// Zeitvariablen initalisieren
// Auslöseverzögerung Kamera
long aktuellezeit_ausloeseverzoegerung = 0;
long startzeit_ausloeseverzoegerung = 0;
// Ventil
long aktuellezeit_ventil = 0;
long startzeit_ventil = 0;

// Ventilöffnungszeiten festlegen
int tropfenzeit_1 = 150;
int verschlusszeit_1_2 = 70;
int tropfenzeit_2 = 150;
int verschlusszeit_2_3 = 70;
int tropfenzeit_3 = 150;
int gesamtzeit_tropfserie = tropfenzeit_1 + verschlusszeit_1_2 + tropfenzeit_2 + verschlusszeit_2_3 + tropfenzeit_3 + 500; // für die Inaktivzeit der Lichtschranke, 500 ms Sicherheitsreserve, damit die Lichtschranke nicht durch den dritten Tropfen doch wieder aktiviert werden kann

// Zeit zwischen den Tropfenserien festlegen
int pausenzeit = 10000;

// Auslöseverzögerung festlegen
int ausloeseverzoegerung = 288;

// Aktivierungszeit für Kameraauslöser festlegen
int ausloeser_aktivzeit = 200;

// Lichtschranken-Schwellenwert festlegen
int lichtschranke_messwert;
int lichtschranke_maximum;
int lichtschranke_minimum;
int lichtschranke_schwellenwert;
float lichtschranke_schwellenwertfaktor = 0.85; // Faktor, mit dem der maximale Messwert der Lichtschranke multipliziert wird, um den Schwellenwert zu errechnen, muss unbedingt kleiner als 1 sein!

// Statusvariable Lichtschranke
boolean lichtschranke_unterbrochen = false;

// Statusvariable Kameraauslöser
boolean kamera_ausloeser_aktiv = false;

// Satusvariable Ventil
boolean ventil_offen = false;

// Statusvariable Tropfserie
boolean tropfserie_laeuft = false;

// Statusvariable Tropfen ausgelöst
boolean tropfen_ausgeloest = false;

// Ventilzeiten in Absolutwerte umrechnen
int endzeit_offen_1 = tropfenzeit_1;
int endzeit_geschlossen_1_2 = endzeit_offen_1 + verschlusszeit_1_2;
int endzeit_offen_2 = endzeit_geschlossen_1_2 + tropfenzeit_2;
int endzeit_geschlossen_2_3 = endzeit_offen_2 + verschlusszeit_2_3;
int endzeit_offen_3 = endzeit_geschlossen_2_3 + tropfenzeit_3;
int endzeit_pause = endzeit_offen_3 + pausenzeit;

// Eingabevariable initialisieren
int eingabe;

void setup() {
  // Ausgangspins initialisieren
  pinMode(ventil_pin, OUTPUT); 
  pinMode(kamera_pin, OUTPUT);
  pinMode(ircontrol_pin, OUTPUT);
  // Serielle Verbindung zum Computer initialisieren für Textausgabe
  Serial.begin(9600);
  Serial.println("Lichtschranke wird kalibiert...");
  // Die ersten zwei Sekunden die Lichtschranke kalibrieren
  while (millis() < 2000) {
    lichtschranke_messwert = analogRead(lichtschranken_pin);
    // Maximalwert speichern
    if (lichtschranke_messwert > lichtschranke_maximum) {
      lichtschranke_maximum = lichtschranke_messwert;
    }
    // Minimalwert speichern, nur fuer den Fall, dass wir den Schwellenwert irgendwann mal anders berechnen wollen
    if (lichtschranke_messwert < lichtschranke_minimum) {
      lichtschranke_minimum = lichtschranke_messwert;
    }
  }
  lichtschranke_schwellenwert = lichtschranke_maximum * lichtschranke_schwellenwertfaktor;
  Serial.print("Leerwert der Lichtschranke: ");
  Serial.println(lichtschranke_maximum);
  Serial.print("Schwellenwert der Lichtschranke: ");
  Serial.println(lichtschranke_schwellenwert);
}


// sets the pulse of the IR signal.
void pulseON(int pulseTime) {
  unsigned long endPulse = micros() + pulseTime;        // create the microseconds to pulse for
  while( micros() < endPulse) {
    digitalWrite(ircontrol_pin, HIGH);                       // turn IR on
    delayMicroseconds(13);                              // half the clock cycle for 38Khz (26.32×10-6s) - e.g. the 'on' part of our wave
    digitalWrite(ircontrol_pin, LOW);                        // turn IR off
    delayMicroseconds(13);                              // delay for the other half of the cycle to generate wave/ oscillation
  }
}
void pulseOFF(unsigned long startDelay) {
  unsigned long endDelay = micros() + startDelay;       // create the microseconds to delay for
  while(micros() < endDelay);
}
void takePicture() {
  for (int i=0; i < 2; i++) {
    pulseON(2000);                                      // pulse for 2000 uS (Microseconds)
    pulseOFF(27850);                                    // turn pulse off for 27850 us
    pulseON(390);                                       // and so on
    pulseOFF(1580);
    pulseON(410);
    pulseOFF(3580);
    pulseON(400);
    pulseOFF(63200);
  }                                                     // loop the signal twice.
}


void loop() {
  tropfen_ausgeloest = true;

  // Tropfserie fallen lassen falls ausgelöst
  if (tropfen_ausgeloest == true) {
    aktuellezeit_ventil = millis();
    if (aktuellezeit_ventil - startzeit_ventil < endzeit_offen_1 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      tropfserie_laeuft = true;
      Serial.println("Tropfen 1 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_1 && aktuellezeit_ventil - startzeit_ventil < endzeit_geschlossen_1_2 && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 1 Ende, Ventil geschlossen");    
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_geschlossen_1_2 && aktuellezeit_ventil - startzeit_ventil < endzeit_offen_2 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      Serial.println("Tropfen 2 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_2 && aktuellezeit_ventil - startzeit_ventil < endzeit_geschlossen_2_3 && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 2 Ende, Ventil geschlossen");        
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_geschlossen_2_3 && aktuellezeit_ventil - startzeit_ventil < endzeit_offen_3 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      Serial.println("Tropfen 3 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_3 && aktuellezeit_ventil - startzeit_ventil < endzeit_pause && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 3 Ende, Ventil geschlossen");    
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_pause) {
      startzeit_ventil = aktuellezeit_ventil;
      tropfserie_laeuft = false;
      lichtschranke_unterbrochen = false;
      Serial.println("Ende der Pause, Startzeit aktualisiert, Lichtschranke wieder scharf");
    }
  }
  
  // Lichtschranke abfragen
    lichtschranke_messwert = analogRead(lichtschranken_pin);
    if (lichtschranke_messwert < lichtschranke_schwellenwert && lichtschranke_unterbrochen == false) {
      Serial.println("Lichtschranke unterbrochen");
      lichtschranke_unterbrochen = true;
      startzeit_ausloeseverzoegerung = millis();
    }
    // Verzögerungszeit abwarten, dann Kamera-Auslöser aktivieren
    aktuellezeit_ausloeseverzoegerung = millis();
    if (aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung > ausloeseverzoegerung && aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung < ausloeseverzoegerung + ausloeser_aktivzeit && kamera_ausloeser_aktiv == false && lichtschranke_unterbrochen == true) {
      digitalWrite(kamera_pin, HIGH);
      takePicture();
      kamera_ausloeser_aktiv = true; 
      Serial.println("Kamera-Ausloeser aktiviert");
    }
    // Aktivzeit des Auslösers abwarten, dann Kamera-Auslöser deaktivieren
    else if (aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung > ausloeseverzoegerung + ausloeser_aktivzeit && aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung < gesamtzeit_tropfserie && kamera_ausloeser_aktiv == true) {
      digitalWrite(kamera_pin, LOW);
      kamera_ausloeser_aktiv = false;
      Serial.println("Kamera-Ausloeser deaktiviert");
    }
}

Die Auslöseverzögerung muss ich noch anpassen, das Magnetventil ist immer noch mit Hand ausgelöst, Beleuchtung und Schärfe haben noch Verbesserung notwendig.

Guten Abend noch, ich schau jetzt fern mit meiner Frau;)
 
Hab nochmal ein paar Euro in ein LCD Shield fürs Arduino investiert. Es werden (natürlich auf möglichst einfachem Wege) ein LCD und Knöpfe zur Bedienung hinzugefügt. Das geht natürlich mit erheblichen Änderungen am Programmcode einher. Was bisher funktioniert:
- Tropfsequenz Auslösen durch Knopfdruck
- Verstellung von Kameraverzögerung und Tropfverzögerung über Knöpfe

Gravierender Vorteil gegenüber der bisherigen Version: der ständige Upload vom PC aufs Arduino entfällt, da man die Zeiten nun auch per Knopfdruck verändern kann. Das System wird also wesentlich bequemer zu bedienen.

Falls sich jemand selbst versuchen will: ich habe das DFRobot LCD Shield gekauft. Es lässt sich problemlos über die Liquidcrystal Bibliothek ansteuern und kommt mit 5 Knöpfen, die alle über einen einzigen analogen Pin geschaltet werden, es bleiben also noch genügend Ein- und Ausgänge frei. Das Ding ist fertig zusammengebaut, man muss also nichts mehr löten sondern das Ding nur oben aufs Arduino stecken. Dazwischen hab ich noch ein WingShield gesteckt, in das dann die Ansteuerung für die Kamera und die Lichtschranke gebastelt werden sollen, damit hab ich allerdings noch nicht angefangen.

Leider ist noch relativ viel Programmier- und auch ein wenig Bastelarbeit zu leisten. Es kann also noch eine ganze Weile dauern, bis ich dafür eine Bastelanleitung erstellen kann.
 
Gravierender Vorteil gegenüber der bisherigen Version: der ständige Upload vom PC aufs Arduino entfällt, da man die Zeiten nun auch per Knopfdruck verändern kann. Das System wird also wesentlich bequemer zu bedienen.
Hallo niggoh und alle anderen,
ich habe die Auslöseverzögerung mit einem Poti eingestellt und mich langsam an den richtigen Wert rangetastet, allerdings konnte ich da den Wert auch nur über die USB-Leitung am Rechner ablesen.
Die Lösung mit dem LCD Keypad ist freilich luxuriös! Nur zum programmieren fehlt mir die Ahnung;)
Gibt es zum Auslesen der Tasten fertige Routinen? Also ich meine kurz drücken ist +/-1, lang drücken zählt von alleine- so wie man das vom Wecker kennt?
Viele Grüße
Ralf
 
Das mit den Tasten geht relativ problemlos so wie mit Deinem Wecker. Man kann auch einstellen, wie schnell das Hochzählen gehen soll. Die Knöpfe brauchen nur einen einzigen analogen Eingangspin am Arduino. Jeder hat einen anderen Widerstand dran, so dass sich das Signal verändert, je nachdem, welcher Knopf gedrückt wird.

Ich habe jetzt zumindest die Hardware fertig, an der Software hab ich noch ein bisschen was zu tun. Die Hardware-Funktionen sind:

1 Ausgang für Kameraauslöser, mit Autofokus (wichtig für die Nicht-Canon-Besitzer)
2 Ausgänge für Blitze
1 Ausgang für ein 12V Magnetventil
1 kombinierter Aus- und Eingang für Lichtschranke

Bauteile:
1x PC847
1x SFH610
1x BD139
1x 1N4007
2x Widerstand 100 Ohm
1x Widerstand 470 Ohm
3x Widerstand 1kOhm
1x IR-LED
1x IR-Fototransistor
dazu eine Platine, ein paar Drähte, 5 Klinkenbuchsen

Die Schaltung ist ohne Lötarbeiten aber leider nicht mehr sinnvoll zu realisieren. Alternativ kann man sich aber auch ein Breadboard zusammenstecken. Den Schaltplan hab ich mal aufgemalt und angehängt. Die LED und den Fototransistor muss man wie im ersten Post in diesem Thread an die richtigen Pole anschließen. Neu ist, dass der 5V-Ausgang des Arduinos für die LED genutzt wird. Das ermöglicht es, ein "Lichtschranken-Modul" zu basteln, das sich an einer 3-poligen Klinkenbuchse betreiben lässt. Prinzipiell wären auch andere Module denkbar (z.B. Licht- oder Schallauslöser). Es sind trotz LCD noch mehrere Pins frei, d.h. man könnte die Schaltung ggf. noch um zusätzliche Ausgänge erweitern, beispielsweise für Magnetventile oder weitere Blitze. Alle sind einzeln steuerbar, es wäre also kein Problem, mehrere Blitze zeitversetzt für eine Mehrfachbelichtung zu zünden.

Der Programmcode ist (wie bereits erwähnt) noch nicht fertig. Neben den Funktionen für die Wassertropfenfotografie sind prinzipiell auch viele andere Möglichkeiten umsetzbar, beispielsweise HDR, Zeitraffer, oder eine IR-Fernsteuerung.

Falls jemand trotzdem wissen möchte, wie ich das mit den Knöpfen und dem LCD angehe, hier der bisherige Quelltext.

ACHTUNG! NICHT FUNKTIONSFÄHIG!
Code:
#include <LiquidCrystal.h>  // LiquidCrystal Bibliothek einbinden

// Folgende PINS werden für Knöpfe und LCD genutzt und stehen somit nicht mehr zur Verfügung:
// LCD: Digital 4,5,6,7,8,9
// Knöpfe: A0

// Arduino-Pins für das LCD setzen
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// sonstige Arduino-Pins setzen
const int lichtschranken_pin = A1;
const int ventil_pin = 12;
const int kamera_pin = 13;

// Variablen und Konstanten für die Knöpfe am LCD Shield definieren
int LCD_Knopf = 0;
int Analoge_Knopf_Eingabe = 0;
#define rechts_Knopf 0
#define links_Knopf  1
#define oben_Knopf   2
#define unten_Knopf  3
#define select_Knopf 4
#define kein_Knopf   5

// Zeitvariablen initalisieren
// Auslöseverzögerung Kamera
long aktuellezeit_ausloeseverzoegerung = 0;
long startzeit_ausloeseverzoegerung = 0;
// Ventil
long aktuellezeit_ventil = 0;
long startzeit_ventil = 0;

// Ventilöffnungszeiten festlegen, evtl. in nächster Programmversion später im EEPROM speichern!
int tropfenzeit_1 = 150;
int verschlusszeit_1_2 = 70;
int tropfenzeit_2 = 150;
int verschlusszeit_2_3 = 0; // auf Null gesetzt, solange noch keine Menüs existieren und wir nur mit 2 Tropfen arbeiten
int tropfenzeit_3 = 0; // auf Null gesetzt, solange noch keine Menüs existieren und wir nur mit 2 Tropfen arbeiten
int gesamtzeit_tropfserie = tropfenzeit_1 + verschlusszeit_1_2 + tropfenzeit_2 + verschlusszeit_2_3 + tropfenzeit_3 + 500; // für die Inaktivzeit der Lichtschranke, 500 ms Sicherheitsreserve, damit die Lichtschranke nicht durch den dritten Tropfen doch wieder aktiviert werden kann

// Standardwerte für Auslöseverzögerung festlegen, evtl. in nächster Programmversion später im EEPROM speichern!
int ausloeseverzoegerung = 288;
int tropfverzoegerung = 70;

// Zeit zwischen den Tropfenserien festlegen
int pausenzeit = 10000;

// Aktivierungszeit für Kameraauslöser festlegen
int ausloeser_aktivzeit = 200;

// Statusvariable Tropfen ausgelöst
boolean tropfen_ausgeloest = false;

// Lichtschranken-Schwellenwert festlegen
int lichtschranke_messwert;
int lichtschranke_maximum;
int lichtschranke_minimum;
int lichtschranke_schwellenwert;
float lichtschranke_schwellenwertfaktor = 0.85; // Faktor, mit dem der maximale Messwert der Lichtschranke multipliziert wird, um den Schwellenwert zu errechnen, muss unbedingt kleiner als 1 sein!

// Statusvariable Lichtschranke
boolean lichtschranke_unterbrochen = false;

// Statusvariable Kameraauslöser
boolean kamera_ausloeser_aktiv = false;

// Satusvariable Ventil
boolean ventil_offen = false;

// Statusvariable Tropfserie
boolean tropfserie_laeuft = false;

// Ventilzeiten in Absolutwerte umrechnen
int endzeit_offen_1 = tropfenzeit_1;
int endzeit_geschlossen_1_2 = endzeit_offen_1 + verschlusszeit_1_2;
int endzeit_offen_2 = endzeit_geschlossen_1_2 + tropfenzeit_2;
int endzeit_geschlossen_2_3 = endzeit_offen_2 + verschlusszeit_2_3;
int endzeit_offen_3 = endzeit_geschlossen_2_3 + tropfenzeit_3;
int endzeit_pause = endzeit_offen_3 + pausenzeit;

// Debounce-Variablen
const int debounce_zeit = 100; // (in ms) reduzieren, um schnelleren Zahlendurchlauf bei Knopfdruck zu erreichen, erhöhen für langsameren Zahlendurchlauf
long debounce_zeitstempel = 0; // Zeitstempelvariable für Knopf-Debounce initialisieren

void setup() {
  lcd.begin(16, 2);                 // LCD initialisieren
  lcd.setCursor(0,0);               // LCD Cursor in die erste Reihe nach oben links setzen
  lcd.print("crazy machine");       // Programmnamen ausgeben
  lcd.setCursor(0,1);               // LCD Cursor in die zweite Reihe nach ganz links setzen
  lcd.print("Version 0.1");         // Programmversion ausgeben
  delay(1000);                      // 1 Sekunde verzögern
  lcd.clear();                      // Display löschen
  lcd.setCursor(0,0);
  lcd.print("Cam. delay");  
  lcd.setCursor(11,0);
  lcd.print(ausloeseverzoegerung);
  lcd.setCursor(14,0);
  lcd.print("ms");
  lcd.setCursor(0,1);
  lcd.print("Drop delay");
  lcd.setCursor(11,1);
  lcd.print(tropfverzoegerung);
  lcd.setCursor(14,1);
  lcd.print("ms");
  // Ausgangspins initialisieren
  pinMode(ventil_pin, OUTPUT); 
  pinMode(kamera_pin, OUTPUT);
  // Serielle Verbindung zum Computer initialisieren für Textausgabe
//  Serial.begin(9600);
//  Serial.println("Lichtschranke wird kalibiert...");
  // Die ersten zwei Sekunden die Lichtschranke kalibrieren
  while (millis() < 2000) {
    lichtschranke_messwert = analogRead(lichtschranken_pin);
    // Maximalwert speichern
    if (lichtschranke_messwert > lichtschranke_maximum) {
      lichtschranke_maximum = lichtschranke_messwert;
    }
    // Minimalwert speichern, nur fuer den Fall, dass wir den Schwellenwert irgendwann mal anders berechnen wollen
    if (lichtschranke_messwert < lichtschranke_minimum) {
      lichtschranke_minimum = lichtschranke_messwert;
    }
  }
  lichtschranke_schwellenwert = lichtschranke_maximum * lichtschranke_schwellenwertfaktor;
//  Serial.print("Leerwert der Lichtschranke: ");
//  Serial.println(lichtschranke_maximum);
//  Serial.print("Schwellenwert der Lichtschranke: ");
//  Serial.println(lichtschranke_schwellenwert);  
  Serial.begin(9600);               // Serielles Verbindung (9600 Baud) starten
  Serial.println("Funktioniert!");  // Auch über seriellen Port bekanntgeben, dass das Programm läuft
}

// ##############################
// BEGINN HAUPTSCHLEIFE VOID LOOP
// ##############################
void loop(){
  if (debounce_zeitstempel + debounce_zeit < millis()) {
    Knopf_Lesen();  // Knopfdruck auslesen und darauf entsprechend reagieren
    debounce_zeitstempel = millis();
  }
  if (tropfen_ausgeloest == true) {
    Tropfen_Fallen_Lassen();
  }
}
// ############################
// ENDE HAUPTSCHLEIFE VOID LOOP
// ############################

void kamera_ausloesen() {
  // Lichtschranke abfragen
    lichtschranke_messwert = analogRead(lichtschranken_pin);
    if (lichtschranke_messwert < lichtschranke_schwellenwert && lichtschranke_unterbrochen == false) {
//      Serial.println("Lichtschranke unterbrochen");
      lichtschranke_unterbrochen = true;
      startzeit_ausloeseverzoegerung = millis();
    }
    // Verzögerungszeit abwarten, dann Kamera-Auslöser aktivieren
    aktuellezeit_ausloeseverzoegerung = millis();
    if (aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung > ausloeseverzoegerung && aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung < ausloeseverzoegerung + ausloeser_aktivzeit && kamera_ausloeser_aktiv == false && lichtschranke_unterbrochen == true) {
      digitalWrite(kamera_pin, HIGH);
      kamera_ausloeser_aktiv = true; 
//      Serial.println("Kamera-Ausloeser aktiviert");
    }
    // Aktivzeit des Auslösers abwarten, dann Kamera-Auslöser deaktivieren
    else if (aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung > ausloeseverzoegerung + ausloeser_aktivzeit && aktuellezeit_ausloeseverzoegerung - startzeit_ausloeseverzoegerung < gesamtzeit_tropfserie && kamera_ausloeser_aktiv == true) {
      digitalWrite(kamera_pin, LOW);
      kamera_ausloeser_aktiv = false;
//      Serial.println("Kamera-Ausloeser deaktiviert");
    }
}

// *******************************************
// BEGINN FUNKTION: VOID TROPFEN_FALLEN_LASSEN
// *******************************************
void Tropfen_Fallen_Lassen() {
    aktuellezeit_ventil = millis();
    if (aktuellezeit_ventil - startzeit_ventil < endzeit_offen_1 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      tropfserie_laeuft = true;
      Serial.println("Tropfen 1 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_1 && aktuellezeit_ventil - startzeit_ventil < endzeit_geschlossen_1_2 && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 1 Ende, Ventil geschlossen");    
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_geschlossen_1_2 && aktuellezeit_ventil - startzeit_ventil < endzeit_offen_2 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      Serial.println("Tropfen 2 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_2 && aktuellezeit_ventil - startzeit_ventil < endzeit_geschlossen_2_3 && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 2 Ende, Ventil geschlossen");        
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_geschlossen_2_3 && aktuellezeit_ventil - startzeit_ventil < endzeit_offen_3 && ventil_offen == false) {
      digitalWrite(ventil_pin, HIGH);
      ventil_offen = true;
      Serial.println("Tropfen 3 Start, Ventil offen");
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_offen_3 && aktuellezeit_ventil - startzeit_ventil < endzeit_pause && ventil_offen == true) {
      digitalWrite(ventil_pin, LOW);
      ventil_offen = false;
      Serial.println("Tropfen 3 Ende, Ventil geschlossen");    
    }
    else if (aktuellezeit_ventil - startzeit_ventil > endzeit_pause) {
      startzeit_ventil = aktuellezeit_ventil;
      tropfserie_laeuft = false;
      lichtschranke_unterbrochen = false;
      tropfen_ausgeloest = false;
      Serial.println("Ende der Pause, Startzeit aktualisiert, Lichtschranke wieder scharf");
    }
}
// *****************************************
// ENDE FUNKTION: VOID TROPFEN_FALLEN_LASSEN
// *****************************************

// *********************************
// BEGINN FUNKTION: VOID KNOPF_LESEN
// *********************************
// Funktion, um die auf Knopfdrücke zu reagieren
void Knopf_Lesen() {
  LCD_Knopf = Umwandlung_Analoge_Knopf_Eingabe();    // Funktion Umwandlung_Analoge_Knopf_Eingabe aufrufen
  switch (LCD_Knopf) {               // Ergebnis der Funktion auswerten
    case rechts_Knopf: {             // Rechts Knopf gedrückt
      if (ausloeseverzoegerung < 999) {
        ausloeseverzoegerung = ausloeseverzoegerung + 1;
      lcd.setCursor(11,0);
      lcd.print("   ");
      lcd.setCursor(11,0);
      lcd.print(ausloeseverzoegerung);      
      }
      break;
    }
    case links_Knopf: {              // Links Knopf gedrückt
      if (ausloeseverzoegerung > 0) {
        ausloeseverzoegerung = ausloeseverzoegerung - 1;
      lcd.setCursor(11,0);
      lcd.print("   ");
      lcd.setCursor(11,0);
      lcd.print(ausloeseverzoegerung);      
      }
      break;
    }
    case oben_Knopf: {               // Oben Knopf gedrückt
      if (tropfverzoegerung < 500) {
        tropfverzoegerung = tropfverzoegerung + 1;
      lcd.setCursor(11,1);
      lcd.print("   ");
      lcd.setCursor(11,1);
      lcd.print(tropfverzoegerung);      
      }
      break;
    }
    case unten_Knopf: {              // Unten Knopf gedrückt
      if (tropfverzoegerung > 0) {
        tropfverzoegerung = tropfverzoegerung - 1;
      lcd.setCursor(11,1);
      lcd.print("   ");
      lcd.setCursor(11,1);
      lcd.print(tropfverzoegerung);      
      }
      break;
    }
    case select_Knopf: {             // Select Knopf gedrückt
      tropfen_ausgeloest = true;
      break;
    }
    case kein_Knopf: {               // Kein Knopf gedrückt
      break;
    }
  }   
}
// *******************************
// ENDE FUNKTION: VOID KNOPF_LESEN
// *******************************

// *****************************************************
// BEGINN FUNKTION: INT UMWANDLUNG_ANALOGE_KNOPF_EINGABE
// *****************************************************
// Funktion, um Spannungsveränderungen durch die Knopfdrücke in einen Integer umzuwandeln (SELECT, LEFT, UP, DOWN, RIGHT)
int Umwandlung_Analoge_Knopf_Eingabe() {
  // Wert von A0 auslesen und mit der "Knopfwerttabelle" vergleichen
  Analoge_Knopf_Eingabe = analogRead(0);      
  // Knopfwerttabelle:
  // Rechts: 0 // Oben: 142 // Unten: 328 // Links: 504 // Select: 741 // keiner: 1023
  // mittels des Testprogramms ermittelt
  // um Raum für Schwankungen zu lassen, uu jeder gemessenen Zahl etwa 50 addieren und die Werte zu den Knöpfen zugeordnet hier eintragen:
  if (Analoge_Knopf_Eingabe > 1000) return kein_Knopf;
  if (Analoge_Knopf_Eingabe < 50)   return rechts_Knopf;
  if (Analoge_Knopf_Eingabe < 195)  return oben_Knopf;
  if (Analoge_Knopf_Eingabe < 380)  return unten_Knopf;
  if (Analoge_Knopf_Eingabe < 555)  return links_Knopf;
  if (Analoge_Knopf_Eingabe < 790)  return select_Knopf; 
  return kein_Knopf;  // Falls alles andere nicht zutrifft: kein_Knopf zurückgeben
}
// ***********************************************
// ENDE FUNKTION: UMWANDLUNG_ANALOGE_KNOPF_EINGABE
// ***********************************************
ACHTUNG! NICHT FUNKTIONSFÄHIG!
 
Zuletzt bearbeitet:
Um mein nagelneues LCD-Shield zu testen, hab ich Niggohs Programm hochgeladen. LCD geht, Programm geht auch! Danke!(y)
 
Ich war die letzten Tage ziemlich fleißig und habe jetzt einen Programmcode, der einige Funktionen bietet. Es gibts bestimmt noch ein paar Bugs, aber die grundsätzlichen Dinge funktionieren.

Einstellung von folgenden Parametern im laufenden Betrieb:
  • Kameraverzögerung
  • Tropfzeit für den ersten Tropfen
  • Pausenzeit zwischen erstem und zweitem Tropfen
  • Tropfzeit für den zweiten Tropfen
  • Pausenzeit zwischen zweitem und drittem Tropfen
  • Tropfzeit für den dritten Tropfen
Weiterhin kommt man über das Menü an:
  • Auslösung Tropfsequenz für ein Einzelbild
  • Serienbildfunktion, dabei wird die Tropfsequenz mehrfach nacheinander ausgelöst
  • Die Anzahl der Bilder für die Serienbildfunktion und die Pause zwischen den Bildern ist ebenfalls über das Menü veränderbar
Die Vorteile liegen auf der Hand: man muss nicht für jede Veränderung eines Parameters das Programm neu hochladen. Es ist somit ein Betrieb unabhängig vom PC möglich.
Die Bedienung erfolgt über 5 Knöpfe (SELECT, LEFT, RIGHT, UP, DOWN). Ein Menü wird durch Betätigung von SELECT ausgewählt, durch LEFT und RIGHT kann man durch die einzelnen Menüpunkte scrollen. Die Veränderung der einzelnen Parameter erfolgt über UP und DOWN. Die Werte bleiben bis zum Neustart des Arduinos erhalten, danach werden wieder die im Quelltext vorgegebenen Standardwerte geladen. Es ist ein Betrieb mit und ohne Lichtschranke möglich. Um ohne Lichtschranke zu arbeiten einfach im Quellcode (erster Tab, Zeile 110) den Wert "use_irbarrier" auf false setzen.

Die Programmierung des Menüs war recht aufwändig, ich habe daher auf die Bibliothek "MenuBackend" aus dem Arduino-Playground zurückgegriffen. Diese muss separat heruntergeladen werden und unter Erhaltung der Verzeichnisstrukturen ins Verzeichnis "libraries" im Arduino-Programmordner entpackt werden. Gibts hier zum Download.
Aus Gründen der Übersichtlichkeit habe ich meinen Quelltext jetzt auf mehrere Dateien verteilt. Diese gibts natürlich ebenfalls zum Download, und zwar hier. Das Potential der Arduino-Plattform ist damit noch lange nicht erschöpft, ich werde von Zeit zu Zeit neue Funktionen hinzufügen. Die Menüstruktur ist deswegen auch darauf ausgelegt, in alle Richtungen mit verhältnismäßig wenig Aufwand erweiterbar zu sein.

Ich bin dabei, eine eigene Internetseite zum Thema einzurichten, um ein wenig mehr Übersichtlichkeit zu ermöglichen. Dafür sind Forenthreads ja nicht unbedingt der Weisheit letzter Schluss...

Die Software ist auf den Betrieb eines Arduinos mit einem LCD Shield ausgelegt. Die zusätzlich benötigte Hardware ist im Schaltplan im vorletzten Post zu sehen.

FRAGEN BITTE NICHT PER PN SONDERN HIER IM THREAD STELLEN. DANKE.

Viel Spaß beim Testen.
 
Das ist ja ganz grosses Kino, Niggoh!
Da warst Du wirklich fleißig! Ich habe mich mal durch das Menü geforstet und schon paar Tropfen fallen lassen. Alles Andere ausser dem Magnetventil habe ich noch nicht angeschlossen. Als "Tester" ist mir folgendes aufgefallen:
- Der Magnetventil-Pin entspricht nicht mehr Deinem Schaltplan, ist jetzt Pin 11
- bei der Aufnahmeserie ist nach der 4. Pause Ende- die 5. Tropfenserie fällt nicht mehr
- ebenso kann ich keinen 3. Tropfen fallen lassen, egal was ich bei Pause 2und Tropfen 3 für eine Zeit eingebe
- Die Zeiten im Menü lassen sich in den negativen Bereich runter zählen, arbeitest Du etwa an einer Zeitmaschine?
Super Webseite!
Freundliche Grüße
Ralf
 
Zum Thema Pin-Belegung:
Da bin ich insgesamt noch etwas unzufrieden. Wenn man Pin 0/1 mit Anschlüssen belegt, funktioniert der Upload aufs Board nicht mehr. Pin 13 wird nach jedem Reboot vom Arduino mehrfach an- und ausgeschaltet, d.h. weder Kamera noch Magnetventil sollten darauf liegen. Pin 4-10 sowie A0 sind vom LCD belegt, wobei ich mir bei Pin 10 nicht so sicher bin, angeblich wird darüber die Helligkeit der Hintergrundbeleuchtung geregelt, da muss ich mich nochmal belesen.
Bleiben also noch 2, 3, 11, 12 und 13 unter der Einschränkung, dass da nichts dran sollte, was nicht bei jedem Start aktiviert werden soll. Vielleicht einer der Blitzausgänge. Mal sehen. A1 braucht man für die Lichtschranke, A2, A3, A4, A5 könnte man soweit ich informiert auch als digitale Ausgangspins nutzen. Muss ich auch nochmal nachlesen. Dann könnte man nämlich ohne große Probleme noch das eine oder andere Ventil zusätzlich anschließen und ansteuern.

Das Problem mit der Serienaufnahme lässt sich leicht beheben. Ich hatte da auch schon die Vermutung, dass das passiert, aber ich habe nicht nachgezählt. Wenn Du es selbst ändern willst: in der Funktion take_waterdrop_picture_series einfach ein "<=" aus dem "<" in der ersten Zeile (mit dem "for" ganz am Anfang) machen. Ich habs für die nächste Version geändert, außerdem habe ich noch verhindert, dass nach dem letzten Bild einer Serie trotzdem die Pausenzeit abgewartet wird.

Das Problem mit dem dritten Tropfen muss ich mir nochmal genauer anschauen, da weiß ich auf Anhieb nicht, wo es herkommt.

Die negativen Zeiten hab ich jetzt erstmal dadurch verhindert, dass ich die entsprechenden Variablendeklarationen in "unsigned int" geändert habe. Das führt dazu, dass man bei Unterschreiten des Nullpunkts auf einmal den Wert 65535 bekommt. Funktioniert aber auch andersherum, man kommt auch schnell wieder auf 0 zurück.


Ich habe auch sonst noch ein paar Dinge verbessert. Die Datei im Downloadlink wurde aktualisiert.

Falls sich jemand meine Homepage zum Thema anschauen möchte: http://crazymachine.nicolai-korff.de/
Diese ist aber noch im Aufbau.
 
Zuletzt bearbeitet:
Zum Thema Pin 10- es stimmt, wenn man ihn anderweitig belegt, bleibt das Display dunkel! Ich habe wie immer die IR-LED zur Fernsteuerung meiner Nikon D40 angeschlossen, jetzt halt an Pin 13- den brauche ich momentan nicht.
Mit den analogen Pins hab ich es auch im Hinterkopf, man könne die digital benutzen- weiss ich aber nicht mehr genau, wo ich das gelesen habe.
Also bei mir tropft es und die Kamera löst über IR-LED aus, Ich find' das geil!
Schönen Abend
Ralf
 
Hab mal nachgelesen, man kann die analogen Pins problemlos auch als digitale Ausgänge nutzen (siehe hier). Somit hat man theoretisch die Möglichkeit, neben dem LCD bis zu 12 externe Geräte anzusteuern (Ventile, Kameras, Blitze oder Sensoren wie Lichtschranken, Schall- und Lichtsensoren, etc.). Irgendwann wirds halt ein bisschen eng mit den 30kb für den Programmcode, derzeit sind es etwa 10kb.

Was Dein Problem mit dem dritten Tropfen angeht: ich habe es bei mir mal getestet und der Tropfen wird genau wie gewünscht ausgelöst. Hab also keine Idee, warum es bei Dir nicht gehen sollte. Die paar zusätzlichen Zeilen Code, die Du für den IR-Auslöser brauchst, dürften eigentlich keinen so großen Unterschied machen.
 
So viele Eingänge braucht es nicht, zwei analoge Eingänge jeweils mit Spannungsversorgung sind ausreichend. Z.B. für eine Kreuzlichtschranke als Insektenfalle oder eine Lichtschranke plus Mikrofoneingang, wenn ich unbedingt den Donner mit auf dem Bild haben will. Die Art des Sensors sollte im Menü softwaretechnisch ausgewählt werden- Schall, Licht (Gewitter), Lichtschranke etc.
Kamerabuchse und zwei Blitze jeweils unabhängig mit verschiedenen Verzögerungszeiten zu steuern und als Schmankerl noch die Magnetventilsteuerung! Eine IR-LED um diverse Kameramodelle fern zu steuern, ein verständliches Menü dazu und das Ding ist perfekt!
Für ein Patent wird es nicht reichen, aber ich finde es faszinierend, wie aus Deiner Idee ein solches Projekt gewachsen ist! Da ist das Problem mit meinem dritten Tropfen gerade zu lächerlich, zwei reichen auch!:lol:
Freundliche Grüße
Ralf
 
Zuletzt bearbeitet:
Hier gibts relativ viele Infos zu Blitzen:
https://www.dslr-forum.de/showthread.php?t=254094

Ich persönlich habe:
1x Canon 460EXII, 2x LumoPro LP160, 2x YongNuo YN460-II
Funktionieren alle und haben alle Vor- und Nachteile:
Der Canon ist ganz nett wegen E-TTL, außerdem kann ich ihn mit meiner 7D auch ohne Funktrigger entfesselt auslösen. Lässt sich zoomen, ist aber manuell etwas fummelig einzustellen (geht bis 1/32) und relativ teuer.
Die LumoPros machen ziemlich viel Licht, das ist für Wassertropfen aber eher uninteressant. Lassen sich auf 1/64 runterregeln und lassen sich zoomen. Gut zu bedienen und es gibt einen 3,5mm Klinkenstecker-Eingang zum Auslösen. Fiepen leider ziemlich, kann schon nervig sein. Ansonsten aber (sofern man kein TTL braucht) ein guter Blitz.
Die YongNuos sind nur mäßig gut verarbeitet, lassen sich manuell aber ganz gut einstellen (1/64) und sind relativ billig.

Günstigste Variante sind aber sicherlich gebrauchte Blitze aus der Bucht, da müsstest Du Dich aber vorher ein bisschen einlesen bzgl. Regelbarkeit.
 
Einen kompletten Schaltplan habe ich in der aktuellen Fassung noch nicht, kann ich aber evtl. morgen früh mal erstellen. Im Grunde genommen kannst Du aber nach wie vor den hier nehmen:
https://www.dslr-forum.de/showpost.php?p=7822985&postcount=18
Letztlich geht es nur darum, das Magnetventil elektrisch vom Arduino zu trennen, damit Letzteres nicht zerstört wird.
Die Lichtschranke aus dem ersten Post kannst Du ebenfalls weiterhin benutzen, da hat sich eigentlich nichts verändert.

Neu ist bei mir eigentlich nur, dass ich inzwischen auch die Kamera über Optokoppler vom Arduino trenne und dass ich auch den AF-Kontakt beschalte, da sonst die nicht-Canon Kameras nicht auslösen.
 
WERBUNG
Zurück
Oben Unten