Wednesday, 1 October 2014

Nikon Hacks Part VI

Nikon Flash and Arduino

Runner Beans - Ring Flash
Check my other site !

Introduction 

In this section I aim to trigger the shutter of the camera and the Flash using the Arduino. I need to experiment with bits of code to get triggering and delay times just right.
So far I have established that the minimum trigger time for my flash is 12us (twelve microseconds). That is the minimum time the Trigger pin can be grounded to fire the flash.
Here is the simple code for that: --------------------------------------------------------------
 /*
  FLASH


  This example code is in the public domain.
 */


int flash = 11; // trigger pin

// the flash triggers once when you press reset after a short delay:

void setup() {               
  // initialize the digital pin as an output.
  pinMode(flash, OUTPUT);  
 
digitalWrite(flash, HIGH);

delay(3000);

// fire flash once------------------------------------------

digitalWrite(flash, LOW);   // 
  delayMicroseconds(12);               // wait 12us minimum trigger time
  digitalWrite(flash, HIGH);  
               // wait  
}

// the loop routine runs over and over again forever:
void loop() {
 
}

End Flash code:------------------------------------------------------

I want to use the camera in Bulb mode:

1.ensure IR is off and  prepare camera for bulb mode to receive IR
2. trigger IR and open shutter
3. wait for exposure eg 10 secs
4. trigger IR and close shutter
5. check result 

I decided to use the Transistor method for triggering the IR remote:

Code for IR:------------------------------------------------------------
/*
  shutter IR


  This example code is in the public domain.
 */

int shutter = 10; //IR shutter pin

int flash = 12; // Flash trigger pin


void setup() {               
  // initialize the digital pin as an output.
  pinMode(flash, OUTPUT);  
  pinMode(shutter, OUTPUT);
 
  Serial.begin(9600);
  digitalWrite(shutter, HIGH); // high is IR OFF

Serial.println ("Prepare Camera - 30 sec");

delay(30000); //pause 30sec

}

//
void loop() {
 
//bulb mode

digitalWrite(shutter, LOW); // low is IR on open shutter
Serial.println ("IR ON 1 - open shutter");
delayTenthsSeconds (2); // 0.2 seconds trigger shutter
 
  digitalWrite(shutter, HIGH); // high is IR OFF
  Serial.println ("IR OFF");
delayTenthsSeconds (100);// ten seconds

digitalWrite(shutter, LOW); // low is IR on close shutter
Serial.println ("IR ON 2 - open shutter");
delayTenthsSeconds (2);

 
  digitalWrite(shutter, HIGH); // high is IR OFF
   Serial.println ("IR OFF");
//delayTenthsSeconds (10);
Serial.println ("CHECK RESULT");
delay(50000); // hold for check

}

void delayTenthsSeconds (int multi){// delay multi x 0.1 sec

    for (int i = 1; i < (multi * 100); i++) //
    {
      delayMicroseconds(1000);   // multi x 100     }
}

End Code for IR:--------------------------------------------------

Sunday, 21 September 2014

Nikon Hacks Part V

Triggering Nikon Flash

Adapting the Cable



I'm using a serial cable connector and cable to breakout the flash cable, because they are cheap and make very strong physical connections which can be screwed together. The flash cable will still work without Arduino control..




Camera side: remove screws from case
  
Unplug the two halves

Remove hot-shoe PCB and ID the contacts.
1. Trigger (+3.7)
2. Detect (+5v)
3. Ready(+5v)
4. Quench(+4v)
5. Ground(0v)

 Solder header pins to the PCB contacts



Drill holes into the case to allow header pins through

Reassemble the case, and Identify the header pins for soldering

Solder a serial connector to the header pins which are poking through the case


1. Trigger (+3.7)
2. Detect (+5v)
3. Ready(+5v)
4. Quench(+4v)
5. Ground(0v)

Both ends of the Serial Cable Assembly

N.B. I added some epoxy putty to strengthen and protect the end with the hot-shoe. The Arduino end is soldered and broken out onto a serial PCB which I will use to connect to the Arduino using a ribbon cable. It also has a gender adapter.

I checked for continuity in the connections using my Multimeter and also that the flash is triggered when I make the circuit between Trigger and Ground.

Next: Playing with Arduino code and camera flash.

Saturday, 20 September 2014


Nikon Hacks Part IV

Triggering Nikon Flash

With Arduino

 


It's miserable weather here in Consett, so I'm staying in and hacking a Nikon flash cable so I can trigger a flash with an Arduino. The cable is only about £10 on Amazon.  http://pinoutsguide.com/ is a very useful link for pinouts of loads of electronic stuff.

WARNING - do not a attach your camera to the hot-shoe whilst it is attached to the Arduino, you may damage the camera by shorting out things or applying voltages to the camera circuits (very expensive mistake). If you blow an arduino chip , they cost just a few dollars, but a new Camera could cost you hundreds even thousands!

Nikon Hot-shoe cable Pinout 

When the flash is On and Ready (ready light is lit on the flash:

1. Trigger (+3.7)
2. Detect (+5v)
3. Ready(+5v)
4. Quench(+4v)
5. Ground(0v)


Testing
To simply trigger the flash you make the circuit between 1 and 5 (trigger and ground).  The ground (5) is connected to Arduino GND and 1 (trigger) is connected to a digital pin (in my case PIN13) which will go from HIGH to LOW, so triggering the flash in manual mode.When attached to my flash, the trigger pin reads +5v approx.

 You can test this by loading the Blink demo from the Arduino IDE and playing with the delay(). I did this initially by just holding the Arduino jumper wires onto the pinout surfaces of the hot-shoe. It is recommended to use a diode between the GND and the trigger pin (13)  to protect against voltage surges and ESD.

Code:------------------------------------------------------
/*
  FLASH
  Trigger a Camera Flash repeatedly.

  This example code is in the public domain.
 */

// Pin 13 has an LED connected on most Arduino boards so you
//should see the LED blink as well as the flash being triggered.

int flash = 13;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(flash, OUTPUT);    
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(flash, HIGH);   //  (HIGH is the 5v voltage level)
  delay(200);               // wait
  digitalWrite(flash, LOW);    // trigger the FLASH by making the voltage LOW
  delay(100);               // wait
}
End Code:------------------------------------------------------ 


Why?
Now I have a way of triggering the camera shutter (using the IR sensor) and the flash (using the hot-shoe cable) independently via the Arduino. It gives me greater creative and technical control over the exposures, remote or automatic triggering and special effects.

Next physically adapting the cable by soldering wires inside the cable's case.


Friday, 12 September 2014

Nikon Hacks Part III

Triggering Nikon with an Ultra Sound

Range-finding Sensor

SRF05 

 

 Introduction.
In the previous post I used
an arduino pin to switch a transistor which powered a relay and triggered an Nikon IR remote. Now I want to use a sensor to detect and range a subject, before firing the IR to capture the subject on camera. 



You can find the wiring and technical information for the SRF05 here:

Here is a brief video of the setup. First a side-view then to a view where I am outside of the scanning region of the SRF05. This front view dark because I am behind an object. I then "pop up" into the scanning region, within 200cm of the SRF05. The Camera focuses, the shutter opens and there is a flash, shutter closes. It does it twice in the time I am in the scanning region.




Triggered by a Subject in Range

Code:
---------------------------------------------------------------------------
int subjectRange = 200; // 200cm
const int numOfReadings = 5;                   // number of readings to take/ items in the array / readings to average
int readings[numOfReadings];                    // stores the distance readings in an array
int arrayIndex = 0;                             // arrayIndex of the current item in the array
int total = 0;                                  // stores the cumlative total
int averageDistance = 0;                        // stores the average value - using ints because 1cm or so is precise enough.

// setup pins and variables

int echoPin = 2;                                // SRF05 echo pin (digital 2)
int trigPin = 3;                                // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0;                    // stores the pulse in Micro Seconds
unsigned long distance = 0;                     // variable for storing the distance (cm)

int nikonPin = 8; // pin to trigger relay and IR unit



void setup() {


  pinMode(trigPin, OUTPUT);                     // set init pin 3 as output
  pinMode(echoPin, INPUT);                      // set echo pin 2 as input
  pinMode(nikonPin, OUTPUT);                   // sets pin 8 as output NikonPin
  digitalWrite(nikonPin, LOW);

  // create array loop to iterate over every item in the array

  for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
readings[thisReading] = 0;
 }

     Serial.begin(9600);
 }


void loop() {
// SRF05 code 
digitalWrite(trigPin, HIGH);                    // send 10 microsecond pulse
delayMicroseconds(10);                  // wait 10 microseconds before turning off
digitalWrite(trigPin, LOW);                     // stop sending the pulse
pulseTime = pulseIn(echoPin, HIGH);             // Look for a return pulse, it should be high as the pulse goes low-high-low
distance = pulseTime/58;                        // Distance = pulse time / 58 to convert to cm.
 total= total - readings[arrayIndex];           // subtract the last distance
readings[arrayIndex] = distance;                // add distance reading to array
total= total + readings[arrayIndex];            // add the reading to the total
arrayIndex = arrayIndex + 1;                    // go to the next item in the array
// At the end of the array (x items) then start again
if (arrayIndex >= numOfReadings)  {
    arrayIndex = 0;
  }

  averageDistance = total / numOfReadings;      // calculate the average distance
 
  Serial.println(averageDistance, DEC);         // print out the average distance to the Obj
  if (averageDistance <= subjectRange) // if subject comes to less than set distance take pictures until subject exits range
{
digitalWrite(nikonPin, HIGH); // trigger IR and camera
delay(2000); // allow some time (500 to 2000 seems to be ok for me)
digitalWrite(nikonPin, LOW); // IR off
}
else {
  digitalWrite(nikonPin, LOW); // default ir IR Off

}


}// end of loop

End of code: ---------------------------------------------------------------------------




Tuesday, 9 September 2014

Nikon Hacks

Part II

Triggering Nikon IR remote with Arduino


 In the previous post [Nikon Hacks Part I] I modified a generic Nikon IR camera trigger. 


[click images to enlarge]


I want to use an Arduino to make this work so I can attach sensors and / or bluetooth communication.
In the next post [SRF05 Nikon] I use an SRF05 ultrasound range finding sensor to trigger the camera.

1. SPDT Relay. I already made a relay board some time ago for another project. I'm going to adapt it to make the electrical connect between the two wires I soldered on the IR board  (see previous post). The signal from an Arduino pin will switch a transistor which in turn will close the contacts on the relay, so triggering the IR pulse, but it will need some modification.




The IR control wires are connected to the relay Normally Open (NO) and Common. When PIN8 goes from LOW to HIGH the transistor switches the relay which closes the NO and Common contacts making the circuit. R2 is a pull down resistor. The IR pulse is sent to the camera sensor and the camera takes a picture. Note camera is in live-view mode and set up for IR trigger (Nikon D5100 in my case).

Video to follow in next post [SRF05 Nikon].

So now I can use the Bluetooth code I presented in earlier posts to trigger the camera from my Android device Bluetooth, Android to Arduino. I can also attach sensors to the Arduino such as PIR or Ultrasound to detect movement and or distance. The limit is my imagination, I guess. 

2. Reed Relay (SPST). you can use a reed relay because we are not switching much current:


3. Or try an opto-Isolator.
http://en.wikipedia.org/wiki/Opto-isolator

 Alternative circuits


4. A Transistor is probably the most cost-effective option


Nikon Hacks

Part I 

Modify Nikon IR remote

 Apologies - I've been away for a while from the Blog due to some family issues. But now I'm BACK with a HACK :) 

Introduction

I'm adapting a Nikon IR remote so I can control it using an Arduino. You can find these IR remotes for a few pounds on Amazon - mine was £3.39 inc. delivery, so it wasn't worth me making and encoding my own IR unit. By incorporating Arduino I will be able to use an Android tablet or smart-phone to control the triggering of the camera over bluetooth. I can also incorporate sensors which can trigger the camera eg detect movement, take photo / video etc...

Geekery Recipe


Wires soldered to trigger pins of IR remote encoder

1. Remove the battery and open up the front of the unit. I used fine nosed pliers to peel off the front as it was thin and glued on. U1 is the encoder integrated circuit and probably incorporates a 555 style timer.

2. Locate the control surface under the push button. Then mark where the PCB tracks from the encoder chip (U1) connect to the control surface. This was on the other side on my unit. 

3. You may need to scratch away the PCB coating to expose the copper tracks. Clean and flux these to aid soldering. Solder on wires as in the picture above. 

4. Replace the battery and tape in place, for testing. 

5. Set up your camera for IR control. Test by making electrical contact between the two wires. It should trigger the camera shutter and take a picture. Success !






Friday, 6 December 2013

 Bluetooth Connection in Android from Matt Bell's blog

Project Structure


Here is the java and xml code from Matt Bell's blog adapted to send data only:

[code]--------------------------------------------------------------------------------------

package here
imports here

public class BluetoothTest extends Activity
{
    TextView myLabel;
    EditText myTextbox;
    BluetoothAdapter mBluetoothAdapter;
    BluetoothSocket mmSocket;
    BluetoothDevice mmDevice;
   
    OutputStream mmOutputStream;
   

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
      
        setContentView(R.layout.activity_main); // need a activity_main layout XML file
// with these objects below in it (buttons, labels etc...):
      
        Button openButton = (Button) findViewById(R.id.open);
        Button sendButton = (Button) findViewById(R.id.send);
        Button closeButton = (Button) findViewById(R.id.close);
        myLabel = (TextView) findViewById(R.id.label);
        myTextbox = (EditText) findViewById(R.id.entry);

        // Open BT connection Button
        openButton.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                try
                {
                    findBT();
                    openBT();
                } catch (IOException ex)
                {
                }
            }
        });

        // Send Button
        sendButton.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                try
                {
                    sendData();
                } catch (IOException ex)
                {
                }
            }
        });

        // Close button
        closeButton.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                try
                {
                    closeBT();
                } catch (IOException ex)
                {
                }
            }
        });
    }

    void findBT()
    {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null)
        {
            myLabel.setText("No bluetooth adapter available");
        }

        if (!mBluetoothAdapter.isEnabled())
        {
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0)
        {
            for (BluetoothDevice device : pairedDevices)
            {
                if (device.getName().equals("linvor"))// change accordingly
                {
                    mmDevice = device;
                    break;
                }
            }
        }
        myLabel.setText("Bluetooth Device Found");
    }

    void openBT() throws IOException
    {
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");                                                                                                                                                         

if (mmDevice != null) 
        {
            mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
            mmSocket.connect();
            mmOutputStream = mmSocket.getOutputStream();           

       
        myLabel.setText("Bluetooth Opened");
        }
    }

   

    void sendData() throws IOException
    {
        String msg = myTextbox.getText().toString();
        msg += "\n";
        mmOutputStream.write(msg.getBytes());
        myLabel.setText("Data Sent");
    }

    void closeBT() throws IOException
    {
      
        mmOutputStream.close();
        mmSocket.close();
        myLabel.setText("Bluetooth Closed");
    }
}// end of java code.


XML code: 
Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="your package"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" >
        <activity android:name="BluetoothTest"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="9"/>
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <supports-screens android:anyDensity="true" />
</manifest>



Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Type here:"/>
    <EditText
        android:id="@+id/entry"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_below="@id/label"/>
    <Button
        android:id="@+id/open"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/entry"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="10dip"
        android:text="Open" />
    <Button
        android:id="@+id/send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/open"
        android:layout_alignTop="@id/open"
        android:text="Send" />
    <Button
        android:id="@+id/close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/send"
        android:layout_alignTop="@id/send"
        android:text="Close" />
</RelativeLayout>


Arduino Test Code:
#include <SoftwareSerial.h>

int bluetoothTx = 2;
int bluetoothRx = 3;

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
const int LED = 10;
char incomingByte = ' ';

void setup()
{
  //Setup usb serial connection to computer
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  //Setup Bluetooth serial connection to android
  bluetooth.begin(115200);
  bluetooth.print("$$$");
  delay(100);
  bluetooth.println("U,9600,N");
  bluetooth.begin(9600);
  Serial.println("Start");
 
}

void loop()
{


  //Read from bluetooth and write to usb serial
  if(bluetooth.available())
  {
    Serial.println("BlueTooth OK");
    char toSend = (char)bluetooth.read();
    Serial.println(toSend);
    incomingByte = toSend;
  }


if (incomingByte == 'l')
{
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
}
 
}


[end code]----------------------------------------------