360° Panorama

English version.

In einem früheren Beitrag habe ich gezeigt, wie man ein großes Panorama erstellt, und dieses dann im Web vorstellt. Nun gehe ich einen Schritt weiter und erstelle ein 360° Kugelpanorama.

Die Bilder

Um ein Panorama dieser Art zu erstellen braucht man natürlich vernünftige Bilder. Dabei muss man ein paar Dinge beachten, damit man später bei der Verarbeitung nicht in Arbeit untergeht (Stiching-Fehler). Gute Aufnahmen sind hier tatsächlich ein absolutes Muss, vor allem in Innenräumen, da die Abstände der Motive zur Kamera stark variieren. Es sei denn man steht in einem leeren Raum mit quadratischer Grundfläche.

Das Objektiv und die Aufnahmen

Das Objektiv erster Wahl ist hier das Sigma 8-16mm Superweitwinkelobjektiv.

lens

Bei einem Bildwinkel von 121,2° (bei 8mm Brennweite) erlaubt es ein 360° Panorama mit nur 4 Aufnahmen zu erstellen. Wer ein anderes Objektiv nutzt kann die mindestens nötige Anzahl entweder durch probieren herausfinden, oder man hohlt sich einfach eine App.

app

Sollte man sich allerdings an einem Ort befinden, an dem man nicht mehr so schnell zurückkommt, dann lohnt es sich, mehr Aufnahmen als besagte Mindestgrenze zu machen. Besser zu viel als zu wenig. Meistens mache ich gesamt 10 Aufnahmen, sechs im Hochformat um die Hochachse der Kamera, zwei Zenitaufnahmen und zwei Nadiraufnahmen – in genau dieser Reihenfolge.

Die sechs Bilder um die Hochachse überschneiden sich bei mir immer etwas, sodass sich das Stitchen bei etwaigen Aufnahmefehlern leichter bewältigen lässt.

Die Zenitaufnahme zeigt nach oben. In den meisten Fällen, sofern man sich draußen befindet, sieht man hier nur Wolken. Die erste Aufnahme zeigt einfach nach oben, die zweite erstelle ich 180° in der Objektivachseachse gedreht. Warum zuerst Zenit? Meistens sind Wolken in Bewegung – daraum sollte man zuerst die Bilder des bewegten Himmels machen, als vom als statischen zu betrachtenden Boden.

Die Nadiraufnahme ist das Pendant zur Zenitaufnahme – sie zeigt nach unten. Hier macht das Stativ gerne mal Probleme, da seine Beine dann am Bild zu sehen sind. Abhilfe schafft hier wieder die zweite, um 180° gedrehte Aufnahme, wodurch sich das spätere Entfernen der Beine am PC ziemlich einfach gestalltet. Als Notlösung (wer Photoshop nicht mag) kann man mit ausgestreckter Hand die beiden Aufnahmen machen, dabei muss man aber auf die Verwackelungsunschärfe achten!

Weil ich das Stativ erwähnt habe: Am besten werden die Bilder wenn die Kamera auf einem Stativ montiert ist, genauer: Mit einem Nodalpunktadapter.

Der Nodalpunkt

Der Nodalpunk ist jener „Punkt“ in welchem sich alle Lichtstrahlen vor und hinter der Linse kreuzen würden. Das bedeutet also, wenn man die Kamera um ihre Hochachse um den Nodalpunkt dreht fallen alle Lichtstrahlen aller umliegenden Objekte in diesem Punkt zusammen. Nur so erreicht man, dass beim Drehen der Kamera keine Tiefenfehler entstehen und das Bild später beim Stichen fehlerfrei zusammengefügt werden kann.

Um die Kamera auch richtig auf dem Adapter platzieren zu können muss man den Abstand des Nodalpunktes zur Stativschraube kennen. Dazu gibt es hier passende und gut beschriebene Tabellen.

Wer keinen Nodalpunktabadpter hat, der kann zumindest im Freien (große, weite Flächen) freihand arbeiten. Dabei entstehen zwar immer ein paar Fehler beim Stitchen, mit etwas Geduld kann man diese jedoch später in Photoshop retuschieren. Wer es trotz fehlendem Adapter ganz geanu nehmen mag: Einfach ein Stück Schnur am Objektiv auf der Höhe des Nodalpunktes befestigen. Am anderen Ende etwas schweres befestigen (eventuell ein kleiner Stein), damit die Schnur gespannt ist. Dann muss man sich nur noch „um die Schnur drehen“, darauf achtend, dass der Stein auf seiner Position liegen bleibt und die Schnur auch wirklich senkrecht nach unten hängt.

cord

Die Kamerasettings

Kurz und bündig: Manueller Modus, konstante Belichtungszeit, konstante Blende, konstanter ISO-Wert, konstante Brennweite.

Die Brennweite sollte so kurz wie möglich gehalten werden, in meinem Fall also 8mm. Die Belichtungszeit ist abhängig von der Umgebung, sie ist der variable Part der 4 Paramter. Ebenso variabel, allerdings zu Gunsten der Bildqualität niedrig zu halten ist der ISO-Wert. Die Blende sollte so weit offen sein, dass die Schärfentiefe in jeder Bildebene gleich hoch ist.
Ein guter Richtwert bei 8mm ist f/12 bis f/16. Zu klein sollte die Blendenöffnung nicht sein, da sonst die Lichtstrahlen zu stark gebeugt werden, was zu einer Unschärfe führt.

Über den „Schärfebereich“ gibt die hyperfokale Distanz auskunft, für welche es ebenso Apps gibt. Der Fokus sollte so gewählt werden, dass die hyperfokale Distanz dem Abstand zwischen Kamera und nächstgelegenen Objekt entspricht.

Das Histogramm

Das Histogram ist bei 360° Panoramas (oder eigentlich generell) eines der besten Hilfswerkzeuge in der digitalen Fotografie. Es gibt Auskunft über die Anzahl der Pixel zu einem gewissen Helligkeitsbereich. Der linke Rand im Histogram zeigt die Anzahl an rein schwarzen Pixel, der rechte Rand die Anzahl rein weißer Pixel. Dazwischen liegen alle Graustufen. Das folgende Bild zeigt die beiden Extrema und mittleres Grau.

histogram_description_1

Das Histogramm des Teelöffels zeigt recht gut was ich meine. Es sind sehr viele helle Grautöne vorhanden, deshalb liegt der Schwerpunkt auch im rechten Bereich. Ganz links und ganz rechts sind hohe Spitzen erkennbar.

histogram_description_2

Diese hohen Spitzen sind sehr schlecht, da sie keine Informationen mehr enthalten – es ist im Bild an diesen Stellen nur mehr pures Schwarz oder Weis. Für das spätere Bearbeiten ist das eine Katastrophe (ja, es ist wirklich so schlimm).

Deshalb achte ich Aufnahmen immer darauf, innerhalb der beiden Grenzen zu liegen, so wie ich es bei einem der 10 Bilder für das Panorama gemacht habe:

histogram

Hier kommt nun der schwierige Part: Alle Bilder des Panoramas müssen innerhalb der Grenzen liegen, damit keine Bildinformation verloren geht. Dazu ein Tipp: Ein Bild vom Himmel (Zenit) machen, die Belichtungsdauer entsprechend korrigieren, dann ein Bild vom Boden (Nadir) machen und schauen, ob noch alles im grünen Bereich ist. Wenn nicht: Nachkorrigieren.
Generell gilt, dass digitale Kameras wesentlich besser mit dunklen Tönen umgehen können als mit hellen. Deshalb lieber alles etwas dunkler Fotografieren, sodass nichts an den rechten Rand des Histograms rutscht. Beim späteren Bearbeiten kann man dann einfach die zu dunklen Stellen heller machen.
Fotografiert wird natürlich im RAW Format!

Das Stitchen

Sind die Bilder im Kasten kann man sie mit ICE von Microsoft zusammenfügen. Der Editor ist kostenlos und unter allen bisher von mir getesteten mein Favorit.

Als Projektion muss man Spherical wählen, nur so erstellt ICE aus dem Panorama die gewünschte Rektangularprojektion.

ice_projection

Am Ende sollte das Resultat dann so zirka so aussehen, wobei ich die Breite des Bildes meist auf 5000 Pixel setze – die Höhe muss dann die halbe Breite sein, da ein 360° Panorama in seiner Höhe mit 180° beschränkt ist. Sollte das nicht der Fall sein, dann fehlen Bilder – ICE kann dann keine volle Kugeloberfläche erstellen.

ice

three.js

Nun da das Bild endlich fertig ist, muss man es auch irgendwo anzeigen. Und wo geht das besser als im Web? Hierzu nutze ich three.js

Auf GitHub findet man alles nötige. Im Ordner 360_Panorama befindet sich das index.html und die nötigen Java Scripte, außerdem auch das Bild (area.jpg). Achtung! Wer die index.html Datei lokal öffnet wird zunächst nichts sehen, außer einen schwarzen Bildschirm, der Grund ist, dass 3D-Figuren lokal nicht angezeigt werden. Einige Tipps wie man das umgeht findet man hier.
Da man das Ganze aber ohnehin online stellen will kann man den Ordner 360_Panorama auch gleich auf seinen Webspace kopieren, und diesen dann ansurfen.

Kostenlose Webspaces gibt es wie Sand am Meer, ich habe, bevor ich mir eine eigene Domain mit Webspace zugelegt habe, bplaced genutzt. Einfach anmelden, den Ordner hochladen und mit yourname.bplaced.net/360_panorama/ online ansehen.

Im index.html befindet sich das Script, welches alle nötigen Aufgaben für das Anzeigen des Bildes übernimmt (Kugel erstellen, Kamera in die Kugel setzen, Bild auf die Innenseite projizieren, Rendern starten, Mausbefehle abfangen). Hierfür gibt es eine guteDokumentation. Ich habe eingestellt, dass sich die Kugel langsam drehen soll, wem das nicht gefällt, der kann dies mit controls.autoRotate = false; ändern.

controls.noPan = true;
controls.noZoom = true; 
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;

Das Bild wird, wie bereits erwähnt, auf die Innenseite der Kugel projiziert. Nun erklärt sich auch, warum man in ICE eine Rektangularprojektion erzeugt. Betrachtet man ein „normales“ Bild in 2D, so sieht dieses so aus:

grid_small

In 3D wird daraus jedoch das hier. (Leider unterstützt WordPress wegen Sicherheitsrichtlinien keine iFrames. Den Beitrag gibt’s flawless hier zu sehen)

Das Ergebnis

Hat man alles zusammen, so präsentiert sich am Ende ein 360° Panorama, das man hier interaktiv steuern kann!

Das war’s auch schon.

.

.

 

Online 2.1

Falls es jemanden aufgefallen ist, ich war längere Zeit nicht auf WordPress unterwegs. Das liegt daran, dass ich meine Website nun mit einer ordentlichen Domain betreibe (und im Urlaub war).

deloarts.com

Wer den Beitrag zu Online 2.0 gelesen hat, und sich dadurch auf die alte Website verirrt hat, dem wird auffallen, dass sich das Design nicht wirklich geändert hat.

preview.PNG

Was sich aber geändert hat, ist wie ich die Website nun erstelle. Die Website wird nun automatisch erstellt, ich definiere nur noch in den Content-html-Files, was ich auf der Seite sehen will, den Rest (Inhalt auf ein Base-File führen, alles vereinheitlichen, alles vereinfachen, etc…) erledigt Gulp. Hier läuft dann ein Server auf meinem PC, auf welchem ich ganz einfach die Website lokal betrachten kann.

Weiters kann ich mit Gulp-Watch das Verzeichnis, in dem die Website liegt, überwachen lassen, und bei Änderungen im Verzeichnis werden alle Vorgänge (Base-File, vereinheitlichen, …) automatisch ausgeführt, sowie der Browser aktualisiert. Kurz: Ich speichere das html-File in Sublime Text und einen Augenblick später sehe ich die Änderungen im Browser.

Die Domain habe ich mir bei world4you gehohlt, und der Webspace liegt nun bei uberspace, und nicht mehr bei bplaced.

Alles andere, also die Zweisprachigkeit, der Inhalt und der Support für mobile Geräte ist gleich geblieben.

2 Devices

Lediglich das Design bei Desktop-Nutzern hat sich verändert, da ich gesehen habe, zu was CSS3-Transformationen fähig sind! Auf mobilen Geräten ist das leider nicht verfügbar, da man keine Maus hat, mit der man das :hover-Event triggern könnte.

Bleibt nur noch eins zu sagen: Einen großen Dank an ralphharrer.at, er hat mir einen Einblick in die Web-Entwicklung gewährt und mich bei meinem Vorhaben unterstützt.

Arduino & ATtiny85

English version.

In diesem kurzen Beitrag zeige ich, wie man das Arduino als Programmer für den ATtiny85 Mikrocontroller nutzt.

Preview

Arduino IDE vorbereiten

Benötigt wird hierfür zunächst nur das Arduino Uno.

Arduino als ISP konfigurieren.

Als nächstes Öffnet man ArduinoISP (File, Examples, ArduinoISP) und lädt dieses Programm auf das Arduino Uno. Achtung, als Board muss hier das Arduino Uno ausgewählt sein.

ATtiny als Board hinzufügen.

Damit man das Arduino als ISP nutzen kann muss man zunächst den ATtiny in die IDE importieren. Dazu öffnet man die Preferences (File, Preferences) und klickt auf das Icon ganz rechts neben Additional Boards Manager URLs.

Preferences.JPG

Daraufhin öffnet sich ein weiteres Fenster, in welches man folgenden Link kopieren muss.

http://drazzy.com/package_drazzy.com_index.json

Additional_Boards.JPG

Im Anschluss öffnet man den Board Manager 

Boardmanager0.JPG

… und fügt das nötige Modul hinzu. In diesem Fall das ATtinyCore by Spence Konde.

Boardmanager1.JPG

Ist das erledigt kann man das ATtiny im Board Manager auswählen …

Boardmanager2.JPG

… und es im Anschluss konfigurieren.

Boardmanager3.JPG

Man muss darauf achten, alle Einstellungen mit meinen abzugleichen. Also den Timer auf CPU, den Chip auf ATtiny85 und die Clock auf 8MHz setzen.

Danach stellt man sicher, dass der Programmer auf Arduino als ISP eingestellt ist.

Arduino_As_ISP.JPG

Der Setup

Als nächstes folgt der physische Aufbau. Dazu benötigt man die folgenden Bauteile:

  • 1 Arduino Uno
  • 1 ATtiny85
  • 1 10µF Kondensator

Die Pins des ATtiny kann man mit Hilfe der folgenden Abbildung und der Wiring-Tabelle mit dem Arduino Uno verbinden.

ATtiny85_Pinout.png

  • Vcc: +5V
  • GND: GND
  • Reset: Pin 10
  • Pin 0: Pin 11
  • Pin 1: Pin 12
  • Pin 2: Pin 13

ATtiny85_Steckplatine.png

Burn Bootloader

Nun kann man das Arduino wieder mit dem PC verbinden und den Bootloader für den ATtiny auf diesen schreiben.

Burn_Bootloader.JPG

Nun kann man den ATtiny mit der Arduino IDE programmieren.

Programme hochladen

Als kleines Beispiel habe ich ein Programm vorbereitet, das eine LED blinken lässt. Abhängig von dem Status eines Tasters ändert sich die Blinkgeschwindigkeit. Der Aufbau muss dabei um

  • 1 LED
  • 1 220Ω Widerstand für die LED
  • 1 Pushbutton
  • 1 10kΩ Widerstand für den Button

ergänzt werden.

ATtiny85_Steckplatine1.png

Als nächsten Schritt fügt man das folgende Programm in die Arduino IDE ein und lädt es auf das ATtiny85 via dem Arduino Uno hoch.

#define LED 0
#define BUTTON 1

word Delay = 1000;

void setup() 
{
 pinMode(LED, OUTPUT);
 pinMode(BUTTON, INPUT);
}

void loop() 
{
 digitalRead(BUTTON) ? Delay = 250 : Delay = 1000;
 digitalWrite(0, HIGH);
 delay(Delay);
 digitalWrite(0, LOW);
 delay(Delay);
}

Das ganze sieht fertig dann etwa so aus:

Setup.jpg

Zum Schluss kann man noch alle Kabel, die zum Arduino führen, und den Kondensator entfernen, und eine Spannungsversorgung im Bereich von 3V bis 5V herstellen. Die 3V erreicht man beispielsweise durch 2 Batterien des Typs AA. Dann muss man allerdings den 220Ω Widerstand durch eine Drahtbrücke ersetzen.

Bei Fragen dazu, oder falls etwas nicht so funktioniert, wie es soll: Ein Kommentar ist immer erwünscht!

 

 

Water Drop (Pro) – Sensor Add-On

English version.

Wie ich es bereits im Water Drop (Pro) Beitrag (diesen sollte man zuerst lesen) angekündigt habe folgt hier das Sensor Add-On. Da die Hardware der Pro-Version bereits für einen Sensor ausgelegt ist, waren nur noch kleinere Änderungen in der Software zu erledigen und ein funktionierender Sensor zu bauen. Wer den Beitrag über die Advanced-Version gelesen hat, der wird bereits einen Verdacht haben, was nun folgt. Die Idee des Sensors beruht nämlich auf der selben wie in der älteren Version der Water Drop Reihe – einer Laserlichtschranke.

Um auch alles Zusatzmaterial auf einmal zu bekommen, habe ich das Projektverzeichnis auf dem Webserver aktualisiert. Die neuen Dateien können hier heruntergeladen werden.

Der Sensor

Für eine Laserlichtschranke braucht man einen Sender und einen Empfänger. Da ich keine Reflexlichtschranke baue sind beide Geräte in unterschiedlichen Gehäusen verbaut. Als Sender nutze ich einen alten Laserpointer, aus dem ich die Batterien entfernt habe, und diese durch zwei Kabel ersetzt habe.

Sensor_Laserpointer.jpg

Der Laserpointer benötigt 3V Spannung und 15mA Strom. Deshalb kann ich ihn direkt mit einem digitalen Output-Pin des Arduinos (max. 40mA) betreiben. Wer einen Laserpointer mit mehr Leistung nutzen will, der muss, um das Arduino nicht zu zerstören, ein Relais oder einen Transistor zwischenschalten. Der Kabelbinder am Gehäuse dient dazu, den Schalter permanent gedrückt zu halten. Wem das stört, der kann auch das Gehäuse öffnen und die Kontakte des Schalters gemeinsam verlöten.

Da der Laserpointer mit 3V arbeitet, das Arduino jedoch 5V ausgibt, benötigt man zusätzlich einen Spannungsteiler (im Grunde die einfache Variante des Logic Level Shifters).

Spannungsteiler_Sensor

Als Empfänger nutze ich einen Phototransistor (620-960nm). Dieser sitzt in einem anderen Gehäuse, doch das Gesamtpaket wird nur mit einem Kabel mit der Switchbox verbunden. Der Schaltplan unten zeigt das gesamte System, für welches ich die folgenden Komponenten verbaut habe:

  • 1 1kΩ Widerstand für den Spannungsteiler
  • 1 2.2kΩ Widerstand für den Spannungsteiler
  • 1 10kΩ Pull-Down Widerstand für den Phototransistor
  • 1 Phototransistor (620-960nm) (BPW 16N oder ähnlich)
  • 1 alten Laserpointer mit rotem Licht (Hier als LED dargestellt)

Water_Drop_Pro_Sensor_Shematic

Achtung, ich nutze einen Laserpointer mit rotem Licht! Falls jemand einen mit grünen Licht nutzen will, so muss er auch den Phototransistor dementsprechend anpassen, da dieser hier nur auf rotes Licht reagiert! Um die Auswahl des Phototransistors zu erleichtern, gibt es hier eine gute Tabelle.

Der Sensor Jack ist ein einfacher 5-poliger Mikrofonstecker, der an die passende Buchse an der Switchbox gesteckt werden kann. Man kann natürlich auch die beiden GND-Leitungen zusammenfassen, da sie an der Platine sowieso am selben Pin landen, doch dann würde es an der Switchbox zwei 4-polige Buchsen geben, was zu einer Verwechslung führen könnte, und so Schäden am Gerät verursachen würde.

Switchbox_Sensor_Interface

Der Stecker wird direkt mit den passende Terminal-Block-Pins an der Platine verbunden. Man muss dann nur noch darauf achten, am anderen Ende des Steckers auch die richtigen Kabel mit dem Phototransistor oder dem Laserpointer zu verbinden. Hierfür nutze ich den akustischen Diodenprüfer eines Multimeters.

Sensor_Pinout_Real.jpg

Achtung, wer hier unachtsam ist könnte einen Kurzschluss verursachen. Also lieber alles zweimal prüfen!

Zur Sicherheit sollte man das Fritzing-File im Projektverzeichnis (der Link am Beginn des Beitrags) zu Rate ziehen.

Fritzing_Sensor

Das Gehäuse des Phototransistors ist ein kleines, günstiges Kunststoffgehäuse. Ich habe drei Bohrungen angebracht:

  • Die Bohrung für das 5-polige Kabel von der Switchbox
  • Eine kleinere Bohrung für das 2-polige Versorgungskabel des Lasers
  • Eine Bohrung als Öffnung für den Laser

Der Rahmen

Um den Rahmen der Pro-Version nur gering umzubauen, habe ich mich für die einfachste Variante entschieden den Sensor zu montieren: Ein dünnes Brett wird an den mittleren Balken geschraubt. So muss man nichts weiteres tun, als zwei Bohrungen (D=12mm) in den Balken zu bohren, und darin jeweils eine Gewindemutter (M8) zu fixieren. So kann man später das Brett einfach mit zwei M8-Flügelschrauben befestigen.

Frame_006.jpg

Das Brett kann man gestallten wie man es gerne möchte, und da ich nicht davon ausgehe, dass jeder die selben Gehäuse für Sender und Empfänger der Laserlichtschranke zur Verfügung hat, habe ich das Brett auch nicht in das Zip-File hinzugefügt. Einzige „Bedingung“ ist, dass die beiden Flügelschrauben einen Abstand von 130mm zur Mitte des Balkens haben (also 260mm Abstand zueinander).

Der Code

Natürlich befindet sich die neueste Version des Programmcodes auch in dem Zip-File. Für all‘ jene, die sich das Programm gerne auf GitHub ansehen möchten: Der Sensor wird erst ab der Version 1.3.0 unterstützt, und läuft ohne Probleme seit der Version 1.3.2.

Um den Sensor auch nutzen zu können, muss, sobald der Host mit der Switchbox verbunden ist, das Häkchen neben dem Start-Button gesetzt werden.

Software_Sensor_Mask

Danach kann man links in der Software die Parameter einstellen.

  • Height 1: Dies ist die Distanz zwischen dem Fallobjekt und dem Sensor oberhalb des Sensors. Hält man beispielsweise einen Apfel 10cm über dem Sensor, bevor man ihn fallen lässt, so muss man hier 100mm einstellen.
  • Height 2: Hier wird die Distanz zwischen Sensor und Boden festgelegt.
  • Delay: Das Delay wird automatisch berechnet, jedoch kann man es noch zusätzlich variieren, je nachdem wie das Bild später aussehen soll.

Ist das Häkchen gesetzt, so werden beim Vorgang die Ventile nicht genutzt! Sollte ich Anfragen bekommen, die Ventile und den Sensor gleichzeitig nutzen zu können, dann werde ich das ins Programm bringen, ansonsten sehe ich für mich keinen Sinn beides gleichzeitig zu nutzen.

Ist der Sensor zu empfindlich, also löst die Kamera aus, ohne dass etwas durch den Sensor fällt? Kein Problem, in den Optionen (Tools -> Options) kann die Empfindlichkeit eingestellt werden. Null ist hierbei die maximale Empfindlichkeit, und 10 die niedrigste (ich weiß, konträr, aber das liegt an meiner Faulheit).

Software_Sensor_Options_Mask

Der Sensortyp gibt an, ob man einen analogen oder einen digitalen Sensor nutzt. Der Sensor, den ich hier vorgestellt habe ist ein analoger, da er den Spannungswert direkt an den Controller schickt (ohne weitere Verarbeitung). Ein digitaler Sensor bereitet das Signal vorher auf, bevor er einen digitalen Wert (5V oder 0V) an den Controller schickt.

Ein solcher Sensor kann zum Beispiel als Reflexlichttaster ausgeführt sein.

Light_Sensor_Advanced

Hierbei muss man darauf achten, dass das digitale Signal LOW wird, wenn ein Objekt erkannt wird, ansonsten funktioniert der Sensor nicht mit der Switchbox.

Das Ergebnis

Um es zu testen habe ich in der Software das Delay auf Null gesetzt, und den Blitz die Arbeit machen lassen. Soll heißen, ich habe die Kamera 4 Sekunden in einem halbdunklen Raum belichten lassen, und der Blitz hat dann das Fallobjekt „eingefangen“.

In_Flight.jpg

Das Bild ist jetzt nicht gerade das schönste, aber es zeigt recht gut wie schnell das System reagieren kann. Wer die Kamera die Arbeit machen lässt, der muss die Verzögerung des Verschlusses mit einrechnen (trotz aktivierter Spiegelverriegelung). Hat man diese Zeit erst einmal durch Probieren gefunden, kann man sie als mehr oder weniger konstant annehmen und damit arbeiten.

Ein paar letzte Worte. Man kann neben diesem Sensor auch noch andere anschließen, etwa Schallsensoren. Wer mehr dazu wissen will, der kann mich gerne per Mail oder in einem Kommentar dazu fragen. Sollten mehrere Anfragen kommen, so schreibe ich gerne einen weiteren Blogeintrag zu diesem Thema.

Edit (22.06.2016)

Wer das Fallobjekt immer aus der gleichen Höhe fallen lassen, und zwar ohne es zudem noch halten zu müssen, der findet die Idee von Resterampe Berlin sicher genau so fein wie ich! Entweder man nutzt dazu einen separaten Mikrocontroller oder legt die Versorgung (Vcc & GND) des Lasers mit der des Phototransistors zusammen (Relais oder Transistor dazwischen und eine eigene Versorgung wegen des maximalen Stroms). Bei dem zweiten Punkt muss man allerdings das Programm des Arduinos etwas ändern, sodass das Servo auch arbeitet. Wer dazu Fragen hat: Einfach ein Kommentar!

So, das war’s.

.

Arduino & Nunchuk

English version.

Eines meiner Projekte benötigt einen Joystick und 2 Buttons als Eingabemöglichkeit. Das ganze selbst zu bauen wäre nicht das Problem, doch als ich hörte, dass der Wii Nunchuk mit I2C arbeitet konnte ich gar nicht anders, als ihn für meine Zwecke zu nutzen.

Setup_Bokeh.jpg

In diesem Beitrag zeige ich, wie man die Daten vom Controller via I2C auslesen kann. Diese Daten werden dann auf einem Display und mit 6 LEDs dargestellt.

Der elektrische Aufbau

Für dieses Tutorial benötigt man die folgenden Bauteile

  • 1 Arduino UNO/Nano
  • 1 Wii Nunchuk
  • 1 0.96″ I2C Display
  • 6 LEDs
  • 6 220Ω Widerstände für die LEDs

Neben dem Steckbrett gibt’s auch noch den Schaltplan, da es wegen der LED-Anordnung recht eng geworden ist.

Wii_Nunchuk_Schaltplan

Wii_Nunchuk_Steckplatine

In Real sieht der Setup dann etwa so aus:

Setup

Achtung! Die Versorgungsspannung des Nunchuks beträgt 3.3V. Er darf auf keinen Fall an die 5V Leitung angeschlossen werden, da dies ihn sonst beschädigen würde! Er hat zudem einen Logic Level Shifter integriert, was die Nutzung der I2C-Pins ohne weitere Maßnahmen erlaubt.

Die meisten I2C-Displays dieser Größe arbeiten mit 5V. Mehr zu dem Display und dessen Verwendung kann man hier nachlesen. Wem das Lesen zu viel ist, der kann sich hier die nötige Programmbibliothek für den Display herunterladen und in das Standard-Verzeichnis für Arduino-libs (../Arduino/libraries/) kopieren.

Der Code

Wie immer: GitHub.

Im Hauptverzeichnis auf GitHub findet man 3 *.ino-Dateien. Wer die Standard-Arduino-IDE nutzt, der muss lediglich das Hauptfile – Wii_Nunchuk.ino – öffnen. Die beiden anderen Dateien werden automatisch in neue Tabs geladen. Wenn alle Dateien offen sind folgt hier die Erklärung der Funktionen:

  • setup. Pins festlegen, Controller initialisieren, controllerspezifische Kalibrierung festlegen (dazu später mehr), Display initialisieren.
  • loop. Daten vom Nunchuk anfordern, diese dann auf ein „hübsches“ Outputformat für den Display bringen und ausgeben. Zum Schluss noch die LEDs passend zum Signal ansteuern.
  • printFormNum. Damit die Zahlen rechtsgebunden am Display erscheinen wird der auszugebende String an die Länge der Zahl angepasst.
  • sendDataToNunchuk. Hier wird mit Hilfe der Wire.h-Library ein Datensatz an den Nunchuk gesendet. Für mehr Info über die I2C-Kommunikation: http://playground.arduino.cc/Learning/I2C.
  • initNunchuk. Zu Beginn muss der Nunchuk initialisert werden, wobei festgelegt wird aus welchem Register des Nunchuks wie ausgelesen wird.
  • getNunchukData. Hier passiert das Spannende. Zuerst schickt man dem Controller einen Request für die ersten 6 Register (0x00, 0x01, …). Hinter diesen Registern verbergen sich die Postionsdaten des Joysticks und der Buttons als Zahlenwert. Hat der Controller den Request erhalten, so schickt er an das Arduino die jeweiligen Daten zurück. Die map-Funktion wird hier als controllerspezifische Kalibrierung eingesetzt.

Ist das Programm auf das Arduino geladen, so kann man bei Benützung des Nunchuks die Daten, welche von ihm empfangen werden vom Display ablesen. Zusätzlich ändert sich die Helligkeit der LEDs passend zur Eingabe.

Display_Close.JPG

Was ist nun die ominöse Kalibrierung? Die Daten, welche der Controller an den Arduino schickt sind nicht weiter verarbeitet, sie sind also Rohdaten. Nun kann es passieren, dass man den Joystick ganz nach links drückt, der Zahlenwert der X-Koordinate dennoch nicht Null ist. Um das zu ändern muss man zunächst im Setup alle die Min/Max-Values zurücksetzen auf:

nunchuk.MinX = 0;
nunchuk.MaxX = 255;
nunchuk.MinY = 0;
nunchuk.MaxY = 255;

Nun lädt man das Programm erneut auf das Arduino und notiert sich die angezeigten Werte der äußersten Position des Joysticks:

  • MinX ist jener Wert, wenn der Joystick ganz nach links gedrückt wird (zB: 29).
  • MaxX: Wert, wenn Joystick ganz nach rechts gedrückt wird (zB 228).
  • MinY: Wert, wenn Joystick nach unten gedrückt wird (zB 33).
  • MaxY: Wert, wenn Joystick nach oben gedrückt wird (zB 222).

Diese Werte trägt man dann in die Kalibrier-Variablen ein.

nunchuk.MinX = 29;
nunchuk.MaxX = 228;
nunchuk.MinY = 33;
nunchuk.MaxY = 222;

Nun ist das Programm für diesen einen Controller ausgelegt.

Das war’s, bei Fragen ist ein Kommentar immer erwünscht!

.

 

Panorama w/ Leaflet

English version.

Hier zeige ich wie man Giga-Panoramas im Web einfach und (mehr oder weniger) schnell darstellen kann. Hierfür nutze ich Leaflet. Dabei handelt es sich um ein Java Script, das sich wirklich leicht in eine Website implementieren lässt.

Bilder & Verarbeitung

Das erste Panorama, das ich fürs Web optimiert habe zeigt die Landschaft meiner Heimatstadt. Man braucht nur knapp 30 Minuten lang bergauf zu gehen und schon befindet man sich in einer wesentlich idyllischeren Umgebung. Das Bild war von Anfang an als „Testbild“ gedacht. Ich habe nicht auf den besten Ausschnitt oder die höchste Schärfe geachtet, sondern ich wollte einfach eine nette Basis für das Online-Pano.
.
Ich habe die Kamera ohne Stativ (es lag zuhause) im Hochformat gehalten und sechs Bilder gemacht. Dabei habe ich darauf geachtet, dasss sich alle Folgebilder zu gut 40% überlappten. Das ist wichtig für die spätere Nachbearbeitung.
.
Nach einer kurzen Bearbeitung (Helligkeit, Kontrast, Schärfe) aller RAW-Bilder und deren Konvertierung ins jpg-Format habe ich das Bild in Photoshop von Photomerge zusammensetzen lassen. Danach folgte die Farbanpassung im gesamten Bild, da dies wesentlich einfacher ist, wenn man das Bild als ganzes betrachtet. Hier habe ich ebenfalls nur sehr wenig verändert, etwa das sehr dominate Blau etwas abgeschwächt und mit etwas Magenta vermischt.
.
Eine kleine Anmerkung zum Stitchen der Bilder: Ich habe erst nachdem das Bild fertig und online war einen anderen Editor entdeckt, mit welchem das Mergen sehr viel besser funktioniert. Es handelt sich um den ICE (Image Composite Editor) von Microsoft. Er ist kostenlos und lässt sich zudem sehr angenehm bedienen. Außerdem stimmen die Resultate.
.
ice
.

Als letzten Schritt, bevor wir zum Script kommen, muss man das Bild „zerhacken“. Dabei wird das Bid in unterschiedlichen Zoomebenen in 256×256 Pixel große Quadrate zerlegt und gespeichert. Jede Zoomebene erhält ihre eigene Nummer, und die Position des Teilbildes in der Ebene wird mit X-Y-Koordinaten festgelegt. Hierzu eine kleine Beschreibung:

Zoomlevel 0, die Koordinaten des Bildes sind X=0 und Y=0, also heißt die Datei 0-0-0.jpg.

zoom0.jpg

Zoomlevel 1, die Koordinaten des Bildes 1 sind X=0 und Y=0 und jene von Bild 2 sind X=1 und Y=0, also heißen die Dateien 1-0-0.jpg und 1-1-0.jpg.

zoom1.jpg

Warum macht man das? Das gesamte Bild auf einer Website zu laden würde viel zu lange dauern. Deshalb lädt man immer nur die Anteile des Bildes, die auch tatsächlich gebraucht werden – auf den Bildschrim passen. Lässt man sich das Bild in die Ansicht einpassen, so sieht man nicht das tatsächliche Panorama mit (hier) 15000×8000 Pixel, sondern nur mit ungefähr der momentanen Bildschirmauflösung.

Wie macht man das? Eine gute Lösung ist Zoomify. Wer mit Photoshop arbeitet, der hat das Glück, dass im Export Zoomify unterstützt wird. Die exportierten Bilder werden in Ordnern mit maximal 256 Bildern gespeichert, ehe ein neuer Ordner angelegt wird. Diese Ordner lädt man dann auf den Webserver und verweist im Java Script darauf.

Leaflet

Auf GitHub findet man das nötige Script, sowie ein kleines Beispiel-html-File.

In Zeile 21 des panorama.html Files gibt man den Link zum eigenen js-File an und in Zeile 26 folgt der Link zum Ordner, welcher die Ordern der Tiles beinhaltet.

Das js-File kommt natürlich in den js-Ordner am Webserver. Hier darf man dann den Link nicht vergessen!

Das Resultat

Alles zusammen sieht dann so aus:

http://www.deloarts.com/de/photography/first_pano/

WordPress unterstützt hier aufgrund der Sicherheitsrichtlinien leider keine iFrames. Deshalb muss man separat auf den Link klicken. Hier kann man den Eintrag Flawless betrachten.

Bilddaten
  • Kamera: Canon EOS 650D
  • Blende: f/8
  • Belichtungsdauer: 1/320 Sek.
  • Filmempfindlichkeit: ISO-100
  • Objekitv: Canon 18-200mm
  • Brennweite: 50mm

16×2 I2C-Display on Raspberry Pi

English version.

Wer einen kleinen Display am Raspberry benötigt, der ist hier richtig! Mit wenig Aufwand und ein paar wenigen Bauteilen kann man einen I2C-Display am Raspberry Pi nutzen.

Das Raspberry vorbereiten

Als erstes muss alles aktuell sein, weshalb man im Terminal den Befehl

sudo apt-get update

eingeben muss. Um auf dem Raspberry Pi auch wirklich den I2C-Bus nutzen zu können, muss man diesen zuerst aktivieren. Der erste Schritt ist es im Terminal den Befehl

sudo raspi-config

einzugeben. Daraufhin erscheint die Setup-Utility, in welcher man den Menüpunkt 8 Advanced Options auswählen muss.

001

Im nächsten Fenster muss man A7 I2C auswählen, und alle kommenden Fenster mit Yes oder OK bestätigen. Mit Finish kehrt man zurück zum Terminal.

002

Im zweiten Schritt muss das Module File um zwei Einträge erweitert werden. Dies wird erledigt, indem man zunächst

sudo nano /etc/modules

ausführt und dann am Schluss der Datei die beiden Einträge

i2c-bcm2708
i2c-dev

hinzufügt. Mit STRG+X, Yes und Enter speichert man die Datei und schließt sie.

003

Um den I2C-Bus mit Python nutzen zu können benötigt man python-smbus und die i2c-tools. Beides hohlt man sich durch den Terminal-command

sudo apt-get install -y python-smbus i2c-tools

Danach muss man das Raspberry neu starten, sodass der I2C-Bus wirksam wird. Dies kann über die grafische Oberfläche oder im Terminal geschehen:

sudo reboot

Der Aufbau

Die paar wenigen Bauteile sind:

  • Raspberry Pi 2
  • 16×2 I2C-Display
  • Logic Level Shifter

Der Logic-Level-Shifter wird benötigt, da das Raspberry mit dem logischen Level von 3.3V arbeitet, die meisten Displays jedoch mit 5V arbeiten. Solche Level Shifter gibt es bereits um unter einen Euro auf eBay zu haben. Bei diesem Preis lohnt sich das selbst machen nur noch aus Interesse daran.

Level_Shifter

Die Verdrahtung ist wie im Bild unten ersichtlich nach der folgenden Tabelle durchgeführt.

  • Level Shifter – Raspberry Pi
    • GND – GND (Pin 6)
    • HV – 5V (Pin 2)
    • LV – 3V3 (Pin 1)
    • LV1 – SDA (Pin 3)
    • LV2 – SCL (Pin 5)
  • Level Shifter – I2C Display
    • GND – GND
    • HV – Vcc
    • HV1 – SDA
    • HV2 – SCL

Untitled Sketch_Steckplatine

Der fertige Setup sieht dann in etwa so aus:

Setup

Das Display ist ein normales HD44780-Display, welches einen I2C-Rucksack bekommen hat. Diese „Rucksäcke“ gibt es einzeln, oder bereits mit dem Display verlötet.

Display

Der Code

Das Programm befindet sich auf GitHub und kann auch direkt von dort auf das Raspberry geladen werden.

Die beiden Python-files (16x2_I2C_Display.py & lcd.py) müssen in das selbe Verzeichnis auf dem Raspberry kopiert werden, da das erste File das zweite aufruft.

16x2_I2C_Display.py

Dieses Programm zeigt die IP-Addresse des Pi auf dem Display an. Dabei importiert es die Funktionen der Datei lcd.py.

Im Main ist die Herangehensweise gezeigt. Man muss den Display zuerst initialisieren, danach kann man ihm Text zum „Drucken“ schicken oder aber auch die Hintergrundbeleuchtung an- oder abschalten.

lcd.initialize()
lcd.printString("TEXT", lcd.LINE_1)
lcd.noBacklight()
lcd.Backlight()

lcd.py

Hier passiert das Wichtige – die Kommunikation mit dem Display. Diese funktioniert ähnlich wie mit einem Arduino (siehe hier). Deshalb lassen sich die Befehle des Displays auch genauso bequem senden. In der sendByte()-Funktion lässt sich erkennen, dass ich immer wieder BACKLIGHT mitsende. Das muss so sein, weil der Display ansonsten die Hintergrundbeleuchtung abdreht, und so seinen Sinn & Zweck verliert.

Über den smbus (hier als i2c deklariert) werden die nötigen Daten gesendet. Dabei wird immer die Addresse, gefolgt von den Daten gesendet. In der sendByte()-Funktion werden diese als Abfolge der Datenblöcke (Typ, Daten, Beleuchtung) gesendet. Hier wird das Delay benötigt, da der Display die Daten ansonsten nicht korrekt erhält.

Das lcd.py kann man nun (genau so wie es ist) für andere Projekte nutzen. Einfach in das jeweilige Python script mit import lcd einfügen. Allerdings muss es sich im selben Verzeichnis befinden.

Anmerkung: Man kann auch einen 20×4 Display verwenden, dazu muss man im lcd.py File einfach nur die Zeile 15 verändern (16 -> 20) und Line_3, Line_4 nutzen im printString-Befehl nutzen.

Nachbereitung

Ich möchte die IP-Adresse für 15 Sekunden anzeigen lassen, sobald der Raspberry hochgefahren ist. Hierfür muss man das Script nach dem Start ausführen lassen.

Zuerst habe ich beide Dateien in das Verzeichnis /home/pi/Autostart/ verschoben und die Datei 16x2_I2C_Display.py umbenannt in showIP.py.

Danach muss man das Terminal öffnen und folgenden Befehl eingeben:

sudo nano /etc/rc.local

Anschließend muss man den Pfad und die zu öffnende Datei angeben, in meinem Fall ist dies

/bin/sleep 15 && cd /home/pi/Autostart/ && sudo python showIP.py &
exit 0

sleep 15 bewirkt, dass das Script erst 15 Sekunden nach dem Hochfahren ausgeführt wird. Nach einigem Testen hat sich gezeigt, dass das Pi etwa 15 braucht, um eine IP Adresse abzurufen. & am Ende der Zeile bedeutet, dass das Script im Hintergrund ausgeführt wird. Das exit 0 am Ende wird von rc.local benötigt, es beendet das Script. Wenn ihr also noch andere Scripts beim Systemstart ausführen wollt, stellt sicher, dass exit 0 auch wirklich in der letzten Zeile steht.

004

Mit STRG+O speichert man das File, und mit STRG+X schließt man es. Beim nächsten Neustart sollte man dann ein ähnliches Bild wie das folgende sehen können.

IP.jpg

Bei Fragen ist ein Kommentar immer erwünscht!