Creating a Wireless remote for Nikon Camera using Esp8266

03 Aug 2017

The Nikon DSLR camera I own does have a Bluetooth connection, but unfortunately it is of no use. You cannot trigger shots from Bluetooth. Also u can only share photos of low resolution across Bluetooth. What a shame!!! I also want a time lapse option which is absent in the camera. There is a WiFi option, but have to invest a lot more money to buy the WiFi adaptor. Fortunately it has an IR interface. So I thought of creating my own triggering device (like the ML-L3) which works over WiFi so that I can remotely trigger the shutter and also take time lapse pics.

I can control ESP over phone and ESP will in turn control the camera using IR. (It can also behave as a normal ML-L3 Wireless remote). I got the command sequence for taking shots from here https://www.bigmike.it/ircontrol/. This is the code I wrote for controlling my DSLR.

#include <ESP8266WiFi.h>

const char* ssid = "Nikon";
const char* password = "password";

WiFiServer server(80);

int OutputPIN = D0;
unsigned int seq[] = {2000,27830,400,1580,400,3580,400};

void setupWiFi()
{
  ESP.eraseConfig();
  delay(1000);
  Serial.println();
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();
  Serial.println("Server started");
}

void setup() 
{
  // put your setup code here, to run once:
  pinMode(OutputPIN,OUTPUT);
  digitalWrite(OutputPIN, LOW);
  Serial.begin(9600);
  setupWiFi();
}

void sendSignal(unsigned int milliSec)
{
  int noofRepetition = milliSec/(15+9);

  for(int i=0;i<noofRepetition;i++)
  {
    digitalWrite(OutputPIN,HIGH);
    delayMicroseconds(15);
    digitalWrite(OutputPIN,LOW);
    delayMicroseconds(9);
  }
}

void wait(unsigned int milliSec){
  unsigned int microSec = milliSec%1000;
  delay((unsigned int)milliSec/1000);
  delayMicroseconds(milliSec%1000);
}

void sendCommand()
{
  for(int i=0; i<sizeof(seq)/sizeof(seq[0]);i++) 
  {
    /*Even places are 1 and odd places are 0*/
    if(i%2==0)
      sendSignal(seq[i]);
    else
      wait(seq[i]);    
  }
}

void takeSnap()
{
  sendCommand();
}

void timeSnap(unsigned long int shots, unsigned long int delayMilli)
{
  if(shots == 0)
    return;
  for(unsigned long int i=0;i<shots;i++)
  {
    takeSnap();
    delay(delayMilli);
  }
}
void loop() 
{
  unsigned long int shots,delayMilli;
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  Serial.println("new client");
  client.setNoDelay(1);
  while(!client.available()){
    delay(1);
  }
  
  String req = client.readStringUntil(',');
  shots = (unsigned long int)req.toInt();
 
  req = client.readStringUntil('\r');
  delayMilli = (unsigned long int)(req.toInt()*1000);
  Serial.println(shots);
  Serial.println(delayMilli);
  client.flush();
  timeSnap(shots,delayMilli);
  
}

snapshot

I am able to

  • remotely trigger the shutter from WiFi.
  • remotely trigger the shutter from remote.
  • configure to take time lapse pics from WiFi. (Will automatically take pics according to the number of shots and interval)