# NikonD3Server Console Application

## Introduction

The `nikonD3Server` is a multi-threaded application designed to trigger and download images from a Nikon DSLR (D3 and D700) in an autonomous fashion. Because of the nature of the USB PTPP interactions and their timing, multiple threads have been programmed in order to avoid unresponsive communications and improve overall acquisition speeds. Those threads are as follows:

- main thread: Used for initialization and tcp server
- trigger thread: Used for uart issued camera hardware triggering on a fixed interval.
- camera thread: Used for camera USB PTPP interactions, including configuration and image downloads.

## Program Usage

The `nikonD3Server` is configured from a windows-style INI file. Program execution will not occur if the file is not specified as an arguments (i.e. `nikonD3Server.exe <ini filename>`) or if the default file `nikonD3Server.ini` is not present in the working directory. 

## Operation 

On program start the ini file is loaded, and an attempt to find the camera on the USB bus occurs. Also a "syslog"-style log file is written out as specified in the INI file. One note on the INI file, proper escapes for backslashes must exist in any file path fields in order to work properly.

There are three main commands the user will want to interact with the server during runtime via the TCP protocol:

- Camera Connection: Checking or changing the connection status to the camera.
- Acquisition Interval: The time period when frame acquisition is hardware triggered to the camera.
- Acquisition Enabling: Start or stop acquiring. 

When images are asked to acquire more quickly than they can be downloaded from the camera, the DRAM onboard the camera begins to store the images not yet downloaded. The program will only allow 15 triggers without image downloads. However, the ability to separate triggering and acquisition allows for smaller intervals because the staggered downloads delinearize the acquisition steps and allow for downloads from DRAM while another images is being read in from the sensor. For this reason it is important for the user to note the differences in frame download counts and trigger counts. Too large of a difference implies lost images, false triggering, or a problem in the camera. 

## Requirements

Compiling this program requires the use of Microsoft Visual Studio. Initial development was done under *MSVS 2012 for Desktop*. Runtime requirements for the executable are Windows 7 or newer on a computer providing USB 1.0+ and a single serial port (server only).

## Flowchart

![UML Chart of the application](/nikonD3Server.png "UML Chart")

## Sample INI File

	# Sample INI FILE
	# ---------------------------------
	#	file: nikonD3Server.ini
	#	author: Eric J Martin
	#			2014 MBARI
	# ---------------------------------

	# SERVER SETTINGS
	[server]

	# port is any avaiable tcp port on your machine.
	port=2020

	# currently the code only supports one client
	maxclients=1

	# this is the file name and path for the operating syslog style log.
	logfilename="E:\\\data\nikonD3server.log"

	# CAMERA SETTINGS
	[camera]

	# This setting is deprecated
	pretrigger=0

	# Initial value for image triggering interval.
	interval=5000

	# This prefix should also contain the absolute path for destination
	# images. The prefix is appended with the trigger time and date as well.
	fileprefix="E:\\\\data\"

	# TRIGGER SETTINGS
	[trigger]
	
	# string of the comm port name windows serial only.
	serialport="COM2"
	
	# baudrate in in bps, only standard rates are recognized.
	baudrate=600
	
	# bits per character: only 6/7/8
	bits=8

	# parity: string with E/O/N
	parity="N"

	# stop bits: 1 or 0
	stop=1

	# DIGITAL OUT
	[laserpower]

	# string of the comm port name windows only. The UART must have handshaking lines.
	serialport="COM1"

	# baudrate in in bps, only standard rates are recognized.
	baudrate=600

	# bits per character: only 6/7/8
	bits=8

	# parity: string with E/O/N
	parity="N"
	
	# stop bits: 1 or 0
	stop=1
