Archiv der Kategorie: Sony Camera

Sony Camera Remote Control mit ESP8266

Einleitung

Seit kurzem bin ich begeisterter Besitzer einer Sony DSC-HX90V. Für die Fernsteuerung dieser Kamera hat Sony eine WiFi Schnittstelle eingebaut und bietet eine App für Smartphones an, siehe PlayMemories. Leider gibt es keine weitere Schnittstelle (IR, elektrisch, Funk) um die Kamera remote zu bedienen.

Die Idee

Warum also sollte man die Kamera nicht über die WiFi Schnittstelle fernsteuern und damit gleichzeitig eine Schnittstelle per Mikrocontroller schaffen. Eine Realisierung einer WiFi Remote für eine GoPro wurde vor kurzem auf Hackaday vorgestellt. Eine Suche nach entsprechenden Programmen für Sony Kameras war ohne Erfolg. Auch die Sony Dokumentation der API brachte mich nicht weiter, da ich kein Android programmiere.
Über das ESP8266 Forum, fand ich zumindest Interessierte mit der gleichen Idee, aber keine Lösung.

ESP_Sony3

Reverse Engineering zur Lösung

Durch Zufall stieß ich auf die TimeLapse App von Thibaud Michel.
Mit Hilfe eines WiFi PacketAnalysers habe ich mir auf dem Tablett das Protokoll näher angeschaut und dann mit der Sony Doku der APK verglichen.
ESP_Sony1
Nach einiger Recherche fand ich heraus, dass es sich um ein einfaches HTTP POST Verfahren handelt mit der Übergabe der Parameter in einem json Format. Das nachzubilden mit dem ESP8266 war nur noch Fleißarbeit.

Proof of Concept

Die hier vorgestellte Lösung ist ein erster „Proof of Concept“ ohne jegliches Fehlerhandling und soll zunächst nur die Funktion des Schnittstelle darstellen. An einem ESP8266-01 ist lediglich ein Pushbutton zur Auslösung der Kamera angeschlossen der Rest ist Programm. Als Test wurde das Programm auf meinem Prototyp Board entwickelt. Auf diesem Board ist die 3,3V Stromversorgung und der FTDI zur Programmierung und zur Ausgabe von Debug Informationen fest verbunden. Der ESP8266 ist steckbar. Einzige zusätzliche Komponente ist der Pushbutton zur Fernauslösung der Kamera. Eine Beschreibung des Protoboards und die Einbindung der ESP8266 Libraries in die Arduino IDE findet sich hier. Die prinzipielle Verschaltung hier. Der Code ist ausführlich kommentiert und weicht nicht erheblich von den bekannten WiFiClient Codes ab, sollte also leicht verständlich sein. Auf eine Auswertung der json Antworten der Kamera wurde verzichtet.

//----------------------------------------------------------------------------------------------------------------------
// This program is based on: WiFiClient from ESP libraries
//
// Camera handling by Reinhard Nickels https://glaskugelsehen.wordpress.com/
// tested with DSC-HX90V, more about protocol in documentation of CameraRemoteAPI https://developer.sony.com/develop/cameras/
// 
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// http://creativecommons.org/licenses/by-sa/3.0/
//
// Requires Arduino IDE with esp8266 core: https://github.com/esp8266/Arduino install by boardmanager
//----------------------------------------------------------------------------------------------------------------------

#include <ESP8266WiFi.h>
#define DEBUG 1
#define BUTTON 2   // pushbutoon on GPIO2
volatile int counter;

const char* ssid     = "DIRECT-GKC2:DSC-HX90V";
const char* password = "5uv2LSwj";     // your WPA2 password

const char* host = "192.168.122.1";   // fixed IP of camera
const int httpPort = 8080;

char JSON_1[] = "{\"version\":\"1.0\",\"id\":1,\"method\":\"getVersions\",\"params\":[]}";
char JSON_2[] = "{\"version\":\"1.0\",\"id\":1,\"method\":\"startRecMode\",\"params\":[]}";
char JSON_3[] = "{\"version\":\"1.0\",\"id\":1,\"method\":\"startLiveview\",\"params\":[]}";
char JSON_4[] = "{\"version\":\"1.0\",\"id\":1,\"method\":\"stopLiveview\",\"params\":[]}";
char JSON_5[] = "{\"version\":\"1.0\",\"id\":1,\"method\":\"actTakePicture\",\"params\":[]}";
// char JSON_6[]="{\"method\":\"getEvent\",\"params\":[true],\"id\":1,\"version\":\"1.0\"}";


unsigned long lastmillis;

WiFiClient client;

void setup() {
  Serial.begin(115200);
  delay(10);

  pinMode(BUTTON, INPUT_PULLUP);
  attachInterrupt(2, pulleddown, FALLING);  // handled by interrupt to debounce

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {   // wait for WiFi connection
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  delay(1000);
  httpPost(JSON_1);  // initial connect to camera
  httpPost(JSON_2); // startRecMode
  httpPost(JSON_3);  //startLiveview  - in this mode change camera settings  (skip to speedup operation)
}

void loop() {
  if (buttonpressed()){
    Serial.println("pressed..");
    httpPost(JSON_4); //stopLiveview    (skip to speedup operation)
    httpPost(JSON_5);  //actTakePicture
    httpPost(JSON_3);  //startLiveview    (skip to speedup operation)
    }
}

void httpPost(char* jString) {
  if (DEBUG) {Serial.print("Msg send: ");Serial.println(jString);}
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  else {
    Serial.print("connected to ");
    Serial.print(host);
    Serial.print(":");
    Serial.println(httpPort);
  }

  // We now create a URI for the request
  String url = "/sony/camera/";

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("POST " + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n"));
  client.println("Content-Type: application/json");
  client.print("Content-Length: ");
  client.println(strlen(jString));
  // End of headers
  client.println();
  // Request body
  client.println(jString);
  Serial.println("wait for data");
  lastmillis = millis();
  while (!client.available() && millis() - lastmillis < 8000) {} // wait 8s max for answer

  // Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println();
  Serial.println("----closing connection----");
  Serial.println();
  client.stop();
}

void pulleddown()  // Interrupt handler
{
  counter++;
}

boolean buttonpressed() {  // function to check if pressed
  if (counter!=0) {  
    counter=0;
    delay(10);     // je nach Schalter 
    if (counter==0 && !digitalRead(BUTTON)) return true;
  }
  return false;
}
 

ESP_Sony2

Bedienung

Für die Funktion muss auf der Kamera die aktuelle Version der Smart-Fernbedienung (das Gegenstück für die PlayMemories App) installiert sein.

Im Programm muss die SSID und das Passwort der benutzten Kamera eingetragen werden. Die Kamera wird nach dem Einschalten über das Menue in den Fernsteuermodus gebracht. Nach dem Einschalten des ESP8266 wird die Verbindung zur Kamera hergestellt und die Kamera wird in einen Modus versetzt, wo Einstellungen (Zoom, Blende, Zeit, …) möglich sind.

Ein Druck auf den Pushbutton löst die Kamera aus und die Kamera kehrt in den vorhergehenden Modus zurück.

Über die serielle Schnittstelle werden Debug Informationen ausgegeben, hier ein Beispiel nach dem Einschalten des ESP bis nach der ersten Fernauslösung der Kamera.

Connecting to DIRECT-GKC2:DSC-HX90V 
....... 
WiFi connected 
IP address:  
192.168.122.115 
Msg send: {"version":"1.0","id":1,"method":"getVersions","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 51
Content-Type: application/json

{"result":[["1.0","1.1","1.2","1.3","1.4"]],"id":1} 
----closing connection---- 
 
Msg send: {"version":"1.0","id":1,"method":"startRecMode","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 21
Content-Type: application/json

{"result":[0],"id":1} 
----closing connection---- 
 
Msg send: {"version":"1.0","id":1,"method":"startLiveview","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 75
Content-Type: application/json

{"result":["http:\/\/192.168.122.1:8080\/liveview\/liveviewstream"],"id":1} 
----closing connection---- 
 
pressed.. 
Msg send: {"version":"1.0","id":1,"method":"stopLiveview","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 21
Content-Type: application/json

{"result":[0],"id":1} 
----closing connection---- 
 
Msg send: {"version":"1.0","id":1,"method":"actTakePicture","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 108
Content-Type: application/json

{"result":[["http:\/\/192.168.122.1:8080\/postview\/memory\/DCIM\/100MSDCF\/DSC01272.JPG?size=Scn"]],"id":1} 
----closing connection---- 
 
Msg send: {"version":"1.0","id":1,"method":"startLiveview","params":[]} 
connecting to 192.168.122.1 
connected to 192.168.122.1:8080 
Requesting URL: /sony/camera/ 
wait for data 
HTTP/1.1 200 OK
Connection: close
Content-Length: 75
Content-Type: application/json

{"result":["http:\/\/192.168.122.1:8080\/liveview\/liveviewstream"],"id":1} 
----closing connection---- 
 

Video

Video (Downloadlink):

Fazit und Ausblick

Dieser Blogeintrag beschreibt in einfacher Weise die grundsätzliche Funktion der WiFi Fernsteuerung einer Sony Kamera. Die Funktionsweise lässt sich zumindest auf die Kameras übertragen, die PlayMemories kompatibel sind. Möglicherweise ist dann die Serveradresse der Kamera zu modifizieren. Der Schritt zu komplexeren Lösungen ist reine Programmierarbeit. Ersetzt man den Pushbutton mit einer Zeitschleife kann man sehr einfach die Einzelbilder für TimeLapse Videos (Zeitraffer) aufnehmen. Die Auslösung kann natürlich auch durch Sensoren (Annäherung, Bewegung, …) erfolgen. Prinzipiell ist auch der Start und Stop einer Videoaufnahme (Kamera im Videomodus) möglich. Die entsprechenden json Kommandos sind in der Doku der APK enthalten. Wenn man auf den Modus „Liveview“ verzichtet ist die Auslöseverzögerung nur minimal (siehe Kommentar im Code, diese Zeilen dann auskommentieren), allerdings verliert man dann die Möglichkeit Kameraeinstellungen zu ändern. Für einen Batteriebetrieb ist der ESP8266 bekanntermaßen nicht so gut geeignet, aber für einen einzelnen Shot braucht es nicht viel Zeit. Für Timelapse Projekte wäre es sicher sinnvoll den Sleep Mode des ESP zu nutzen (was bei der Bauform ESP-01 nicht funktioniert ohne Modifikation). Ich würde hier das Modell ESP-12 empfehlen, das außerdem CE und FCC zertifiziert ist.

 

Advertisements