Adding Support for Additional Cameras

Camera Controller talks to all the different cameras using a common interface called ICC_Camera3.  This makes it fairly simple to add support for additional cameras.  All you have to do is get that camera's SDK from the camera manufacturer and write a straightforward support module that implements the ICC_Camera3 interface.  Click the links below for more information.

Creating the VB project
Implementing the ICC_Camera3 interface
Building the ActiveX DLL
Adding the new support module to Camera Controller
Using your new support module

Notes about the interface
Interface definitions

Sample source code


Creating the VB project

  1. Create a new ActiveX DLL project using Microsoft VB 6.0 SP5 or better.
  2. Give the project a good name that describes the type of camera support modules contained in the project.  For example for the Olympus V2.0 SDK cameras, you might use OlyV20.  Keep in mind that one ActiveX dll can contain a number of Class modules that support a number of different cameras.
  3. Select Project/References from the VB menu.  Look for the "Pine Tree Computing, LLC Camera Interface" type library, select it, and click OK to add the reference.  Note: The type library was installed when you installed Camera Controller.
  4. Create a new class that will support the camera interface for each camera model supported in the project.  Give the class a good name that will describe the camera.  For example for the C3030 you might call the class CC3030.  Again, one project can have several classes, each supporting a different model camera.

Implementing the ICC_Camera3 interface.

  1. At the top of the new class module add the line "Implements ICC_Camera3"
  2. Now you will add the code to implement each of the properties and methods of the ICC_Camera3 interface.  You can also add any other procedures you like, however, Camera Controller will only call the methods and properties of the ICC_Camera3 interface.
  3. Make sure to implement all the interfaces properties and methods.

Building the ActiveX DLL

  1. Build the ActiveX dll.  Building the dll adds all the registry entries Camera Controller will need to locate the dll.
  2. Once you have a camera support module built, we suggest you enable binary compatibility.  This will make it easier for Camera Controller to find the correct ActiveX component while you're troubleshooting.  Run the project in VB before running camera controller and camera controller will call into VB, making it easy to troubleshoot.

Adding the new support module to Camera Controller

  1. Run Camera Controller.
  2. Select View/Advanced Tools from the Camera Controller menu.
  3. Now select Tools/Add Camera Model from the menu.
  4. In the Add/Edit Camera Model dialog, enter a descriptive name for the camera in the Camera model name field.  Give it a name like Olympus C-3030 Zoom.
  5. Enter the progid of the new class contained in your ActiveX dll.  For example, if you used the project and class names mentioned in the previous steps, the prog id would be OlyV20.CC3030.
  6. Now click OK to add the new camera definition to the registry.

Using your new support module

  1. Once the camera definition has been added, you can use the Tools/Select Camera Model menu item to select your new camera support module.

Notes about using the Interface

Overview

The interface works like a language translator, communicating with Camera Controller using a language it understands and communicating with the camera using the manufacturer's SDK.  The interface defines the language (API) that is used to communicate with Camera Controller and it is up to the support module to translate the request into something the camera can understand.

For example, Camera Controller has no idea how to tell a particular camera to take a picture.  When camera controller wants to take a picture, it simply calls the CapturePic method of the ICC_Camera3 interface.  The camera support module for the selected camera model then receives control and translates the request into the code necessary to command the camera to take a picture.  The code to take a picture is typically very simple as in the following example from the Olympus C3030 support module supplied with Camera Controller.

Private Function ICC_Camera3_CapturePic(ByVal lngResolution As Long) As Long

   On Error GoTo eh:

   ConnectCamera

   WaitForCamera
   cam.propResolution = lngResolution
   WaitForCamera
   cam.propExpoBias = m_bias
   WaitForCamera
   cam.propIsoSpeed = m_iso
   WaitForCamera
   cam.propMetering = m_meteringmode
   WaitForCamera
   cam.propWhiteBalance = m_whitebalance
   WaitForCamera
   cam.Capture
   WaitForCamera
   ICC_Camera3_CapturePic = cam.propPicCount

   DisconnectCamera

   Exit Function

eh:
   UserErr.CopyErrorInfo Err
   DisconnectCamera
   UserErr.Raise UserErr.Number, "CICC_SX351.CapturePic!" & UserErr.Source, _
      UserErr.Description, UserErr.HelpFile, UserErr.HelpContext
End Function

As you can see, all the support module has to do is set any non-persistent camera parameters from stored member variables, capture the picture, and return a number that uniquely identifies the picture.

Property Values

When it comes to property values, Camera Controller does not know what the actual values are for the various camera parameters. Instead, Camera Controller leaves it up to the camera support module to translate between property values it defines and specific camera values. Camera Controller uses two techniques to do this.

In the first technique, Camera Controller defines several enumerations that are used by Camera Controller to set values. The enumerations are ICC_FlashMode, ICC_FocusMode, ICC_LCDMode, ICC_MeteringMode, ICC_ProgramMode, and ICC_Speed. Each enumeration defines a list of values Camera Controller considers valid for the particular property. With this technique, Camera Controller defines the list of valid values.

For example, the following code snippets from the C3030 support module supplied with Camera Controller show how to load the list of values and get and set the property values for the MeteringMode property. Note the use of the ICC_MeteringMode enumeration to set the ItemData property of the combobox item in LoadComboWithMeteringModes. Also note how the Get/Let procedures translate between the Camera Controller value in the ICC_MeteringMode enumeration and the constants (MM_PATTERN, and MM_SPOT) defined in the Olympus SDK.

' load the valid values into a combo box
Private Sub ICC_Camera3_LoadComboWithMeteringModes(cmb As Object)
   On Error GoTo eh:

   cmb.Clear
   cmb.AddItem "Normal"
   cmb.ItemData(cmb.NewIndex) = ICC_MeteringMode.mmNormal
   cmb.AddItem "Spot"
   cmb.ItemData(cmb.NewIndex) = ICC_MeteringMode.mmSpot

   Exit Sub
eh:
   Err.Raise Err.Number, "CICC_SX351.ICC_Camera3_LoadComboWithMeteringModes!" & _
     Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub

' set the camera metering mode
Private Property Let ICC_Camera3_MeteringMode( _
   ByVal lngNewMode As ICC_MeteringMode)
   On Error GoTo eh:

   Dim vMsg(0) As Variant

   Select Case lngNewMode
   Case ICC_MeteringMode.mmCenterWeighted
      vMsg(0) = lngNewMode
      UserErr.Raise ICC_Errors.ERROR_NOT_SUPPORTED_BY_CAMERA, , , , , vMsg
   Case ICC_MeteringMode.mmNormal
      m_meteringmode = MM_PATTERN
   Case ICC_MeteringMode.mmSpot
      m_meteringmode = MM_SPOT
   Case Else
      vMsg(0) = lngNewMode
      UserErr.Raise ERRORS.ERROR_INVALID_PARAMETER, , , , , vMsg
   End Select

   ConnectCamera
   cam.propMetering = m_meteringmode
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.MeteringMode(Set)!" & Err.Source, _
     Err.Description, Err.HelpFile, Err.HelpContext
End Property

' retrieve the camera metering mode property
Private Property Get ICC_Camera3_MeteringMode() As ICC_MeteringMode
   On Error GoTo eh:

   ConnectCamera

   Select Case cam.propMetering
   Case CAM_METERING_MODE.MM_PATTERN
      ICC_Camera3_MeteringMode = mmNormal
   Case CAM_METERING_MODE.MM_SPOT
      ICC_Camera3_MeteringMode = mmSpot
   End Select
  
   DisconnectCamera
  
   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.MeteringMode(Get)!" & Err.Source, _
     Err.Description, Err.HelpFile, Err.HelpContext
End Property

In the second technique, Camera Controller allows the camera support module to define the list of valid parameters. The ICC_Camera3 interface includes several "LoadCombo" methods that allows the camera support module to load the list of valid values for the applicable properties. In particular, the properties that use this technique are Apertures, Bias, Quality, and Shutters. In this technique, when the "LoadCombo" method is called, the camera support module loads the passed combo box with the text strings for each valid value and assigns a unique ID to each value using the combobox's ItemData property. Later, when Camera Controller wants to set the properties, it sends the value in the ItemData property of the selected value to the applicable Property Let function in the ICC_Camera3 interface.

For example, the following code snippets from the C3030 support module supplied with Camera Controller show how to load the list of values and get and set the property values for the Bias property. Note the use of the constants supplied by the Olympus SDK to set the ItemData property of the combobox item in LoadComboWithApertures. Also note how the Get/Let procedures translate the values from the constants defined in the Olympus SDK into valid values for the camera metering mode property.

' load valid values into passed combobox
Private Sub ICC_Camera3_LoadComboWithBias(cmb As Object)
   On Error GoTo eh:

   cmb.Clear

   cmb.AddItem "+2.0"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p20
   cmb.AddItem "+1.7"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p17
   cmb.AddItem "+1.5"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p15
   cmb.AddItem "+1.3"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p13
   cmb.AddItem "+1.0"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p10
   cmb.AddItem "+0.7"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p7
   cmb.AddItem "+0.5"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p5
   cmb.AddItem "+0.3"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p3
   cmb.AddItem "0.0"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.p0
   cmb.AddItem "-0.3"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m3
   cmb.AddItem "-0.5"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m5
   cmb.AddItem "-0.7"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m7
   cmb.AddItem "-1.0"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m10
   cmb.AddItem "-1.3"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m13
   cmb.AddItem "-1.5"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m15
   cmb.AddItem "-1.7"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m17
   cmb.AddItem "-2.0"
   cmb.ItemData(cmb.NewIndex) = CAM_BIAS.m20

   Exit Sub
eh:
   Err.Raise VBA.Err.Number, "CICC_SX351.ICC_Camera3_LoadComboWithBias!" & _
      VBA.Err.Source, VBA.Err.Description, VBA.Err.HelpFile, VBA.Err.HelpContext
End Sub

' Set Bias property value
Private Property Let ICC_Camera3_Bias(ByVal dblBias As Double)
   On Error GoTo eh:

   m_bias = dblBias - 100

   ConnectCamera
   cam.propExpoBias = CLng(dblBias - 100)
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.Bias(Set)!" & _
      Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Property

' Get Bias property value
Private Property Get ICC_Camera3_Bias() As Double
   On Error GoTo eh:

   ConnectCamera
   ICC_Camera3_Bias = CDbl(cam.propExpoBias + 100)
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.Bias(Get)!" & _
      Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Property

Persistent versus non-persistent properties

As is the case with the Olympus cameras, some cameras may lose some of their camera properties when you disconnect from the camera.  Properties that hold their values when you disconnect from the camera are called persistent properties.  Those that lose their values are called non-persistent properties.  Camera support modules should take appropriate action to save the values of non-persistent properties when they disconnect from the camera.  This easiest way to do this is to store the property values in member variables and apply them to the camera when they are needed.  For example the following Property Let procedure might be an example of how to save a non-persistent property such as whitebalance.  Note that the procedure saves the incoming value into a class member variable and then applies the value to the camera.  Later when capturing the picture, the value from the member variable can be used to update the camera property.

Private Property Let ICC_Camera3_WhiteBalance(ByVal dblWhiteBalance As Double)
   On Error GoTo eh:
  
   m_whitebalance = dblWhiteBalance
   ConnectCamera
   cam.propWhiteBalance = dblWhiteBalance
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.WhiteBalance(Set)!" & _
      Err.Source, _ Err.Description, Err.HelpFile, Err.HelpContext
End Property

To use a property stored in this manner, you would simply reference the stored member variable as is show in the following Property Get procedure.

Private Property Get ICC_Camera3_WhiteBalance() As Double)
   On Error GoTo eh:
  
   ICC_Camera3_WhiteBalance = m_whitebalance
   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.WhiteBalance(Get)!" & _
      Err.Source, _ Err.Description, Err.HelpFile, Err.HelpContext
End Property

The same property, if it were persistent - in the Olympus SDK it is not - could be stored directly on the camera object supplied by the Olympus SDK as follows.

Private Property Let ICC_Camera3_WhiteBalance(ByVal dblWhiteBalance As Double)
   On Error GoTo eh:
  
   ConnectCamera
   cam.propWhiteBalance = dblWhiteBalance
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.WhiteBalance(Set)!" & _
      Err.Source, _ Err.Description, Err.HelpFile, Err.HelpContext
End Property

To use a property stored in this manner, you would simply reference the camera property on the SDK's camera object as is show in the following Property Get procedure.

Private Property Get ICC_Camera3_WhiteBalance() As Double
   On Error GoTo eh:
  
   ConnectCamera
   ICC_Camera3_WhiteBalance = cam.propWhiteBalance
   DisconnectCamera

   Exit Property
eh:
   UserErr.Raise Err.Number, "CICC_SX351.WhiteBalance(Get)!" & _
      Err.Source, _ Err.Description, Err.HelpFile, Err.HelpContext
End Property


The ICC_Camera1 Interface

Properties:

Methods:

CapturePic

Purpose:

called to make the camera take a picture.

Inputs:

lngResolution - a number that uniquely identifies a resolution supported by the camera.  The number passed into Capture pic will be taken from the ItemData property of the applicable item in a combox box that is filled with a call to ICC_Camera1.LoadComboWithQuality.

Outputs:

Returns a long that is used to uniquely identify the resulting picture stored on the camera media.

CheckForCamera

Purpose:

Called to see if a camera is connected to the indicated communications port.

Inputs:

lngPort - a number that identifies the communications port to be checked.  The number passed from Camera Controller will be taken from the ItemData field of the applicable item in a combo box filled will a call to ICC_Camera1.LoadComboWithPorts.

lngSpeed - a number that identifies the communications speed to use on the selected port.  The number passed from Camera Controller will be taken from the ItemData property of the applicable item in a combo box filled with a call to LoadComboWithSpeeds.

Outputs:

Returns True if a camera is found on the indicated communications port.

Returns False if not camera was found on the indicated communications port.

Sets the ICC_Camera1.CameraStatus property to the applicable value from the ICC_CameraStatus enum.

DeletePic

Purpose:

Called to delete a picture from the camera media

Inputs:

lngPicNum - a long that uniquely identifies a picture stored on the camera media.

Outputs:

None.

DownloadPic

Purpose:

Called to download (but not delete) a picture from the camera media.

Inputs:

lngPicNumber - a long that uniquely identifies a picture stored on the camera media.

Outputs:

Returns a byte array containing the bytes of the picture downloaded from the camera.

EnumerateCameras

Purpose:

Called to obtain a list of the cameras that are currently connected to a multi-camera system.

Inputs:

None.

Outputs:

Returns a (0 to 2, 0 to n) variant array describing the connected cameras where n is the number of connected cameras minus 1.  Array element ( 0, n) is a unique number that identifies camera n, element ( 1, n) is a string describing camera n, and element ( 2, n) is a string containing the model name of camera n.

GetExposureProps

Purpose:

Called to retrieve the current exposure settings of the camera.

Inputs:

None.

Outputs:

lngMode - a value from the ICC_ProgramMode enum indicating the current program mode of the camera.

dblAperture - a double word value indicating the current aperture setting of the camera.  The value passed is taken from ItemData property of the applicable item in a combo box filled with a call to ICC_Camera1.LoadComboWithApertures.

dblShutter - a double word value indicating the current shutter speed setting of the camera.  The value passed is taken from ItemData property of the applicable item in a combo box filled with a call to ICC_Camera1.LoadComboWithShutters.

GetPicProps

Purpose:

Called to retrieve the exposure settings of a picture stored on the camera media.

Inputs:

lngPicNum - a long that uniquely identifies a picture stored on the camera media.

Outputs:

dblAperture - a double word value that indicates the aperture setting use to take the indicated picture.

dblShutter - a double word value that indicates the shutter speed used to take the indicated picture.

lngOrientation - a long value that indicates the orientation of the indicated picture.

strTime - a string containing the time the picture was taken

dblBias - a double word value indicating the exposure bias used to take the indicated picture.

lngMeteringMode - a long value indicating the metering mode used to take the indicated picture.

lngWhiteBalance - a long value indicating the white balance reference used to take the indicated picture.

lngFlashUsed - a long value indicating if the flash was used to take the indicated picture.

lngZoom - a long value indicating the zoom length used to take the indicated picture.

GetPreviewPic

Purpose:

Called to take a preview picture.

Inputs:

boolUseCapture - a boolean indicating if a full size picture should be used for the preview.

lngResolution - a long indicating the resolution to use to capture a full sized picture preview.  The value passed is taken from the ItemData property of the applicable item in a combo box filled with a call to ICC_Camera1.LoadComboWithQuality.

Output:

Returns a long number that uniquely identifies the commanded picture stored on the camera media.

Init

Purpose:

Called to initialize the camera support module and establish communications with the camera.

Inputs:

lngPort - a number that identifies the communications port of the camera.  The number passed from Camera Controller will be taken from the ItemData field of the applicable item in a combo box filled will a call to ICC_Camera1.LoadComboWithPorts.

lngSpeed - a number that identifies the communications speed to use on the selected port.  The number passed from Camera Controller will be taken from the ItemData property of the applicable item in a combo box filled with a call to LoadComboWithSpeeds.

Outputs:

Initializes properties such as ICC_Camera1.Bias, ICC_Camera1.ISO, etc., ..., to the current camera values.

LoadComboWithApertures

Purpose:

Called to load a combo box with valid aperture values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular aperture setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithBias

Purpose:

Called to load a combo box with valid bias values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular bias setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithFlashModes

Purpose:

Called to load a combo box with valid flash mode values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular flash mode setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithFocusModes

Purpose:

Called to load a combo box with valid focus mode values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular focus mode setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithISOs

Purpose:

Called to load a combo box with valid ISO rating values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular ISO rating setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithMeteringModes

Purpose:

Called to load a combo box with valid metering mode values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular metering mode setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithPorts

Purpose:

Called to load a combo box with valid port values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular port setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithProgramModes

Purpose:

Called to load a combo box with valid program mode values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular program mode setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithQuality

Purpose:

Called to load a combo box with valid quality (resolution) values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular quality setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithShutters

Purpose:

Called to load a combo box with valid shutter values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular shutter setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithSpeeds

Purpose:

Called to load a combo box with valid communications port speed values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular speed setting and the ItemData property indicates a long value that uniquely identified the setting.

LoadComboWithWhiteBalance

Purpose:

Called to load a combo box with valid white balance values for the camera.

Inputs:

cmb - a handle to a combo box control

Outputs:

Loads the combo box with strings and their associated ItemData properties.  The strings describe a particular white balance setting and the ItemData property indicates a long value that uniquely identified the setting.

SetExposureProps

Purpose:

Called to set the current exposure properties for the camera.

Inputs:

lngMode - the program mode to be set.  The value must be one of the values in the ICC_ProgramMode enum

dblAperture - a double word value that indicates the aperture setting to set.  The value will be taken from the ItemData property of the applicable item in a combo box filled with a call to ICC_Camera1.LoadComboWithApertures.

dblShutter - a double word value that indicates the shutter speed to set.  The value will be taken from the ItemData property of the applicable item in a combo box filled with a call to ICC_Camera1.LoadComboWithShutters.

Outputs:

Sets the camera exposure properties.

Shutdown

Purpose:

Called to shutdown camera communications and clean up component data before termination.

Inputs:

None.

Outputs:

Closes camera communications and deletes references to component data.

TranslateExposureSettings

Purpose:

Called to translate camera specific exposure setting values to strings suitable for display.

Inputs:

lngMode - a long that indicates a valid program mode for the camera.

dblAperture - a double word value that indicates a valid aperture setting for the camera.

dblShutter - a double word value that indicates a valid shutter settings for the camera.

Outputs:

strMode - a string containing the translated program mode indicated by the input value lngMode suitable for display.

strAperture - a string containing the translated aperture setting indicated by the input value dblAperture suitable for display.

strShutter - a string containing the translated shutter setting indicated by the input value dblShutter suitable for display.

Email us for sample source code.

Is your camera already supported?  Check out the supported camera list for information about the supported cameras, firmware versions, and other support information.

Go To Camera List

 

Got a comment? Need help? Click on the CC Support button above or check out the Camera Controller forum.

Go To Forum