Controlling MFT turntable from external software

There are two options available to programmatically control turntable.

Option 1: Communicate with turntable directly via USB

When turntable is connected to PC via USB, it is represented as virtual COM port. You can communicate with turntable using the text protocol described at this page. Sending commands manually and looking at received messages using software like PuTTY can be useful for troubleshooting and development.

This approach is programming language and OS agnostic, but requires effort to correctly implement.

Option 2: Use .NET turntable API libraries

We provide ready to use turntable control API for .NET with the following features:

Supported devices and installation

In order to use our libraries in your .NET application, please install one or more of the following NuGet packages:

Upon installing any of these packages NuGet should automatically install the following dependencies:

Turntable specific packages also have following dependencies:

Device and features support will be extended over time as we continue to develop new turntable models and Photo3DStudio.

Note: Due to the fact that System.IO.Ports requires windows-specific functionality, MFT API is currently unlikely to work on non-Windows OS. Please contact support if you need to use this library on non-Windows machines.

Working with API

The following guide assumes most common use case: you have installed Mft and DeviceDiscovery packages and have your turntable connected via USB.

Documentation

Documentation for all our packages can be found at https://developer.photomechanics.com/dotnet-api/annotated.html where you can find detailed description of all types in our packages.

Instantiation of the API

The following example shows how to open connection with turntable (assuming it is visible in system device manager as COM4):

using (var port = new SerialPort("COM4")) { port.Open(); using (var messagesTransport = new MftSerialMessagesTransport(port)) using (var commandRunner = new MftCommandRunner(messagesTransport)) using (var api = new MftApi(commandRunner)) { await api.Initialize(); // Use api } }

Note that SerialPort, MftCommandRunner and MftApi (which is implementation of ITurntableApi) are disposable and also wrap each other. If any of them is disposed, all other components will be disposed. For example, if messages transport encountered an error (lost connection or received invalid text), it will log this event and trigger disposal of serial port and command runner, which will trigger disposal of API object itself.

Subscribe for Disposed event of ITurntableApi to handle this situation (for example, attempt to reconnect). Disposal of all components will also be logged.

You can automatically connect to USB turntable using DeviceDiscovery package. The ITurntableManagerService will do all the work for you:

using (var turntableManagerService = new TurntableManagerService()) { await turntableManagerService.SearchForDevicesAsync(); if (turntableManagerService.Api == null) throw new InvalidOperationException("Turntable not found"); // Use turntableManagerService.Api }

Using ITurnTableApi

ITurntableApi serves as the holder of components. Each component type encapsulates some group of functionality. For instance, all turntables have IRotationProvider that contains basic methods for rotation. If turntalbe uses stepper motor, it is likely to have IEngineLockControlProvider and so on.

The following example shows how to perform simple 360 degree rotation:

private static async Task TestRotate(ITurntableApi api) { // Print version string, see USB protocol description for details about firmware version info string Console.WriteLine(api.GetComponent<IVersionInfoProvider>().GetVersionInfo().Result); // Example usage of component-based turntable API var rotationProvider = api.GetComponent<IRotationProvider>(); await rotationProvider.SetTargetSpeed(20); // Set desired peak speed in degrees per second await api.GetComponent<IAccelerationControlProvider>().SetAcceleration(15); // Set acceleration in degrees per second^2 // Set notification interval // You can subscribe to corresponding event of this component to track progress of rotation await api.GetComponent<IRotationFeedbackProvider>().SetDegreesPerNotify(1); // Perform actual rotation await rotationProvider.RotateDegrees(360); // You can also use lower-level API to send commands directly corresponding to commands from text protocol }

Note that GetComponent will return null if requested component is not supported by your device. You can also use HasComponent method if you only need to check for feature support.