Close

Complete MATLAB script file

A project log for Remote control and image retrieval from Nikon DSLR

This post explains how to control a Nikon D3100 DSLR, and then get the images off of it.

sciencedude1990sciencedude1990 12/09/2020 at 16:590 Comments

Here is the complete MATLAB script file to automatically take a picture, copy to the local PC, convert to TIFF, and then open in MATLAB.  Note that my "pause" times worked for my PC - you might have to adjust them for your PC.  I tried to comment the heck out of it.  Enjoy! 

%% Identification
% Science Dude 1990
% December 9, 2020
%
%% Code
% Take a photo with a Nikon D3100 and transfer to local PC, load it in
% MATLAB

%% Clean up
clc
close all
clear
drawnow

%% Parameters
% Pause after picture taken (allow time for shutter, and file write to
% camera SD card)
pause_after_pic = 6;

% COM port
com_port = 5;

% BAUD rate
baud_rate = 9600;

% Data bits
data_bits = 8;

% Camera directory
camera_dir = 'Computer\D3100\Removable storage\DCIM\100TEST_';

% Current directory
current_dir = pwd;

%% Open the COM port, set the register to take the picture

% The serial port
s = serial(['COM' num2str(com_port)], 'BaudRate', baud_rate, 'DataBits', data_bits, 'Terminator', 'CR');
fopen(s);

% Send the commands
pause(1);
% Read the register for reference
fprintf(s, 'r37');
pause(1);
% Set PORTB to 1, then 3, to take a picture
fprintf(s, 'w37=1');
pause(1);
fprintf(s, 'w37=3');
pause(pause_after_pic);
fprintf(s, 'w37=0');

% Save the response from the microcontroller
scan_count = 1;
tmp = {};
while s.BytesAvailable > 1
    tmp{scan_count} = fscanf(s);
    scan_count = scan_count + 1;
end
% Close the serial port
fclose(s);

%% Go get the photo from the camera to the local PC
% Assumes the explorer views of the camera and current directory are
% already open, ready to copy the file from the camera to the local
% directory

% Create active x server
h = actxserver('WScript.Shell');

% Raise the camera explorer view
temp = h.AppActivate(camera_dir);
pause(1);                   

if temp ~= 1
    error('Could not raise camera directory');
end

% Work around to get focus to the picture in the camera
h.SendKeys('%{TAB}');
pause(0.1);
h.SendKeys('%{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.05);
h.SendKeys('{TAB}');
pause(0.05);
h.SendKeys('{TAB}');
pause(0.05);
h.SendKeys('{TAB}');
pause(0.05);
h.SendKeys('{TAB}');
pause(0.05);                    
h.SendKeys('{DOWN}');                   
pause(1);

% "Cut" the file from the camera
h.SendKeys('^x');
pause(1);

% Raise the local folder
temp = h.AppActivate(current_dir);
pause(1);
if temp ~= 1
    error('Could not raise local directory');
end

% Work around to get focus to the directory
h.SendKeys('%{TAB}');
pause(0.1);
h.SendKeys('%{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.1);
h.SendKeys('{TAB}');
pause(0.1);
h.SendKeys('{DOWN}');
pause(0.1);

% "Paste" the picture from the camera
h.SendKeys('^v');
% Let the file get moved
pause(5);

% Copy the filename of the new picture to the clipboard
h.SendKeys('{F2}');
pause(0.1);
h.SendKeys('^c');
% Let the filename get picked up by the clipboard
pause(0.1);

%% Back to MATLAB, create the .bat file to raise Nikon NX-D to convert to TIFF
% Back to MATLAB
temp = h.AppActivate('MATLAB R2019a');

if temp ~= 1
    error('Could not raise MATLAB window');
end

% Get the filename of the picture from the clipboard
pic_filename = clipboard('paste');

% Create the bat file to launch Nikon NX-D
fid = fopen('test.bat', 'w');

fprintf(fid, 'cd \\\r\n');
fprintf(fid, 'cd "Program Files"\r\n');
fprintf(fid, 'cd Nikon\r\n');
fprintf(fid, 'cd "Capture NX-D"\r\n');
fprintf(fid, 'cd Module\r\n');
fprintf(fid, ['start "" "CaptureNX-D.exe" ' parse_dir_add_slash(current_dir) '\\' pic_filename '.NEF"\r\n']);
fprintf(fid, 'exit\r\n');
fclose(fid);
pause(1);

%% Run the bat file to raise Nikon Capture NX-D
% Run the bat file
status = system('test.bat &');

% Let NX-D open
pause(12);

% Get the java robot
import java.awt.Robot
import java.awt.event.*
my_robot = Robot;

% Bring the window to the foreground
temp = h.AppActivate('Capture NX-D');

if (temp ~= 1)
    error('Could not raise NX-D');
end

disp('Kick off conversion');

% Work around to get proper focus in NX-D
% Press the tab key twice
pause(0.5);
my_robot.keyPress(9);
pause(0.5);
my_robot.keyRelease(9);
pause(0.5);
my_robot.keyPress(9);
pause(0.5);
my_robot.keyRelease(9);

% Kick off the conversion, i.e., CTRL-E
pause(0.2);
my_robot.keyPress(17);
pause(0.2);
my_robot.keyPress(69);
pause(0.2);
my_robot.keyRelease(69);
pause(0.2);
my_robot.keyRelease(17);
% Let window raise
pause(0.8);
% Press enter (assumes TIFF 16 bit already selected)
my_robot.keyPress(10);
pause(0.2);
my_robot.keyRelease(10);
% NX-D will raise the window for conversion - it will force focus as it
% converts
pause(5);

%% Back to MATLAB to load the file
figure(1);
clf
text(0.4, 0.4, 'Waiting for TIFF creation...');
set(1, 'currentchar', ' ') 
title_str = {'.', '..', '...', '....'};
title_count = 0;

% Wait for the TIF file to be created, or until the user presses something
while get(1, 'currentchar') == ' '
    % Set MATLAB to be the window of focus
    h.AppActivate('MATLAB R2019a');
    
    % Bring the figure window to the top
    figure(1);
    
    % Give it the changing title so the user knows code is executing
    title(title_str{title_count + 1});
    title_count = mod(title_count + 1, 4);
    
    temp = dir([pic_filename '.tif']);
    
    if isempty(temp)
        pause(0.5);
    else
        set(1, 'currentchar', 'a');
    end
end

% Expect the .tif file to be present
if isempty(temp)
    error('File not created');
end

% Activate MATLAB again
temp = h.AppActivate('MATLAB R2019a');

if temp ~= 1
    error('Failed to raise MATLAB');
end

% Load the picture
temp_pic = imread([pic_filename '.tif']);

% Show the picture
figure(2);
imshow(temp_pic);

Discussions