ESP8266 & Telegram

Einen Mikrocontroller per Messenger Befehle senden oder Daten erhalten? Ja das geht, und es ist auch genau so cool wie es sich anhört!

An dieser Stelle sollte eigentlich ein kurzes Video folgen, da man dazu jedoch einen Premium-Tarif benötigt, und das neben meiner Website etwas unnötig wäre, gibt es stattdessen den Link zur genannten Website: 

http://deloarts.com/de/arduino/esp8266_telegram/

Dank der entsprechenden Lib (folgt später im Eintrag) erspart man sich viel Schreibarbeit und kann gleich loslegen. Wenn man sich die Bibliothek genauer anschaut merkt man die Ähnlichkeit zur Python API, es ist lediglich stark abgespeckt, was für die Nutzung auf dem ESP nur Hilfreich ist.

Telegram

Zuerst muss man Telegram als Messenger nutzen, entweder auf dem Smartphone, Tablet oder dem PC. Danach kann man schon damit beginnen, einen Bot zu erstellen. Der Übersicht zu Liebe folgt ein Copy/Paste-Inhalt aus dem Raspberry-Tutorial.

Startet damit in das Suchen-Feld den Namen BotFather einzugeben. Dies ist der Manager aller Bots auf Telegram. Bei ihm sucht man um einen neuen Bot an.

Search_Botfather

Sendet ihm den Befehl /newbot, wählt einen Namen und einen Benutzernamen. Der Benutzername ist öffentlich sichtbar und auffindbar, durch geschickte Programmierung redet der Bot aber nur mit ausgewählten Nutzern. Als Namen vergebe ich gerne einen projektbezogenen, in diesem Fall wäre ‚Doorbell‘ recht passend.

Talk_To_BotFather

Ist der Vorgang abgeschlossen, so erhält man einen eindeutigen Token. Dieser ist später im Programm wichtig!

Das Programm

Zu finden wie immer auf GitHub. Wer neu ist, und das ESP noch nicht so gut kennt, dem empfehle ich das Setup-Tutorial zum Board.

Oben im Beitrag habe ich die Lib erwähnt, welche für die Nutzung der Telegram API benötigt wird. Die habe ich sie in das GitHub-Verzeichnis von mir kopiert, um immer die passende Version zu haben.

Bevor ihr beginnen könnt, gebt die WLAN-Daten eures Netzwerks ein.

static char SSID[] = "your network name";
static char password[] = "your password";
static char hostname[] = "Doorbell";

Weiter geht’s mit den Definitionen des Programms, dazu muss man den Botnamen, seinen Usernamen, den Token und die ID angeben, an welche die Nachrichten geschickt werden sollen.

#define botName "Doorbell"
#define botUserName "something that ends with bot"
#define botToken "your:token"
#define adminID "yourID"

Die adminID ist demzufolge die ID eures persönlichen Telegram-Accounts. Um diese herauszufinden, ladet das Script auf den ESP, gebt aber zuvor in den Programmdefinitionen eure Daten ein (Username & Token). Über das Suchen-Feld in Telegram könnt ihr über den Usernamen euren Bot finden. Sendet danach dem Bot über Telegram eine Nachricht, dieser wird euch sodann eure ID zurücksenden.

String senderID = bot.message[i][4];
bot.sendMessage(bot.message[i][4], "Access denied. Your ID: " + senderID, "");

Ein anderer Weg ist der serielle Monitor. Die Chat ID wird bei jedem Zugriff angezeigt.

Tragt danach die ID einfach an der entsprechenden Stelle im Programm ein, und voilà, der Bot hört auf euch.

Am Beginn sollte man den ESP via USB mit dem PC verbinden (auf die Baudrate achten), um die Debuginformation zu erhalten. So lässt sich leicht ein möglicher Fehler entdecken, etwa falsche WLAN-Zugangsdaten oder ein falscher Token.

Zurück zum eigentlichen Programm.

Im setup() werden alle Routinen gestartet, das Programm ist (hoffentlich) gut auskommentiert.

In der loop() ist es schon etwas interessanter. Grundsätzlich wäre dem Zweck Genüge getan, wenn der Controller auf das Betätigen des Tasters wartet, und dann eine Nachricht an die AdminID sendet.

if (!digitalRead(inputPin))
{
    bot.sendMessage(adminID, "Ding Dong", "");
}

Ich möchte aber auch zeigen, wie man dem ESP über Telegram Befehle senden kann, weshalb das Programm noch etwas weiter geht. So könnte man etwa ein Relais ansteuern, oder Daten eines Sensors abgreifen. Um das tun zu können, muss man wissen, wo die Daten gespeichert werden.

Grundsätzlich werden die Telegram-Daten beim Empfangen in einem zweidimensionalen Array gespeichert: bot.message[i][j]. Ist i gleich 0, so werden Sonderfälle behandelt:

  • bot.message[0][0]: Anzahl der anstehenden Nachrichten.
  • bot.message[0][1]: ID der letzten Nachricht.

Ansonsten ist i der Index der eingegangenen Nachrichten. j beinhaltet die Daten, welche zu i gehören.

  • bot.message[i][0]: Update ID
  • bot.message[i][1]: User ID
  • bot.message[i][2]: Vorname
  • bot.message[i][3]: Nachname
  • bot.message[i][4]: User ID
  • bot.message[i][5]: Nachricht

Zuerst prüfen wir, ob Updates, also neue Nachrichten zur Verfügung stehen. Diese werfen wir dazu in das Array um sie später zur Verfügung zu haben.

bot.getUpdates(bot.message[0][1]);

Danach arbeiten wir uns Schritt für Schritt durch die Daten durch, und prüfen zugleich, ob die empfangene Nachricht einem Befehl entspricht.

for (int i = 1; i < bot.message[0][0].toInt() + 1; i++)
{
    if (bot.message[i][4] == adminID)
    {
        bot.message[i][5] = bot.message[i][5].substring(1, bot.message[i][5].length());
        if (bot.message[i][5] == "info")
        {
            bot.sendMessage(bot.message[i][4], "Hello.", "");
            bot.sendMessage(bot.message[i][4], "I am your doorbell.", "");
        }

        ...

    }
}

i entspricht, wie wir wissen, dem Index der IDs, welche dem Bot eine Nachricht gesendet haben. Bevor wir also auf eine Nachricht antworten, prüfen wir ob der Absender auch berechtigt ist, eine Antwort vom Bot zu bekommen. Ist er das nicht, bekommt er eine entsprechende Rückmeldung.

bot.sendMessage(bot.message[i][4], "Access denied.", "");

So viel zum Programm. Man sieht, es steckt nicht viel dahinter (also, eigentlich schon, aber das Interface ist einfach).

Der elektrische Aufbau

Zum Testen des Programms reicht die Lochrasterplatine vom Setup-Tutorial und ein Taster, wie es im Video am Beginn gezeigt wird.

Ich möchte die bestehende Türklingel nicht durch die WIFI-Klingel ersetzen, sondern beide parallel bestehen haben. Deshalb setze ich ein Relais in die Leitung der vorhandenen Glocke, welches das Signal an den Controller gibt, sobald die Taste betätigt wird. Hierfür muss man das Relais entsprechend der verbauten Klingel auswählen. Meine arbeitet mit 12VDC, weshalb ich auch ein Relais nutze, das bei 12V schließt. Dabei ist darauf zu achten, dass das Netzteil für die Klingel genügend Strom für die Klingel selbst, als auch für das Relais liefert.

shematic.jpg

Im Schaltplan erkennt man unter anderem, dass das Relais ohne Pull-Down-Widerstand (im Normalfall 10kΩ) an den Controller angeschlossen wird. Der Grund ist der gleiche, wie der im Setup-Tutorial beschriebene: Ist einer der beiden GPIO-Pins beim Booten nicht logisch HIGH (oder in einem Zwischenzustand), so startet der ESP nicht das Programm, sondern erwartet den Upload eines Programms. Deshalb starte ich den ESP mit offenem Relais (es ist doch sehr unwahrscheinlich, dass jemand anleutet wenn der Controller gerade bootet).

Der zweite Punkt, welcher auffällig ist, ist dass der GPIO-Pin über das Relais nicht mit +3V3 verbunden ist, sondern mit der Groundleitung. Dazu bedarf es einer Erklärung des …

INPUT_PULLUP

Von den Schaltungen eines Arduinos ist man es gewohnt, einen Taster mit VCC und dem Pin zu verbinden. Vom Pin ausgehend schließt man einen hochohmigen Widerstand auf Ground um Störsignale oder Signalschwankungen zu filtern.

input

Würde man den Pull-Down-Widerstand weglassen, so wäre der Pin bei offenem Taster in einem Zwischenzutand (floating). Es ist also nicht eindeutig festgelegt, ob der Taster nun offen ist. Auf diese Weise können Signale der Umgebung, elektromagnetische oder magnetische Felder, den Pin beeinflussen. Das kann man sich sehr gut veranschaulichen, indem man sich über den seriellen Monitor eines blanken Arduinos den Wert eines Analogpins ausgeben lässt. Bewegt man das Board oder hält ein elektrisches Gerät in seine Nähe, so ändert sich der Wert.

/* Button an Pin 12,
   LED an Pin 13
*/
pinMode(12, INPUT);
pinMode(13, OUTPUT);
digitalWrite(13, digitalRead(12));

Das Programm sieht daher so aus wie immer, wird der Taster betätigt, so leuchtet die LED. Das ganze kann man aber auch umgekehrt lösen, indem man einen Pull-Up-Widerstand nutzt. Dieser wird zwischen VCC und dem Pin eingesetzt.

input_pullup

Ist der Taster offen, so bleibt die Spannung am Widerstand gleich – 5V, 3V3, … was auch immer die Versorgungsspannung ist. Das bedeutet, dass am Pin immer 5V, 3V3, … anliegen. Wird der Taster gedrückt, so fällt die Spannung auf Null ab. Durch den hochohmigen Widerstand verhindert man zudem ein Kurzschließen des Schaltkreises. Man sollte allerdings keinen allzu großen Widerstand wählen, da ansonsten das Rauschen wieder zurückkehrt (Luft ist ja auch ein Widerstand) – 10kΩ sind die Faustregel bei Controllern bis +5V Betriebsspannung.

/* Button an Pin 12,
   LED an Pin 13
*/
pinMode(12, INPUT);
pinMode(13, OUTPUT);
digitalWrite(13, !digitalRead(12));

Im Programm hat man nur eine kleine Änderung zu machen: Den Input mit dem Rufzeichen zu negieren. Ist der Taster nicht gedrückt gibt digitalRead(pin); true zurück und vice versa.

Nun könnten wir das bereits nutzen, um den Button am ESP anzuschließen. Der Pin wäre ohne Interaktion immer logisch HIGH, wodurch der Controller problemlos booten kann. Allerdings hat der Controller die nette Eigenschaft, einen hochohmigen Widerstand hinter seinen GPIO-Pins verbaut zu haben. Das bedeutet, dass wir uns darum nicht mehr kümmern müssen und der Aufbau sich vereinfacht:

input_internal

Gut, etwas muss man schon beachten: Der interne Widerstand muss aktiviert werden. Dies erledigt man, indem man den Input nicht mit pinMode(PIN, INPUT);, sondern mit pinMode(PIN, INPUT_PULLUP); festlegt.

/* Button an Pin 12,
   LED an Pin 13
*/
pinMode(12, INPUT_PULLUP);
pinMode(13, OUTPUT);
digitalWrite(13, !digitalRead(12));

Das lässt sich übrigens auch am Arduino anwenden. Wer also gerade keinen Widerstand zur Hand, oder nicht genug Platz für einen hat, muss nicht verzweifeln: einfach INPUT_PULLUP nutzen!

Weiters sind, auf das Arduino Nano bezogen, auch die analogen Pins A0-A5 (oder 14-19) als digitaler Input nutzbar, und sie haben ebenso einen Pull-Up-Widerstand verbaut. Lediglich die beiden letzten analogen Inputs (A6 und A7 [oder 20 und 21]) haben keinerlei Schaltung und dienen ausschließlich als analoger Input.

Und weil wir bereits beim Arduino sind: Der digitale Pin 13 kann nicht als Pull-Up-Input genutzt werden, da auf den Arduino Boards eine LED mit einem 330Ω Widerstand verbaut ist. Diese verhindert die Funktion, da sie den Pin dauerhaft mit GND verbindet und somit der Pin immer geschalten werden würde.

Zurück zum Thema: Für den Aufbau habe ich die folgenden Bauteile genutzt:

.

Stk. Komponente Ausführung Beschreibung
1 ESP8266 ESP-01
1 Widerstand 10kΩ
1 Spannungsregler LD33V 12VDC -> 3V3DC
2 Elektrolytkondensator 10µF
1 Kermaikkondensator 0.1µF
1 Relais 12VDC Passend zur Klingel

.

Die Kondensatoren dienen zur Glättung der Spannung, ohne diese würde der Spannungswandler instabil werden und die Spannung am Ausgang würde stark schwanken – schlecht für den ESP. Das passiert, weil der verwendete Spannungswandler von seinem Aufbau her ein rückgekoppelter Verstärker ist.

setup

Eine weitere Möglichkeit, neben dem Taster, wäre die Nutzung eines Infrarot-Bewegungsmelders. Diesen könnte man sogar an den verbeleibenden Pin des ESP anschließen (auf die galvanische Trennung beim Booten sollte man achten).

Fragen? Kommentar!

Advertisements

Servo Motor

Ich habe bereits gezeigt, wie ein Schrittmotor am Arduino genutzt wird. Nun will ich zeigen, wie man einen Servomotor steuern kann, und was dahinter steckt.

MG995

Ich nutze meistens den MG995 Servomotor, da er im Vergleich zu anderen Servomotoren mit einem Drehmoment von ~1,47Nm bei 6V viel bietet. Die Betriebsspannung liegt im Bereich zwischen 4,8-7,2 Volt, ich bewege mich eher im Bereich um 6V, das rührt aber eher von der Verwendeung von Batterien. Er hat zudem ein Getriebe aus Stahl und ist zweifach Kugelgelagert (Festlager abtriebsseitig). Der Motor ist zwar teuerer, dafür ist er als Stoßfest deklariert und seine Lebensdauer ist weit höher, als bei Motoren mit Kunststoffgetrieben. Er hat einen Rotationsbereich von 180° (+- 90° vom Nullpunkt), und eine maximale Stellgeschwindigkeit von 0.24 s/90° bei 6V (ohne Last).

mg995.jpg

Der MG955 darf nicht über das Arduino (oder einen anderen Controller) mit Spannung versorgt werden, da er mehr Strom benötigt, als der Spannungswandler oder ein Output-Pin des Arduinos zur Verfügung stellen kann – der Wandler würde überhitzen. Deshalb nutze ich, wie zuvor kurz erwähnt, Batterien, Akkus oder ein Netzteil. Der Controller dient nur als Steuerung für den Motor.

Die Funktionsweise

Der Servoantrieb besteht aus einem Motor (Servomotor) und einer Regelelektronik. Der Motor kann dabei als Gleichstrommotor, Synchron- oder Asynchronmotor ausgeführt sein. Die Regelung dahinter ist in vielen Anwendungen eine Positionsregelung für den Winkel, sie kann aber auch als Geschwindigkeits- oder Momentenregelung ausgeführt sein, oder eine Kombination aus den genannten.

Wer sich den Inhalt zum Schrittmotor durchgelesen hat, und dann den Schrittmotor mit einen Drehgeber und einer Regelung ausstatten würde, der hätte sich so selbst einen Servomotor gebaut. Oft werden aber Servomotoren mit Servos, wie auch der MG995 einer ist, gleichgesetzt. Der Unterschied ist, dass ein ‚Servo‘ lediglich eine Form eines Servomotors ist.

Die Regelung des Servos (ich beziehe mich jetzt auf den MG995 und ähnliche Modelle) erfolgt über den Vergleich zwischen Soll-Wert, also jenem Wert, welcher vom Mikrocontroller vorgegeben wird, und dem Ist-Wert. Der Ist-Wert wird über ein integriertes Potentiometer ermittelt, welches ebenso nur eine Form von Drehgeber ist. Die Elektronik im Servo erledigt den Rest und stellt die Abtriebswelle über das Getriebe auf die gewünschte Position.

pulse

Die obige Grafik zeigt die, wie der Ist-Wert am MG995, oder auch auf anderen gängigen Servos, eingestellt wird. Es ist ersichtlich, dass der Wert über ein 50Hz-Signal eingestellt wird. Für die tatsächliche Positionierung des Winkels wird die Dauer der logisch High und der logsich Low Phase gemessen. Die Grafik macht deutlich, dass 1ms High in der Periodendauer von 20ms einen Winkel von bedeutet. 2ms High korreliert mit 180°.

Kurzer Einfwurf: Ich bin mir nicht sicher, ob das Datenblatt des MG995 einen Fehler hat, oder ob ich doch einen anderen Servo vor mir liegen habe, denn laut Datenblatt sollte dieser nur 120° weit drehen, doch er dreht volle 180°.

Der elektrische Aufbau

Viel bedarf es nicht, lediglich der folgenden paar Bauteile.

Stk. Komponente Ausführung Beschreibung
1 Servo MG995 Antrieb
1 Arduino UNO/Nano Controller
1 Batterie oder Netzteil 6V Versorgung
n Drahtbrücken

Das sind jene Komponenten, um den Servo mit allem zu versorgen, was er benötigt. Das Arduino muss selbst noch mit Spannung versorgt werden. Dies kann entweder über USB oder über den Power-Plug erfolgen.

components

Das Signal, also der Puls, kommt von einem der PWM-Anschlüsse des Boards, dieser kann frei gewählt werden. Neue Servos werden via PPM angesteuert. Wo genau der Unterschied liegt, erkläre etwas weiter unten.

basic_shematic

Sowohl der Ground vom Controller, als auch vom Servo und der Batterien müssen miteinander verbunden sein, da ansonsten die Signalleitung kein gemeinsames Potential hat – der Schaltkreis wäre nicht geschlossen.

Pulsweitenmodulation PWM

Der Grundgedanke war, ein analoges Signal aus einer digitalen Quelle zu bekommen – mit Digital-Analog Umsetzern. Je „schmäler“ der Puls, desto weniger Energie wird über eine Periodendauer frei, die Spannung am Ausgang ist niedrig, und vice versa. Der Grund ist, dass der Controller keine bestimmten Analogwerte am Ausgang liefern kann, sondern nur seine Operationsspannung (hier +5V).

pwm

Beim Servomotor wird allerdings kein analoges Signal genutzt. Die Pulsweite repräsentiert den Winkel am Motor (Beispiel von oben: 1.5ms = 90°). Man sieht, dass die Pulsweitenmodulation also auch Anwendung in der Steuerungstechnik findet. Ein weiteres Beispiel für eine steuerungstechnische Anwendung ist eine LED am PWM Ausgang. Diese wird schnell ein- und ausgeschalten, sodass das Auge dies als konstante Helligkeit wahrnimmt. Je schneller das passiert, desto geringer ist die reusltierende Helligkeit – so kann man das Licht einfach dimmen.

Pulsphasenmodulation PPM

PPM ist eine Erweiterung des PWM-Signals. Dabei werden hintereinander mehrere Pulse in der gleichen 20ms-Periode gesendet. Jeder Puls ist für einen anderen Servo zuständig. Der Vorteil ist klar: Mehrere Motoren können mit nur einer Signalleitung angesteuert werden, ohne dabei Zeit zu verlieren, denn die 20ms-Periode ist ohnehin auch beim „einfachen“ PWM für diese Motoren vorgegeben.

ppm

Der Code

Diesmal gibt es kein GitHub-Repu hierzu, da das Programm sehr kurz ist. Im Grunde zeige ich hier nur die Zusammenfassung des oben beschriebenen Inhalts. Ich zeige auch kein vollständiges Programm, da die Programmbibliothek von Arduino meines Erachtens nach sehr gut ist. Hier findet sich lediglich ein Einblick in den Grundgedanken hinter den Servos.

#define MinAngle 0
#define MaxAngle 180

#define POT 20000
#define MinPWM 1000
#define MaxPWM 2000

#define Multiplier (MaxPWM - MinPWM) / MaxAngle

void setup()
{
    ...
}

void loop()
{
    ...
}
 
void setServo (int Angle)
{
    int PWM = (Angle * Multiplier) + MinPWM;
    PORTD |= _BV(PORTD3);
    delayMicroseconds(PWM);
    PORTD &= ~_BV(PORTD3);
    delayMicroseconds(POT - PWM);
}

Die Definitionen zu Beginn spiegeln lediglich die Eigenschaften des Servos wieder. Der maximale Winkel, den der Servo befahren kann ist zugleich der längste Puls. MaxAngle in Grad entpricht also MaxPWM in Mikrosekunden, ebenso die Min-Werte. Die Periodendauer (Period Of Time [POT]) erhält man ebenso aus dem Datenblatt, bei den meisten Servos ist diese aber 20ms, oder 20000µs.

Der Multiplier ist jener Wert, welcher den gegebenen Winkel zufolge der gegebenen Werte so umrechnet, dass – bei diesem Servotyp – ein Winkel von einem PWM-Signal von 1000ms, und ein Winkel von 180° einem PWM-Signal von 2000ms entspricht. Da die Umrechung keiner Ganzzahldivision entspricht, ist diese mit einem Fehler behaftet.

In der setServo()-Funktion wird zuerst die Dauer des PWM-Signals ermittelt, danach wird für diese Dauer der Ausgang (Pin 3) des Controllers auf HIGH gesetzt. Danach wird die restliche Periodendauer das Signal auf LOW gehalten. Den Zugriff auf den Pin erledige ich nicht mit digitalWrite(Pin, State);, sondern mit dem C-Befehl. Mehr dazu findet man hier.

Durch das Ausführen des restlichen Codes ergibt sich eine Zeitspanne, in welcher die resultierende Periodendauer abweicht. In diesem kurzen Script spielt dies keine tragende Rolle. Sollte das Programm aber länger werden, oder gar Zeitverögernde Funktionen beinhalten, so würde die Periodendauer für die Steuerung des Servos stark abweichen. Abhilfe würde ein Timer schaffen, welcher alle 20ms das PWM-Signal über einen Interrupt triggert.

Diese Grundlogik, und weitere controllerspezifische Absicherungen sind übrigens in der Servo-Library von Arduino enthalten.

Noch eine Anmerkung zum Einschalten des Servos: Wer will, der kann die letzte Position des Servos im EEPROM des Arduinos speichern, sodass er beim Einschalten die Position hält. Das stromlos Schalten des Servos ist im Allgemeinen nicht notwendig, da die Regelung im positionierten Zustand nur wenige Milliampere benötigt.

Das war’s auch schon, ich hoffe, die Idee hinter Servos ist nun klar!

Water Drop (Pro)

Nachdem ich mit Water Drop (Advanced) gute Erfolge im Bereich der Wassertropfenfotografie verbuchen konnte, war es an der Zeit ein neues Projekt zu starten und die Water Drop Reihe etwas zu erweitern. Und so startet hier das neue und bessere Water Drop (Pro).

.

drop_0.JPG

.

Was ist nun der Unterschied zu den beiden Vorgängern, außer das einfallslose Pro hinter dem noch einfallsloserem Water Drop? Nun zum einen nutze ich hier zum ersten Mal Elektromagnetventile, welche über den Mikrocontroller gesteuert werden. Zum anderen arbeitet der Controller nun mit einer Host-Software zusammen, die vorerst nur unter Windows OS läuft. Zusätzlich unterstützt die Software alle gängigen Canon EOS DSLR Modelle, wodurch sich die Einstellung des Fokus, der Blende, der Filmempfindlichkeit sowie der Verschlusszeit vereinfachen soll – man braucht seine Kamera nun nicht mehr anzufassen, um Änderungen vorzunehmen.

Der Umfang der steuerbaren Ventile beläuft sich derzeit auf drei Stück. Zusätzlich arbeite ich noch an ballistischen Ad-Ons, doch bis diese lauffähig sind wird es noch etwas dauern.

Das Projekt ist doch sehr umfangreich, dennoch will ich versuchen, es für alle vollständig nachvollziehbar zu machen, sodass sich jeder, der Tropfen fotografieren will, daran erfreuen kann. Der Aufbau der elektronischen Schaltung benötigt neben Zeit und etwas Geschick beim Löten (falls man sich für die Verwendung einer Platine entschließt) auch etwas mehr an fotografischer Ausrüstung. Doch zu allem später mehr !

Da ich in diesem Blogpost nicht alles unterbringe, was ich unterbringen will, findet man hier alles weitere. In dem Zip-File (so nenne ich es im weiteren Verlauf) sind nicht nur die neuesten Versionen der Software für Host und Controller zu finden, sondern auch die Fertigungspläne für elektrischen und mechanischen Aufbau und ein kleiner Guide für das gesamte Package.

Vorerst möchte ich ein paar Tricks verraten, wie man das Wasser behandeln kann, sodass es sich besser ablichten lässt.

Das Wasser

Wer meinen Beitrag zu Water Drop (Advanced) gelesen hat, dem mögen die folgenden Zeilen vielleicht bekannt sein, denn es hat sich nicht viel geändert.

Die Tropfflüssigkeit, welche von der Düse auf das Wasser trifft, behandle ich auf zwei verschiedene Arten, je nach gewünschtem Ergebnis:

  • Reines Wasser – ergibt starke Spritzer
  • Wasser-Guarkernmehl-Mischung – ergibt gebundenere Formen.

Abgesehen von der Variante filtere ich das Wasser vor jeder Fotosession, um so wenig Verunreinigungen wie möglich im Bild erkennen zu können (der Raum sollte auch sauber sein, da sich ansonsten Staub aus der Umgebung auf der Wasseroberfläche sammeln kann). Als Filter nutze ich einen Sieb, in das ich ein Stück Küchenpapier oder ein Taschentuch lege. Kaffeefilter sind ebenso gut zu verwenden.

Filter.jpg

Die Guarkernmehl-Mischung (etwa ein Teelöffel) bereite ich mit etwa 5cl Weingeist zu. Nach dem Umrühren gibt man das Gemisch in einen sauberen Behälter mit 2 Litern warmen Wasser. Danach muss 15 Minuten stark umgerührt werden, sodass sich das Guarkernmehl im Wasser lösen kann. Dieses Gemisch lasse ich dann abgedeckt ein paar Stunden so stehen.

Guarkern

Die Dichte des Beckenwassers behandle ich nicht. Ich filtriere lediglich reines Leitungswasser, und achte darauf, dass das Becken sauber ist. Als Becken nutze ich alles Mögliche, von Trinkgläsern bis hin zu Pfannen. Je nach Bildausschnitt sollte das Becken bis zum Rand gefüllt werden, sodass man den “Horizont” nicht mehr erkennen kann. Hinter das Becken kann man verschiedenfarbige Platten stellen, um so eine tolle Farbgebung der Szene zu erreichen.

Zuletzt habe ich auch mit destilliertem Wasser experimentiert. Die Ergebnisse auf den Bildern sind identisch mit jenen des normalen Wassers. Ich nutze es lediglich, um das Ventil und die Schläuche zu schonen (Kalkansammlungen). Wer mit höher viskosen Flüssigkeiten seine Bilder macht, der sollte den Aufbau nach der Arbeit auf jeden Fall mit destillieren (oder normalen) Wasser spülen.

Da alles zum Thema Wasser gesagt wurde, kommen wir nun zum nächsten Schritt.

Der mechanische Aufbau

Wie bereits erwähnt unterstützt der Controller bis zu 3 Elektromagnetventile, welche die Wassertropfen erzeugen. Aus finanziellen Mitteln zeige ich die Konstruktion nur mit einem Ventil, doch die Installation der beiden anderen Ventile funktioniert in jeder Hinsicht gleich. Sowohl die Software, als auch die Hardware unterstützen alle drei Ventile – Plug & Play.

Der Rahmen

Als Rahmen nutze ich ein selbst gebautes Gestell, welches so gebaut ist, dass man es einfach zerlegen und platzsparend verstauen kann, denn nicht jeder ist mit viel Platz gesegnet.

Die kompletten Daten, sowie die Pläne für die Fertigung sind unter dem oben genannten Link – ZIP-File – zu finden.

Frame_001.jpg

Das Gestell hat eine Höhe von etwa ein-ein-halb Metern, sodass man es auch auf einen Beistelltisch stellen kann, um nicht immer am Boden sitzen zu müssen. Die Breite ist so gewählt, dass man ein Backblech darunter legen kann, das als Spritzschutz für die Umgebung dient.

Die Montage ist einfach. Die beiden seitlichen Bretter werden mit Flügelschrauben an den horizontalen Staffeln befestigt. In den Staffeln sind Einschraubmuttern eingeschraubt, welche die Verbindung zwischen Holz und Schraube herstellen.

So kann man das Gestell schnell zusammenbauen und wieder zerlegen.

Der Ventilkopf

Hierauf sitzen die Ventile, deshalb habe ich hier bei der Fertigung besonders auf hohe Genauigkeit geachtet. Die Ventile befinden sich alle auf der selben Höhe und lassen sich in ihrer Entfernung zueinander über Langlöcher verstellen. Das Ventil präsentiere ich etwas später im Beitrag.

Frame_003

.

Frame_004

Vom Controller ausgehend lasse ich ein 6-poliges Kabel zum Ventilkopf laufen, welches dort dann in einem Verteiler endet. An diesem können die Ventile separat angeschlossen werden.

Der Wassertank

Eine Ebene höher befindet sich der Wassertank. Jedes Ventil hat seinen eigenen Wassertank, welcher nach dem Mariotteschen Prinzip gebaut wurde. So bleibt der Druck des Wassers auf das Ventil konstant und erlaubt eine immer gleich bleibende Austrittsgeschwindigkeit. Das ist in der Berechnung der Fallzeit in der Software äußerst wichtig!

Frame_005.jpg

Das Prinzip der Flasche ist im Grunde recht einfach. Läuft Wasser unten aus, so erzeugt das schwindende Volumen des Wassers einen niedrigeren Druck der Luft oberhalb. Ist der Druck der Umgebung groß genug, das er sowohl jenen der Flüssigkeit und der Luft in der Flasche überwinden kann, so wird Luft von außen angesaugt. Dies hat die Folge, das der Druck am unteren Ende des Röhrchens immer der konstante Umgebungsdruck ist (solange der Wasserspiegel nicht unter die Öffnung des Röhrchens fällt).

Mariottesche_Bottle_Concept

Das Gehäuse

Das Gehäuse beinhaltet die Platine, auf welcher das Arduino Nano sitzt. Die nötigen Unterlagen für die Fertigung der Platine sind ebenfalls im oben genannten Zip-File zu finden, die Details zum Schaltplan folgen etwas später in diesem Post.

Switchbox_Front

An der Front des Gehäuses findet man einen Display, der den jeweiligen Status anzeigt, den Hauptschalter, einen Reset-Button und drei Buttons, welche die jeweiligen Ventile kurz öffnen. Dies soll die Einrichtung des Fokus der Kamera erleichtern.

Switchbox_Back

Auf der Rückseite sind die Anschlüsse untergebracht. Das System wird über die Spannungsbuchse (links unten) mit 12 VDC versorgt und benötigt mindestens 2 A Strom. Darüber erkennt man die Klinkenbuchse für die Kamera.

ACHTUNG! Die Versorgungsbuchse muss passend zum Netzteil verlötet werden! Wie die Beschaltung am Netzteil ist, findet man am Gerät selbst, diese sieht in etwa so aus:

Connection

Hier erkennt man, dass der Plus-Pin innen liegt, also muss man auch bei der Buchse an den innen liegenden Pin das Kabel für die +12V anlöten.

Neben der Versorgungsbuchse findet man die 4-polige Buchse für das USB-Kabel, über welches der PC mit dem Controller kommuniziert. Die Buchse ist deshalb keine Standard-USB-Buchse, weil ich diese 4-polige „Mikrofonbuchse“ und den passenden Stecker gesamt günstiger erworben habe, als eine USB-Buchse alleine … naja ..

Die beiden anderen Buchsen sind für die Steuerung der Ventile und für den Sensor zuständig. Zur Zeit wird noch kein Sensor in der Software unterstützt, doch das Interface hierfür ist bereits gegeben.

Alle nötigen Bauteile, sowie die Pläne für das Gehäuse sind ebenfalls im Zip-File unter „Mechanical Engineering“ zu finden.

Wem das nötige Werkzeug fehlt, um die Bleche entsprechend bearbeiten zu können, der kann diese durch Kunststoffplatten ersetzen. Diese lassen sich recht passabel mit einer Laubsäge bearbeiten.

Der elektrische Aufbau

Zu Beginn eine kleine Anmerkung: Ich nutze auch bei diesem Projekt wieder einen kleinen Display, dieser dient allerdings nur der Visualisierung der Zustände (Verbunden, Prozess arbeitet, offene Ventile, etc.). Wer darauf verzichten will, der kann auch auf den Display verzichten.

Ich habe folgende Komponenten verbaut:

Die Verdrahtung zeige ich als Steckbrett-Aufbau und als Schaltplan, da es auf dem Steckbrett recht eng geworden ist, und so die Übersicht etwas gelitten hat. Zusätzlich habe ich die Leiterplatte für das Projekt auf meinem Webserver (Zip-File) zur Verfügung gestellt. Darin findet man auch eine Bauteilliste und eine Bauanleitung für die Platine.

Zu den beiden folgenden Bildern muss ich anmerken, dass das System mit 12V gespeist wird, und nicht mit 9V, wie hier dargestellt. Außerdem sind die Ventile hier als Schubbolzen dargestellt. Die Funktion ist aber die selbe.

.

Water_Drop_Pro_Breadboard

.

Water_Drop_Pro_Circuit

.

Hinweis: Wer bereits ein Arduino Uno besitzt, und dieses auch verwenden mag, der hat hier ein leichtes spiel. Da sich im Nano v3.0 und im Uno Rev3 der selbe Prozessor befindet, und auch die Pinbelegung ident ist, kann man das Nano einfach gegen das Uno austauschen, ohne dabei die Pins ändern zu müssen.

Nun erkläre ich die einzelnen Komponenten im Detail.

Komponente Camera

Der Kameraanschluss ist ein einfacher 3.5mm Stereo-Klinkenstecker. Viele Kameras und Blitze unterstützen ein Auslösen mit einem solchen Stecker. Um einen solchen zu bauen, braucht man folgende Komponenten:

  • 3.5mm Stereo-Klinkenstecker
  • 2.5mm zu 3.5mm Adatperkabel
  • 3.5mm Stereo-Kabel (Male-Male)

Audio_Jack_Real_Image

Die Verdrahtung zwischen Optokoppler und Klinkenstecker muss so ausgeführt sein, dass das Gehäuse (SLEEVE) des Steckers mit dem Emitter des Kopplers verbunden ist. Der Kollektor des Optokopplers muss mit dem Left-Pin des Steckers verbunden werden, da dieser für das Auslösen der Kamera zuständig ist. Mit Right-Pin kann man den Autofokus betätigen.

Audio_Jack_Shematic

Pin 1 des Optokopplers ist die Anode (+) und Pin 2 ist die Kathode (-). Wenn sich nun jemand fragt, warum ich hierfür einen Optokoppler verwende: Keeps you from frying your stuff!

Das Arduino gibt durch den digitalWrite()-Befehl 5V am entsprechenden Pin aus. Diese 5V könnten an der Kamera Schäden verursachen, deshalb muss man etwas zur Sicherheit zwischenschalten. Diese Sicherheit ist der Optokoppler, er ist von der Funktion her vergleichbar mit einem Relais, jedoch ist die Schaltzeit wesentlich kürzer – also perfekt für solche Anwendungen! Wer sich unsicher ist, wo sich die Kontakte des Optokopplers befinden: Datenblatt!

Mehr dazu findet man hier.

Komponente Elektromagnetventil

Die Elektromagnetventile habe ich bei diesem Shop erworben (Spannung 12 V, Leistung 5 W). Zusätzlich habe ich mir noch 2 Schlauchtüllen (Schlauchgröße 6 mm) dazu bestellt, um das Ganze abzurunden.

Valve_G1_8.jpg

Das Magnetventil arbeitet mit einer Gleichspannung von 12V, das Arduino jedoch mit 5V. Aus diesem Grund braucht man eine Transistorschaltung, um mit dem Arduino das Ventil öffnen und schließen zu können.

Ein Transistor ist im Grunde ein Schalter, welcher elektronisch geöffnet und geschlossen wird. Wer mehr darüber wissen mag -> Transistorschaltung.

Transistor_Circuit.jpg

Der Ground (-) muss vom Signalgeber und vom Ventil der selbe sein, damit die Schaltung funktionieren kann. Ich habe zusätzlich die 12V direkt an den Vin-Pin des Arduinos gehängt, so wird dieses auch gleich von dem Netzteil versorgt.

Die Gleichrichterdiode 1N4001 dient als Schutz für die Bauteile, da es durchaus vorkommen kann, dass es wegen der Spule im Ventil zu einem Rückschlag kommen kann.

Das Ventil hat eine Leistung von 5 Watt und benötigt 12 VDC Spannung. Mit dem Zusammenhang P = U * I ergibt sich für den Strom 0,41667 Ampere. Um 3 Ventile gleichzeitig zu nutzen, und das Arduino Nano/Uno mit ausreichend Strom zu versorgen (max. 200mA in Summe an den Ausgängen) rate ich zu einem 2A Netzteil. Ich habe mir ein kleines Netzteil aus China zugelegt, welches bis zu 8 Ampere liefern kann. Die Schaltung benötigt natürlich nie so viel Strom, doch das Netzteil war außerordentlich günstig (6,50 €, kostenloser Versand).

Die Schaltung kann nun nicht mehr mit einem USB-Akku-Pack genutzt werden, wie es zum Beispiel bei Water Drop (Advanced) zum Einsatz kommt, da diese Akkus-Packs nur 5V liefern. Eine ausreichend starke 12V Batterie würde hier funktionieren, doch ich nutze lieber das Netz, da das Projekt ohnehin nicht portabel sein muss.

Komponente Display (optional)

Display_Real_Image

Bei dem Display handelt es sich um einen 0,96″ OLED Display, welcher mit dem BUS-System I²C angesteuert wird. Das Arduino Nano unterstützt dies, indem man die Library Wire.h implementiert. Dann sind allerdings die beiden Pins A4 & A5 für eben diese Übertragung reserviert und können nicht mehr für andere Zwecke verwendet werden. Wichtig ist hier, dass die Verbindung des Displays mit dem Arduino folgendermaßen ausgeführt wird:

  • SDA ⇒ A4
  • SCL ⇒ A5
  • VCC ⇒ 5V
  • GND ⇒ Ground

Um auch tatsächlich etwas auf dem Display anzeigen zu können bedarf es einer eigenen Programmbibliothek. Ich habe für diesen Zweck eine einfache Bibliothek erstellt. Die Erklärung und Verwendung findet man hier. Die Beschreibung des Codes findet man etwas weiter unten im Beitrag!

Die Platine

Um alles sauber abzuschließen habe ich eine Leiterplatte entworfen, auf welcher alle Komponenten sitzen. Die Kabel von den Buttons, dem Display, der Steckerbuchsen, etc … werden einfach über Terminal-Blocks mit der PCB verbunden. Das Bild unten zeigt die Platine, geroutet in Fritzing. Die Datei findet ihr natürlich auch im oben genannten Package.

Water_Drop_Pro_Finale_Without_Copper_Fill.jpg

.

Raw_Circuit_Board

Für die Platine benötigt man zumindest halb-schlechte Fähigkeiten im Löten. Das Arduino und der Optokoppler sitzen beide auf für diese passende Sockel, um sie einfach austauschbar zu machen. Alle Bauteile findet man natürlich im ZIP-File.

Fertig bestückt ist die Platine bereit für das Verlöten.

Circuit_Board

Beim Einsetzen des Optokopplers sollte man besonders auf den Punkt dessen Gehäuse achten, dieser muss sich dort befinden, so sich im Fritzing-File (Skizze oben) der Stern (*) befindet. Oder anders gesagt: Der Punkt definiert die Position der Anode des ersten Optokoppler im Gehäuse.

Optocoupler_Detail

Die Platine selbst habe ich hier bestellt. Das Preis-Leistungsverhältnis ist unschlagbar (unter 20€ für die Platine + Versand nach Österreich). Es reicht völlig, einfach nur das PDF zu senden, und folgendes anzugeben:

  • Die 4 äußeren Bohrungen: D3.2mm
  • Alle anderen Bohrungen: D1.0mm

Der Code

Eines vorweg: Das Programm wurde in Sublime Text 3 ( Stino ) mit der Arduino IDE 1.6.6 geschrieben.

Sowohl das Programm für den Mikrocontroller, als auch das Programm für den PC sind auf GitHub zu finden. Wer auf Nummer sicher gehen will, kann sich natürlich das Programm durchlesen/durchdenken, bevor es ausgeführt wird.

Wem den Weg über GitHub zu Steinig ist, der findet im ZIP-File ebenfalls beide Programme und eine ausführliche Beschreibung für jedes.

Der Mikrocontroller

Wie bereits oben erwähnt, nutze ich das Arduino Nano v3.0 und habe das Programm auch mehrfach auf diesem getestet. Natürlich kann man auch das Arduino UNO nutzen, da beide Boards den gleichen Prozessor (ATmega328) nutzen.

Arduino_Nano.jpg

Wer neu ist, und sich nicht sicher im Umgang mit dem Arduino ist, der kann sich hier einmal einlesen. Für alle, die schon vertraut mit der Umgebung sind: Einfach auf den Controller hochladen & fertig. Das Programm ist in mehrere Files gesplittet. Um alles auf einmal zu öffnen öffnet ihr nur die Water_Drop_Pro.ino Datei. Die Arduino-Software lädt dann automatisch alle im Verzeichnis befindlichen Dateien automatisch nach.

Ich erstelle gelegentlich Updates für das Programm, um eventuelle Bugs zu fixen, oder einfach um Funktionen einfacher zu machen. Daher sollte man öfter mal auf Github vorbei schauen – aus Selbsterfahrung weis ich: macht man im Allgemeinen nicht.

Der Host

Oben habe ich schon darauf verwiesen, das die Host-Software nur unter Windows läuft. Wie kann man das nur machen? Meine Ausrede ist, dass ich keine Lust hatte, ein GUI mit Pyhon oder Java zu schreiben. Ich habe den einfachen Aufbau von Visual Studio C# genutzt, um den grafischen Aspekt der Software schnell und einfach zu erstellen.

Host_Software_Mask

Das Nachfolgerprojekt soll dann aber Plattformübergreifend sein, bis dahin dauert es aber noch (eventuell, dass es Sommer 2016 beginnt).

Wer dennoch das Programm unter Mac nutzen will, der bekommt hier ein paar Möglichkeiten gezeigt. Leider kann ich aufgrund des Fehlens eines Macs nicht sagen, ob die Software dann auch tatsächlich reibungsfrei läuft.

Die Software unterstützt zudem alle Canon EOS DSLR Kameras. Dies hat den großen Vorteil, das man die Kamera für das Setzen der Einstellungen nicht mehr berühren muss und so unter Umständen den Bildausschnitt kaputt macht. Nikon, Sony, Pentax oder ähnliche Kameras unterstützt die Software nicht, da ich zur Zeit noch an einer neueren Version arbeite, welche alle anderen gängigen Marken unterstützt. Wer keine Canon hat muss sich leider vorerst ohne dieses Feature zufrieden geben.

Live_View

Ein besonderes Plus ist der Live-View, mit dem man den Fokuspunkt exakt einstellen kann.

Host & Controller

Hier mal eine einfache Anleitung für den Vorgang:

  • Anschließen des Arduino (mit bereits geladenem Code) an den PC.
  • Starten der Software am PC und auswählen des COM-Ports mit anschließendem Verbinden.
  • Warten, bis beide Geräte verbunden sind.
  • Done. Jetzt können die Ventile mit dem PC gesteuert werden.
Auf der linken Seite in der Software muss man beim ersten Mal benutzen die Höhe zwischen Ventilauslass und Wasseroberfläche einstellen. Danach wird automatisch die nötige Zeit berechnet, die der Tropfen vom Auslass bis zum Wasser braucht. Diese Dauer ist zudem jene für die Kamera, ist sie abgelaufen, dann löst die Kamera aus.
Host_Software_Mask_Height
.
Die Startzeiten für die Ventile sind an Punkt 0 gebunden. Dies bedeutet, dass eine Startzeit für das Ventil kürzer sein muss, als die Zeit für die Kamera, ansonsten würde ja das Ventil erst öffnen, nachdem die Kamera ausgelöst hat – das ist nicht Zweckdienlich!
.
Um die Verbindung zu trennen sollte man immer auf den Button „Disconnect“ klicken. Dies hat zwar was von „USB-Stick sicher entfernen„, doch es gibt am Arduino Nano/UNO keine Möglichkeit zu erkennen, ob ein Gerät verbunden ist oder nicht. So muss man ihm immer brav den Trennen-Befehl senden, sodass das nächste mal Koppeln gut geht.
Oder man drückt den Reset-Knopf – brute force!
.
Alles Weitere findet man im ZIP-File.
.

Die Vorgehensweise

Nun verrate ich noch ein paar Tricks, wie ich meine Bilder mache. Zuerst möchte ich aber auf meine Ausrüstung eingehen.

  • Canon EOS 650D Spiegelreflexkamera
  • Canon 100mm f/2.8 Macro Objektiv
  • Cullmann Stativ (mit Wechselplatte)
  • Yongnuo 560 III Blitz (kein TTL)
  • Yongnuo RF-602/C Funkauslöser (Entfesselter Blitz)
Das ist meiner Meinung nach die „Mindestausstattung“. Mir ist klar, dass das alles viel Geld kostet, ich habe es mir schließlich selbst über Jahre hinweg zusammengespart. Wer ein ähnliches Sortiment zu Hause hat, der ist gut gewappnet!
.
Equipment.JPG
 .
Zusätzlich empfehle ich noch einen Makroschlitten. Das vereinfacht das feine Positionieren enorm, da man mit dem Festbrennweitenobjektiv doch sehr eingeschränkt ist.
.
Ein sehr gutes Resümee zum Blitz gibt es hier.
.
Zu Beginn jedes Shootings sollte man das Ventil so lange offen lassen, bis Wasser unten austritt. Wenn man es dann schließt ist sicher gestellt, dass beim nächsten Öffnen sofort ein Tropfen austritt.
.
Zum Schluss jedes Shootings sollte man das Ventil unbedingt säubern, um die Lebensdauer so hoch wie möglich zu halten.
 .
Der Fokus
 .
Die beste und zugleich einfachste Methode den Fokus der Kamera einzustellen ist, einen Stab oder ein ähnliches Ding dort hinzulegen, wo später der Tropfen im Bild sein soll. Um sicherzustellen, dass der Tropfen auch tatsächlich dort landet wo man will, habe ich an die Front der Steuerbox die Buttons für die drei Ventile gesetzt. So kann man gezielt nur einen Tropfen fallen lassen. Diesen lasse ich dann auf ein einen Holzstab fallen, an dessen Mitte eine Markierung ist.
..
Setup_02
.
Im Anschluss muss man nur noch die markierte Stelle des Stabes fokussieren. Dies kann man entweder über den LiveView der Kamera oder über die Host-Software erledigen.
.
Focus_01.JPG
.
 Focus_02.JPG
 .
Die Position
 .
Eine perfekte Position für die Kamera und den Blitz gibt es nicht. Jede Session wird anders laufen, jede Veränderung der Viskosität der Tropfflüssigkeit bewirkt andere Tropfen und jede Positionsänderung des Blitzes sorgt für eine andere Stimmung. Eines kann ich allerdings bestimmt sagen: Den Blitz nicht auf der Kamera montieren. Irgendwie wirkt das Bild dann nicht.
.
Setup_01
.
 
Die Wassertropfenfotografie ist zu Beginn eher try & error, bis man ein Gespür für die Vorgänge entwickelt und immer mehr probiert. Nur nicht entmutigen lassen!
 .
Der Vorgang
 .
Hier ist eigentlich alles straight forward. Einfach den Host mit dem Controller verbinden, die Zeiten für die Ventile einstellen, die Auslöseverzögerung festlegen und auf Start drücken. Falls die Aufnahme nicht so wird wie gewünscht, einfach an die Zeitdauer einzelner Punkte anpassen, bis alles sitzt.
Bei immer gleichen Parametern sollten auch immer gleiche Tropfen entstehen. Bedingt durch die Flüssigkeit kommt es allerdings recht oft vor, dass ich an unterschiedlichen Tagen auch unterschiedliche Tropfen bekomme (trotz gleicher Settings in der Software). Hin und wieder passieren auch während eines Shootings random Dinge, doch das ist eher die Ausnahme. Ich denke, das liegt vielleicht an lokalen Dichteunterschieden oder sich ändernden Adhäsionskräften zwischen Düse und Fluid. Sicher kann ich das jedoch nicht sagen.

Das Ergebnis

Zum Schluss gibt’s noch ein paar Bilder, die ich mit dem System gemacht habe.

Ich hoffe ich habe nichts ausgelassen, und alle Fragen auch beantwortet. Falls dennoch Fragen offen sind, oder jemand generell ein paar Gedanken zu meinem Projekt hat: Ein Kommentar ist immer erwünscht!