Multiple ScanSync Support¶
Applicability
This document describes how the Pinchot API and ScanHeads handle the presence of more than one ScanSync device on their network segment. If you use one ScanSync per ScanSystem, then you can safely skip this document. However, as network routing can be complex, it is suggested to read this document if you employ more than one ScanSync anywhere on your network, so that you are aware of potential consequences. JoeScan recommends using explicit ScanSync mapping as best practice in this case.
Background¶
The ScanSync Module broadcasts timing and encoder information via UDP datagrams, allowing all ScanHeads to synchronize their time base and keep track of encoder and input state.
In API v16.1 and below, if multiple ScanSync modules were broadcasting on a network segment, the ScanHeads potentially received conflicting information, leading to undefined behavior and failures in scanning.
In API v16.2, we introduced a stopgap measure, intended to at least reduce the chance of conflicts: if a ScanHead receives data from more than one ScanSync, the data from the one with the lowest serial number is used and the others are ignored.
In API v16.3, we fully support up to three ScanSyncs on the same network segment, by allowing you to designate a Primary ScanSync and up to two additional Auxiliary ScanSync on a per-ScanSystem basis in a process we call Mapping. This is entirely optional: if you don't operate more than one ScanSync, you can skip the rest of this document.
Default Behaviour in 16.3¶
By default, the ScanSync with the lowest serial number is considered Primary, and will be used for synchronization. All other discovered ScanSyncs are auto-mapped.
Auto-Mapping¶
If you don't explicitly map the devices to your ScanSystem (see below), any additional ScanSyncs will be automatically mapped as Aux1 and Aux2 in order of ascending serial number.
Explicit Mapping¶
If you perform an explicit mapping (see below), you must map all ScanSync devices you are interested in - unmapped ScanSyncs are ignored and will NOT be present in the received profile data.
Discovery¶
The API keeps an internal list of all discovered ScanSync serial numbers by listening on the network at all times. The API supplies calls to query this list:
var scanSystem = new ScanSystem(ScanSystemUnits.Inches);
List<DiscoveredScanSync> discoveredScanSyncs = scanSystem.DiscoverScanSyncs();
int32_t max_count = 5;
jsScanSystem scan_system = jsScanSystemCreate(JS_UNITS_INCHES);
scansyncs_discovered = new jsScanSyncDiscovered[max_count];
int32_t found = jsScanSystemGetDiscovered(scansystem, scansyncs_discovered, max_count);
// return value is the number of devices found
Explicit Mapping¶
Example mapping 3 ScanSync units
jsScanSystem scan_system = jsScanSystemCreate(JS_UNITS_INCHES);
scan_system.SetScanSyncMapping(22235,22234,22233);
// maps unit with serial 22235 to be Primary, 22234 as Aux1 and 22233 as Aux2
// you will get an exception if one of them is not seen on the network
jsScanSystem scan_system = jsScanSystemCreate(JS_UNITS_INCHES);
scan_system.SetScanSyncMapping(22235,22234);
// maps unit with serial 22235 to be Primary, 22234 as Aux1
// you will get an exception if one of them is not seen on the network
jsScanSystem scan_system = jsScanSystemCreate(JS_UNITS_INCHES);
scan_system.SetScanSyncMapping(22235);
// maps unit with serial 22235 to be Primary
// you will get an exception if it is not seen on the network
jsScanSystem scan_system = jsScanSystemCreate(JS_UNITS_INCHES);
jsScanSystemSetScanSyncEncoder(scan_system, 22235, 22234, 22233);
// return value is negative (error) if one of them is not seen on the network
Resulting Profile Data¶
In both cases, auto-mapped and explicitly mapped, the Encoder values of all ScanSyncs are delivered a part of the Profile structure.
Each IProfile
object contains a dictionary, IDictionary<Encoder, long> EncoderValues { get; }
, the key is an enum of type Encoder
with the members Encoder.Main
, Encoder.Auxiliary1
and Encoder.Auxiliary2
, corresponding to up to three ScanSync devices.
Each jsProfile
contains an array encoder_values
, the index is defined by the enum jsEncoder
with the values
JS_ENCODER_MAIN
, JS_ENCODER_AUX_1
and JS_ENCODER_AUX_2
.
SYNC Input
As of API v16.3, we only support reading the value of the SYNC input for the primary ScanSync. This may change in future releases.