Egil Rotevatn
Published © GPL3+

PhotoBlynk

How to use a SparkFun Blynk Board to create a wireless, battery-driven remote control for most digital cameras.

IntermediateFull instructions provided1 hour399
PhotoBlynk

Things used in this project

Hardware components

SparkFun Blynk Board - ESP8266
SparkFun Blynk Board - ESP8266
×1
FDC6401N
Any two NMOS transistors with Gate Threshold Voltage lower than 3.3V should work
×1
Wired shutter release
×1
1s LiPo battery
If you want your wireless remote to be wireless..
×1

Software apps and online services

Blynk
Blynk
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Schematics

This shows how to connect the two transistors to the Sparkfun Blynk Board and the camera cable.
Photoblynk schematics

Code

Arduino code

Arduino
The code you need run on the Blynk board for it to work with the Blynk app.

See the blynk board guide here to set up everything correctly:
https://learn.sparkfun.com/tutorials/blynk-board-arduino-development-guide

The Blynk app i made: http://tinyurl.com/jknp3oy (you need to open this from a phone)
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#include <SimpleTimer.h>

////////////////////
// Blynk Settings //
////////////////////
char BlynkAuth[] = "Your auth token here";
char WiFiNetwork[] = "Your wifi name here";
char WiFiPassword[] = "Your password here";

///////////////////////
// Hardware Settings //
///////////////////////
#define WS2812_PIN 4 // Pin connected to WS2812 LED
#define BUTTON_PIN 0
#define LED_PIN    5
#define FOCUS_PIN  12
#define TRIGGER_PIN  13
WidgetLCD lcd(V10);

bool isFirstConnect = true;
SimpleTimer timer; // Create a Timer object called "timer"! 
int timerId = 0;
int countdownId = 0;

Adafruit_NeoPixel rgb = Adafruit_NeoPixel(1, WS2812_PIN, NEO_GRB + NEO_KHZ800);
bool focus_lock = false;
bool exposure_ongoing = false;
int exposure_time = 0;
int countdown_time = 0;

BLYNK_WRITE(V0) // Store new exposure time from V0
{
  exposure_time = param[0].asInt();

  Serial.print("Exposure time: ");
  Serial.println(exposure_time, DEC);
}

BLYNK_WRITE(V1) // Handle focus lock
{
  if (param[0].asInt()) //V1 is high, so focus should be locked
  {
    digitalWrite(FOCUS_PIN, HIGH);   
    focus_lock = true;

    Serial.print("Focus locked\n");
  }
  else
  {
    digitalWrite(FOCUS_PIN, LOW);   
    focus_lock = false;

    Serial.print("Focus unlocked\n");
  }

}

BLYNK_WRITE(V2) // Handle trigger
{
  if (param[0].asInt()) //V2 button is high
  {
    digitalWrite(TRIGGER_PIN, HIGH);   
    digitalWrite(FOCUS_PIN, HIGH);   

    if (exposure_time > 0) //long exposure/continous trigger
    {
      //Start timer 
      timerId = timer.setTimeout((exposure_time * 1000), exposure_done);

      //Start interval timer for blynk app "LCD" update
      countdownId = timer.setInterval(1000, exposure_countdown);
      countdown_time = 0;
      lcd.clear();
      lcd.print(4, 0, "Exp ");
      lcd.print(8, 0, exposure_time);
      lcd.print(4, 1, "Cnt ");
      lcd.print(8, 1, 0);
    }
    else //Just a short trig, 100ms should be enough
    {
      lcd.clear();
      timerId = timer.setTimeout(100, exposure_done);
    }

    exposure_ongoing = true;
    Serial.print("Capture!\n");
    digitalWrite(LED_PIN, HIGH);
  }
  else if (exposure_ongoing) //V2 button low while exposure is ongoing
  {
    //Stop exposure
    timer.deleteTimer(timerId);
    exposure_done();
  }
}

BLYNK_CONNECTED() //At first connect or reconnecto
{
  //Make sure the app knows if exposure is ongoing
  if (exposure_ongoing)
  {
    Blynk.virtualWrite(V2, HIGH); 
  }
  else
  {
    Blynk.virtualWrite(V2, LOW); 
  }

  //Recommended by tutorial
  if (isFirstConnect) {
    Blynk.syncAll();
  }
  isFirstConnect = false;
}

void exposure_done() //Stop exposure
{
  digitalWrite(TRIGGER_PIN, LOW);   
  if (focus_lock == false){
    digitalWrite(FOCUS_PIN, LOW);   
  }
  
  exposure_ongoing = false;
  Serial.print("Capture done\n");
  digitalWrite(LED_PIN, LOW);
  Blynk.virtualWrite(V2, LOW);   
  
  //Stop Blynk app "LCD" update
  if (countdownId) 
  {
    timer.deleteTimer(countdownId);
    countdownId = 0;   
  }
  lcd.clear();
}

void exposure_countdown()
{
  //Update Blynk app "LCD" with the elapsed time
  lcd.print(8, 1, ++countdown_time);
}

void setup()
{
  // Initialize hardware
  Serial.begin(9600); // Serial
  rgb.begin(); // RGB LED
  pinMode(BUTTON_PIN, INPUT); // Button input
  pinMode(LED_PIN, OUTPUT); // LED output
  pinMode(FOCUS_PIN, OUTPUT); // FOCUS output
  pinMode(TRIGGER_PIN, OUTPUT); // TRIGGER output

  // Initialize Blynk
  Blynk.begin(BlynkAuth, WiFiNetwork, WiFiPassword);
}

void loop()
{
  // Execute Blynk.run() as often as possible during the loop
  Blynk.run();

  // Exposure timer
  timer.run();  
}

Credits

Egil Rotevatn

Egil Rotevatn

1 project • 1 follower
Electronics engineer with a fondness for making and fixing stuff with my own hands. Likes to take pictures.

Comments