360°-Fotos mit GoPro Hero 7

360 Grad Kamera DIY

360°Fotos setzen deinen Ort in ein neues Licht. Ich zeige dir, eine 360°-Kamerahalterung für deine GoPro selber baust und damit Rundumaufnahmen von deinem Lieblingsort macht. Du benötigst hierfür keine professionelle 360°Kamera.

360°-Fotografie

Auch mit einer normalen GoPro und letzlich jeder anderen Kamera kann man eine 360°-Aufnahme erstellen. Um eine Aufnahme zu erstellen werden Fotos in alle Himmelrichtungen gemacht und anschließend zu einem 360°-Foto zusammengesetzt. Eine GoPro bietet hier den Vorteil einer Fischaugenlinse. Durch den starken Weitwinkel müssen weniger Fotos für eine 360°-Aufnahme gemacht werden. Das spart Zeit.

Da das Fotografieren sehr aufwendig ist, habe ich inspiriert durch Pixelmagic und seiner Full automatic 360° panorama V2 GoPro Halterung eine eigene Version seiner 360°Kamerahalterung für die GoPro Hero 7 designed und programmiert.

Anleitung

!!Die Folgenden Links sind die Shops bei denen ich die Materialien gekauft habe oder dienen als Beispiel für die verwendeten Produkte. Ich erhalte keinerlei Provision oder sonstigen Gegenwert!!

Materialien

Funktion der 360 Grad Kamerahalterung

Die Kamerahalterung wird von einem von einem ESP8266 Mikrocontroller auf einem NodeMCU-Board gesteuert. Der Mikrocontroller steuert zum Einen Schrittmotor und Servo, zum Anderen sendet der ESP8266 Befehle per WLAN an die Kamera.

Die Fotos der Kamera werden dann in einem zweiten Arbeitsschritt gestitcht, also zusammengesetzt.

Schematischer Aufbau der 360°-Kamerahalterung

Leider verliert die GoPro oder der Mikrocontroller nach einem 360°-Foto die WLAN-Verbindung und der Akku muss aus der GoPro entfernt und wieder eingesetzt werden. Ich konnte diesen Fehler bisher nicht lösen. Wenn ihr wisst, wo das Problem liegt, schreibt es gerne in die Kommentare!

Zusammenbau

Der Anschluss des Steppermoduls und des Servos erfolgt nach den Anschlusstabellen. Außerdem habe ich an Pin D7 und GND der Taster angeschlossen. Dieser kann im Gehäuse zum Beispiel mit Heißkleber verklebt werden. Er dient zum Starten einer 360°-Aufnahme. Abschließend wird die Elektronik in das Gehäuse eingesetzt und Servo und Schrittmotor können in den Halterungen montiert werden. Den Schrittmotor habe ich mit zwei der Schrauben befestigt. Eine weitere Schraube wird gegenüber des Servos als Befestigung der GoPro Halterung eingedreht (siehe Fotos).

Pin (NodeMcu)Pin (Steppermodul)
D5IN1
D3IN2
D2IN3
D1IN4
GNDGND
3V3VCC
Pin (NodeMcu)Kabel (Servo)
D4oranges Kabel
3V3rotes Kabel
GNDbraunes Kabel

Fotos

Kommunikation zwischen ESP8266 und GoPro

Die GoPro und der ESP8266 kommunizieren über WLAN miteinander. Der Microcontroller versucht sich nach dem Einschalten mit dem WLAN der GoPro zu verbinden.

Dazu habe ich zuvor die SSID, also den Namen des Netzwerks und das Password aus dem GoPro Menü ausgelesen. SSID und Password müssen im Programmcode für YOURSSID und YOURPASSWORD eingesetzt werden.

//USER BEGIN
const char *ssid = "YOURSSID";      //GoPro Wifi name (SSID)
const char *password = "YOURPASSWORD"; //GoPro WiFi password
const int photosPerTurn = 10; //Fotos pro Umdrehung
const int turnsPerPhoto = 3;  //Anzahl der Fotos in Y-Richtung
//USEREND

Ist die Verbindung mit der GoPro erfolgreich erlischt die eingebaute Led des Boards und mit Betätgung des Tasters and Pin D7 wird eine Aufnahme gestartet.

Wenn SSID und Password auf deine GoPro angepasst sind, kann jetzt der Code mit der Arduino IDE oder PlatformIO auf den Arduino geflasht werden.

Denke daran, das verwendete Board in der Arduino IDE, als auch in PlatformIO auf NodeMCU mit ESP8266 anpassen musst. Ansonst kann der Code nicht geflashed werden. In der Arduino IDE kannst du über Werkzeuge->Board->ESP8266 Board das NodeMCU auswählen.

Code

Dieses Skript habe ich mit einer GoPro Hero 7 Black getested. Bei anderen GoPro-Modellen muss unter Umständen das Protokoll zum Ansprechen der GoPro über WLAN abgeändert werden. Das Protokoll zur Kommunikation mit vielen GoPro-Modellen über WLAN findet sich im Github-Repository von KonradIT.

#include <Arduino.h>
#include <Servo.h>
#include <Stepper.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <WakeOnLan.h>

//USER BEGIN
const char *ssid = "YOURSSID";      //GoPro Wifi name (SSID)
const char *password = "YOURPASSWORD"; //GoPro WiFi password
const int photosPerTurn = 10; //Fotos pro Umdrehung
const int turnsPerPhoto = 3;  //Anzahl der Fotos in Y-Richtung
//USEREND


WiFiClient client;
const char *host = "10.5.5.9";
const int httpPort = 80;

//Wake on Lan
WiFiUDP UDP;
WakeOnLan WOL(UDP);
IPAddress broadcastAdress = IPAddress(255, 255, 255, 0);

//Konstanten
const int delaylonger = 1200; //Zeit, die auf das Ausführen der Einstellung gewartet werden soll
const int delaypos = 1000;    //Zeit für die neue Position
const int delayPhoto = 3100;

const int stepperSpeed = 10;  //wichtig zur Berechnung der Wartezeit

//Servo
Servo servo1;

//Stepper
const int SPU = 2048;
Stepper step(SPU, D1, D3, D2, D5);

//Leds_Taster
const int led = D0;
const int start = D7;

//methods
void trigger();
void setPhotoMode();
void setPhotoWide();
void wakeUp();

void setup()
{
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  pinMode(start, INPUT_PULLUP);
  servo1.attach(D4);
  servo1.write(150); //fahre in Grundposition
  step.setSpeed(stepperSpeed);

  //wifi
  WOL.setBroadcastAddress(broadcastAdress); //Wake on Lan
  delay(100);
  bool ledStatus = true;
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  // wait for wifi to connect
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    digitalWrite(led, ledStatus);
    ledStatus = !ledStatus;
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  //settings
  setPhotoMode();
  setPhotoWide();
  ledStatus = true;
  digitalWrite(led, ledStatus); //schalte status led aus
}

void loop()
{
  if (!digitalRead(start))
  {
    digitalWrite(led, LOW);
    delay(1000);
    digitalWrite(led, HIGH);

    for (int j = 0; j < turnsPerPhoto; j++)
    {
      int servoPos = 180 - (j * 180 / (turnsPerPhoto - 1));
      servo1.write(servoPos); //teilt die Schritte des Servos in die Lagen auf
      delay(delaypos);        //warte auf den Servo
      for (int i = 0; i < photosPerTurn; i++)
      {
        if (j % 2 == 0)
          step.step(SPU / photosPerTurn);
        else
          step.step(-(SPU / photosPerTurn));
        delay(60 / stepperSpeed / photosPerTurn + 100);
        trigger();
        delay(delayPhoto);
      }
    }
    if (turnsPerPhoto % 2 == 1)
    {
      for (int i = 0; i < 3; i++)
      {
        //step.step(-682); //wenn ungerade anzahl fotos drehe zurück
        step.step(-SPU/4); //wenn ungerade anzahl fotos drehe zurück
        delay(60 / stepperSpeed / photosPerTurn + 100);
      }
    }
  }
}

void trigger()//make a photo
{
  if (!client.connect(host, httpPort))
  {
    Serial.println("connection failed");
    return;
  }
  String url = "/gp/gpControl/command/shutter?p=1";
  Serial.println(" Click !");
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(delaylonger);
}

void setPhotoMode()
{
  if (!client.connect(host, httpPort))
  {
    Serial.println("connection failed");
    return;
  }
  String url = "/gp/gpControl/command/mode?p=1";
  Serial.println(" Click !");
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(delaylonger);
}

void setPhotoWide()
{
  if (!client.connect(host, httpPort))
  {
    Serial.println("connection failed");
    return;
  }
  String url = "/gp/gpControl/setting/17/0";
  Serial.println(" Click !");
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(delaylonger);
}

void wakeUp()
{
  const char *MACAddress = "06:41:69:B4:47:F1";

  WOL.sendMagicPacket(MACAddress); // Send Wake On Lan packet with the above MAC address. Default to port 9.
                                   // WOL.sendMagicPacket(MACAddress, 7); // Change the port number
}

Zusammenfassung

Du kannst nun mit der 360°-Kamerahalterung einfach Aufnahmen in alle Himmelsrichtungen machen. Diese Bilder können anschließend mit einem Stichingprogramm zum Beispiel Hugin zu einer eigenen 360°-Aufnahme zusammengefügt werden.

Wenn dir all das zu kompliziert ist, dann könnte die Google Street View App etwas für dich sein. Mit dieser kannst du ganz bequem mit deinem Handy 360°-Aufnahmen machen und herunterladen. Du findest den Beitrag dazu hier.

Weitere Projekte

360°-Fotos mit GoPro Hero 7

2 Gedanken zu „360°-Fotos mit GoPro Hero 7

  1. Ich bin auf der Suche nach Beispielen für die Ansteuerung der Gopro7 auf diese Seite gestoßen. Da ich alle Teile in meiner Grabbelkiste habe, habe ich die kleine Maschine gedruckt und zusammengebaut. Leider passen die gedruckten Teile mit meiner NodeMCU und ULN2003 nicht zusammen, ein paar Millimeter zu wenig für die MCU und ein Millimeter zu viel für die ULN2003.
    Aber ich habe den Fehler in deinem Programm gefunden:
    Beim Zurückdrehen des Steppers wird zu viel gedreht.
    Folgende Änderung funktioniert:
    step.step(-SPU/4); //wenn ungerade anzahl fotos drehe zurück
    delay(60 / stepperSpeed / photosPerTurn + 100);
    Viele Grüße

    1. Hallo Matrin,
      vielen Dank für das Feedback. Ich habe die stl-Dateien für die Box jetzt auch als step-Dateien auf Printables veröffentlicht. Ich hoffe, das hilft dir die Box auf dein Boardformat anzupassen und Danke für die Tipps zum Code:)

      Viele Grüße
      Lennart

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen