Platforms to show: All Mac Windows Linux Cross-Platform

/EyeOne/EyeOne Demo
Feedback.

Function:
You find this example project in your Plugins Download as a Realbasic project file within the examples folder: /EyeOne/EyeOne Demo
This example is the version from Tue, 5th Apr 2010.
Notes: Last modified: Tue, 5th Apr 2010
Class App
Inherits Application
// Constants
Const kFileQuitShortcut = Ctrl+Q
Const kFileQuit = E&xit
Const kEditClear = &Delete
End Class

Class Window1
Inherits Window
// Controls
ControlInstance
End ControlInstance
ControlInstance
End ControlInstance
ControlInstance
Sub Action() Handles Event
// Attempt connection to EyeOne
If (MyEyeOneClass.DoCalibration() = True) Then
EditField1.Text = EditField1.Text + "Calibrated..." + EndOfLine
Else
EditField1.Text = EditField1.Text + "Not Calibrated..." + EndOfLine
End If

End Sub
End ControlInstance
ControlInstance
Sub Action() Handles Event
// Are we connected?
If (MyEyeOneClass.Isi1Connected() = False) Then

ST_DeviceStatus.Text = "EyeOne NOT Connected!"
Return

Else

ST_DeviceStatus.Text = "EyeOne Connected!"
// Fall-Through

End If


// Take measurement?
If (MyEyeOneClass.WasButtonPushed() = False) Then
Return
End If


// Execute measurement
Select Case MeasMode


Case 0
If (MyEyeOneClass.MeasDataSingle() = False) Then
Return
End If


Case 1
If (MyEyeOneClass.MeasDataScan() = False) Then
Return
End If


End Select


// Display results
EditField1.Text = MyEyeOneClass.GetMeasData()

End Sub
End ControlInstance
ControlInstance
Sub Action(Index As Integer) Handles Event
// Set measurement mode
MeasMode = Index

End Sub
End ControlInstance
ControlInstance
End ControlInstance

// Properties
Dim MeasMode As Integer

// Event implementations
Sub Open()
// Attempt connection to EyeOne
If (MyEyeOneClass.Connect() = True) Then
EditField1.Text = EditField1.Text + "Connected..." + EndOfLine + "SDK Version: " + MyEyeOneClass.i1_SDKVersion + EndOfLine
Else
EditField1.Text = EditField1.Text + "Not Connected..." + EndOfLine
End If

End Sub
End Class

Class EyeOneClass
Inherits EyeOneMBS
// Constants
Const i1_MacDLLRelPath = i1C.framework
Const i1_WinDLLRelPath = EyeOne.dll

// Properties
Dim i1_SerialNumber As String
Dim i1_SDKVersion As String
Dim i1_DeviceType As String
Private Dim RefSpectrum As MemoryBlock
Private Dim LastMode As String
Private Dim IsCalibrated As Boolean
Private Dim LastCalTime As Date
Private Dim IsInitialized As Boolean

// Methods
Function Connect() As Boolean
Dim TheFile As FolderItem
Dim ResourcePath As String


// Reset initialization flag
IsInitialized = False


// Load EyeOne SDK
If TargetMacOS = True then


// Load EyeOne framework (Mac)
TheFile = GetFolderItem(i1_MacDLLRelPath)

If (LoadFrameworkFile(TheFile) = False) Then
MsgBox("EyeOne> Error Loading Framework: " + EndOfLine + ResourcePath + EndOfLine + "(" + Str(LibraryLoadError) + ") " + LibraryLoadErrorMessage)
Return (False)
End If


Else


// For Windows, optionally utilize the internally linked version of the DLL
If (LoadInternalDLL() = False) Then
MsgBox("EyeOne> Error Loading Internal DLL" + EndOfLine + "(" + Str(LibraryLoadError) + ") " + LibraryLoadErrorMessage)
Return (False)
End If


// Load EyeOne DLL (PC)
'If (LoadDLL(i1_WinDLLRelPath) = False) Then
'MsgBox("EyeOne> Error Loading DLL: " + EndOfLine + ResourcePath + EndOfLine + "(" + Str(LibraryLoadError) + ") " + LibraryLoadErrorMessage)
'Return (False)
'End If


End If


// Check that we are connected
// NOTE: This is optional based on implementation needs
'If (ErrorCheck(IsConnected()) = True) Then
'Return (False)
'End If


// Reset calibration flag
IsCalibrated = False


// Get device info
GetInfo()


// Calibrate
// NOTE: This is handled by the 'Calibrate' pushbutton
'If (DoCalibration() = False) Then
'Return (False)
'End If


// Set initialization flag
IsInitialized = True


// Success!
Return (True)

End Function
Private Sub GetInfo()
// Skip these this if we are not connected to avoid tripping the error messages (usually only occurs during initial call to Connect())
// NOTE: To avoid cyclical call and a StackOverflowException, we need to directly check the connection status in this implementation
If (IsConnected() = EyeOneMBS.eDeviceNotConnected) Then
i1_SDKVersion = ""
i1_SerialNumber = ""
i1_DeviceType = ""
Return
End If


// Obtain various info from the SDK and device
i1_SDKVersion = GetOption(EyeOneMBS.I1_VERSION).Trim
i1_SerialNumber = GetOption(EyeOneMBS.I1_SERIAL_NUMBER).Trim
i1_DeviceType = GetOption(EyeOneMBS.I1_DEVICE_TYPE).Trim


// Error check
If (i1_DeviceType <> EyeOneMBS.I1_EYEONE) Then
Beep
MsgBox("EyeOne> WARNING! The detected device does not appear to be a valid EyeOne instrument...")
End If


// Error check
If (GetOption(EyeOneMBS.I1_PHYSICAL_FILTER) <> EyeOneMBS.I1_NO_FILTER) Then
Beep
MsgBox("EyeOne> WARNING! The detected device appears to have an invalid filter installed...")
End If

End Sub
Function MeasDataScan(Optional MaxPatchLimit As Integer = 50) As Boolean
Dim NumSamples As Integer


// Error check
If (ErrorCheck(IsConnected()) = True) Then
Return (False)
End If


// Check that we did not switch modes
If (LastMode <> "SCAN_REF") Then


// Switch modes
If (SetMeasModeScan() = False) Then
Return (False)
End If


End If


// Trigger measurement
If (ErrorCheck(TriggerMeasurement()) = True) Then
Return (False)
End If


// Get number of samples
NumSamples = GetNumberOfAvailableSamples()


// Error check
If (NumSamples < 1) Or (NumSamples > MaxPatchLimit) Then
Beep
MsgBox("EyeOne> Measurement Error..." + EndOfLine + "Invalid Measurement Count; Please Try Again...")
Return (MeasDataScan(MaxPatchLimit)) // Recursively structured retries
End If


// Success!
Return (True)

End Function
Private Sub WaitForButton()
// Loop until the instrument key is pressed
// NOTE: This will correctly handle any non-connection issues (and not lock up the app!)
While (KeyPressed() = EyeOneMBS.eKeyNotPressed)
App.DoEvents(50)
'DelayMBS(0.25)
WEnd

End Sub
Private Function ErrorCheck(Result As Integer) As Boolean
// Trap unknown/library errors
If (Result = -1) Then
Beep
MsgBox("EyeOne> Error..." + EndOfLine + "Unknown Error Or Library Not Loaded")
Return (True)
End If


// Report error
If (Result <> EyeOneMBS.eNoError) Then
Beep
MsgBox("EyeOne> Error..." + EndOfLine + GetOption(EyeOneMBS.I1_LAST_ERROR).TitleCase)
Return (True)
End If


// OK
Return (False)

End Function
Sub Reset()
// Reset device
If (ErrorCheck(SetOption(EyeOneMBS.I1_RESET, EyeOneMBS.I1_ALL)) = False) Then
'MsgBox("EyeOne> Device Reset Successfully!")
End If

End Sub
Function GetCalCount() As Integer
// Return number of measurements since last calibration
Return (GetOption(EyeOneMBS.I1_CALIBRATION_COUNT).Val)

End Function
Function GetCalSecs() As Integer
// Return number of measurements since last calibration
Return (GetOption(EyeOneMBS.I1_LAST_CALIBRATION_TIME).Val)

End Function
Private Function CalibrateAbsWhite() As Boolean
// Prompt user
MsgBox("EyeOne> Calibrate Absolute White..." + EndOfLine + "Place instrument in dock and click 'OK'...")


// Calibrate scanning reflectance mode
If (SetMeasModeScan() = False) Then
Return (False)
Else
If (ErrorCheck(Calibrate()) = True) Then
Return (False)
End If
End If


// Calibrate single reflectance mode
If (SetMeasModeSingle() = False) Then
Return (False)
Else
If (ErrorCheck(Calibrate()) = True) Then
Return (False)
End If
End If


// Success!
MsgBox("EyeOne> Absolute White Calibration Successful!")
Return (True)

End Function
Private Function CalibratePapWhite() As Boolean
// Prompt user for scan
MsgBox("EyeOne> Calibrate Paper White..." + EndOfLine + "Place instrument on substrate and click 'OK'...")


// Trigger measurement
If (MeasDataSingle() = False) Then
Return (False)
End If


// Allocate our reference spectrum space
RefSpectrum = NewMemoryBlock(EyeOneMBS.SPECTRUM_SIZE * 4) // Enough for 36 single values (144 Bytes)


// Retrieve the measurement spectrum
If (ErrorCheck(GetSpectrum(RefSpectrum, 0)) = True) Then
RefSpectrum = Nil
Return (False)
End If


// Assign paper white spectrum to scanning measurement mode
If (SetMeasModeScan() = False) Or (RefSpectrum = Nil) Or (ErrorCheck(SetSubstrate(RefSpectrum)) = True) Then
Return (False)
End If


// Assign paper white spectrum to single measurement mode
If (SetMeasModeSingle() = False) Or (RefSpectrum = Nil) Or (ErrorCheck(SetSubstrate(RefSpectrum)) = True) Then
Return (False)
End If


// Success!
MsgBox("EyeOne> Paper White Calibration Successful!")
Return (True)

End Function
Function MeasDataSingle() As Boolean
Dim NumSamples As Integer


// Error check
If (ErrorCheck(IsConnected()) = True) Then
Return (False)
End If


// Check that we did not switch modes
If (LastMode <> "SINGLE_REF") Then


// Switch modes
If (SetMeasModeSingle() = False) Then
Return (False)
End If


End If


// Trigger measurement
If (ErrorCheck(TriggerMeasurement()) = True) Then
Return (False)
End If


// Get number of samples
NumSamples = GetNumberOfAvailableSamples()


// Error check
If (NumSamples <> 1) Then
Beep
MsgBox("EyeOne> Measurement Error..." + EndOfLine + "Invalid Measurement Count; Please Try Again...")
Return (MeasDataSingle()) // Recursively structured retries
End If


// Success!
Return (True)

End Function
Function GetMeasData(Optional AbsIncludePaper As Boolean = True) As String
Dim Densities, TriStimulus, Spectrum As MemoryBlock
Dim Result, NumSamples, PatchIndex, SpectrumIndex, DensityIndex As Integer
Dim L, a, b, X, Y, Z, dC, dM, dY, dK As Double
Dim dC_Paper, dM_Paper, dY_Paper, dK_Paper As Double
Dim ResultString As String


// CUSTOMIZE THE RETURN VALUE TO YOUR IMPLEMENTATION -- THIS IS JUST A FEW EXAMPLES OF DATA YOU CAN OBTAIN


// Allocate buffers for data retrieval
Densities = NewMemoryBlock(EyeOneMBS.DENSITY_SIZE * 4) // Enough for 4 single values (16 Bytes)
TriStimulus = NewMemoryBlock(EyeOneMBS.TRISTIMULUS_SIZE * 4) // Enough for 3 single values (12 Bytes)
Spectrum = NewMemoryBlock(EyeOneMBS.SPECTRUM_SIZE * 4) // Enough for 36 single values (144 Bytes)


// Get number of samples
NumSamples = GetNumberOfAvailableSamples()


// CalibratePapWhite() MUST be called before DensAbsIncludePaper can be used or you will get an error!
If (AbsIncludePaper = False) Then
Result = SetOption(EyeOneMBS.WHITE_BASE_KEY, EyeOneMBS.WHITE_BASE_PAPER) // "Exclude Paper"
Else
Result = SetOption(EyeOneMBS.WHITE_BASE_KEY, EyeOneMBS.WHITE_BASE_ABSOLUTE) // "Include Paper"
End If


// Compose response header
ResultString = "L" + Chr(9) + "a" + Chr(9) + "b" + Chr(9) + "V" + Chr(9) + "C" + Chr(9) + "M" + Chr(9) + "Y" + EndOfLine


// Step through each measurement sample
// NOTE: Start loop at PatchIndex = 1 to skip 'Black Starter' patch used in some scanning targets
For PatchIndex = 0 To NumSamples - 1


// Set up measurement interpretation parameters (Lab)
Result = SetOption(EyeOneMBS.ILLUMINATION_KEY, EyeOneMBS.ILLUMINATION_D50)
Result = SetOption(EyeOneMBS.OBSERVER_KEY, EyeOneMBS.OBSERVER_TWO_DEGREE)
Result = SetOption(EyeOneMBS.COLOR_SPACE_KEY, EyeOneMBS.COLOR_SPACE_CIELab)


// Get measurement values (Lab)
If (ErrorCheck(GetTriStimulus(TriStimulus, PatchIndex)) = True) Then
Return ("")
End If


// Map values (Lab)
L = TriStimulus.SingleValue(0)
a = TriStimulus.SingleValue(4)
b = TriStimulus.SingleValue(8)


//////////


// Set up measurement interpretation parameters (Density)
Result = SetOption(EyeOneMBS.DENSITY_STANDARD_KEY, EyeOneMBS.DENSITY_STANDARD_ANSIT)
Result = SetOption(EyeOneMBS.DENSITY_FILTER_MODE_KEY, EyeOneMBS.DENSITY_FILTER_MODE_AUTO)


// Get measurement values (Density)
// NOTE: DensityIndex indicates which filter was dominant for the specified density reading (0-3 = CMYK)
If (ErrorCheck(GetDensities(Densities, DensityIndex, PatchIndex)) = True) Then
Return ("")
End If


// Map values (Density)
dC = Densities.SingleValue(0)
dM = Densities.SingleValue(4)
dY = Densities.SingleValue(8)
dK = Densities.SingleValue(12)


// THIS CODE IS COMMENTED OUT BUT LEFT AS AN EXAMPLE OF HOW TO EXCLUDE PAPER DENSITY; USEFUL IF YOU WANT
// ABSOLUTE TRISTIMULUS VALUES BUT RELATIVE DENSITY VALUES.
'// If this is the first patch, then we will consider it the 'Paper' patch (we mandate this by design)
'If (PatchIndex = 1) Then
'dC_Paper = dC
'dM_Paper = dM
'dY_Paper = dY
'dK_Paper = dK
'End If
'
'
'// If it is any other patch, and we desire paper density to be excluded, then subtract the paper density from the values before we process them any further
'If (AbsIncludePaper = False) Then // "Exclude Paper"
'dC = dC - dC_Paper
'dM = dM - dM_Paper
'dY = dY - dY_Paper
'dK = dK - dK_Paper
'End If


//////////


// Compose response entry
ResultString = ResultString +_
Format(L, "-##0.00") + Chr(9) + Format(a, "-##0.00") + Chr(9) + Format(b, "-##0.00") + Chr(9) +_
Format(dK, "-##0.000") + Chr(9) + Format(dC, "-##0.000") + Chr(9) + Format(dM, "-##0.000") + Chr(9) + Format(dY, "-##0.000") +_
EndOfLine


//////////


// Get measurement values (Spectrum)
// NOTE: We need this before we can auto-set the paper/substrate spectrum (obviously)
If (ErrorCheck(GetSpectrum(Spectrum, PatchIndex)) = True) Then
Return ("")
End If


// Emit spectrum data
For SpectrumIndex = 0 To EyeOneMBS.SPECTRUM_SIZE - 1

ResultString = ResultString + Format(Spectrum.SingleValue(SpectrumIndex * 4), "##0.000")

If (SpectrumIndex < EyeOneMBS.SPECTRUM_SIZE - 1) Then
ResultString = ResultString + Chr(9)
End If

Next


// Append EOL
ResultString = ResultString + EndOfLine


Next


Return (ResultString)

End Function
Function DoCalibration(Optional CalPaperWhite As Boolean = False) As Boolean
// Reset calibration flag
IsCalibrated = False


// Error check
If (ErrorCheck(IsConnected()) = True) Then
Return (False)
End If


// Show calibration window
'EyeOneCalibrationWindow.Show() // Show a window of your choice for user feedback
MsgBox("EyeOne> Place instrument in base and click OK to perform calibration...")


// Wait for button press
'WaitForButton() // Use this if you display a window and wish to trigger the calibration with a push of the button on the instrument


// Calibrate absolute white
If (CalibrateAbsWhite() = False) Then
'EyeOneCalibrationWindow.Close() // Close the window
Return (False)
End If


// Calibrate paper white
If (CalPaperWhite = True) Then
If (CalibratePapWhite() = False) Then
'EyeOneCalibrationWindow.Close() // Close the window
Return (False)
End If
End If


// Set calibration flag
IsCalibrated = True
LastCalTime = New Date // Set to current time/date


// Close the caliibration window
'EyeOneCalibrationWindow.Close()


// Success!
Return (True)

End Function
Function WasButtonPushed() As Boolean
// Return whether the instrument's button has been pushed
// NOTE: Any value other than an acknowledged keypress (including non-connection issues) indicates 'No'
If (KeyPressed() = EyeOneMBS.eDeviceButtonPressed) Then

// If the key was pressed, but we are not calibrated, then prompt the user (each time they do it!)
// NOTE: We return 'False' so that it should prevent any caller's processing functions to not fire
// as they think the button was never pressed.
If (IsCalibrated = False) Then
Beep
MsgBox("EyeOne> Calibration required before measurements can be taken!")
Return (False)
End If

Return (True)

Else

Return (False)

End If

End Function
Private Function SetMeasModeScan() As Boolean
// Set measurement mode parameters
If (ErrorCheck(SetOption(EyeOneMBS.I1_IS_BEEP_ENABLED, EyeOneMBS.I1_YES)) = True) Then
Return (False)
End If

If (ErrorCheck(SetOption(EyeOneMBS.I1_MEASUREMENT_MODE, EyeOneMBS.I1_SCANNING_REFLECTANCE)) = True) Then
Return (False)
End If

If (ErrorCheck(SetOption(EyeOneMBS.I1_IS_RECOGNITION_ENABLED, EyeOneMBS.I1_YES)) = True) Then
Return (False)
End If

// "Include Paper"
// NOTE: This is CRITICAL and is undocumented within the SDK. To obtain proper tristimulus values INCLUDING PAPER,
// the WHITE_BASE_ABSOLUTE option MUST be set prior to the Calibrate() call!!!
If (ErrorCheck(SetOption(EyeOneMBS.WHITE_BASE_KEY, EyeOneMBS.WHITE_BASE_ABSOLUTE)) = True) Then
Return (False)
End If

// Success!
Return (True)

End Function
Private Function SetMeasModeSingle() As Boolean
// Set measurement mode parameters
If (ErrorCheck(SetOption(EyeOneMBS.I1_IS_BEEP_ENABLED, EyeOneMBS.I1_YES)) = True) Then
Return (False)
End If

If (ErrorCheck(SetOption(EyeOneMBS.I1_MEASUREMENT_MODE, EyeOneMBS.I1_SINGLE_REFLECTANCE)) = True) Then
Return (False)
End If

// "Include Paper"
// NOTE: This is CRITICAL and is undocumented within the SDK. To obtain proper tristimulus values INCLUDING PAPER,
// the WHITE_BASE_ABSOLUTE option MUST be set prior to the Calibrate() call!!!
If (ErrorCheck(SetOption(EyeOneMBS.WHITE_BASE_KEY, EyeOneMBS.WHITE_BASE_ABSOLUTE)) = True) Then
Return (False)
End If

// Success!
Return (True)

End Function
Sub Destructor()
// Perform device reset
// NOTE: This is recommended to avoid Mach-O crashes as well as more reliable
// disconnect from the library.
If (IsInitialized = True) Then
Reset()
End If

End Sub
Function Isi1Connected() As Boolean
// Return a general indication of the EyeOne is connected, online, and functioning
// NOTE: Any value other than an acknowledged device (including 'Library Not Loaded') indicates 'Not Connected'
If (IsConnected() = EyeOneMBS.eNoError) Then
GetInfo() // Update device info (done in case a device is connected after initial call to Connect())
Return (True)
Else
IsCalibrated = False // Reset calibration flag (you must recalibrate if you disconnect and reconnect the device!)
Return (False)
End If

End Function
Function GetMeasCount() As Integer
// Return number of measurements in last reading
Return (GetOption(EyeOneMBS.I1_NUMBER_OF_AVAILABLE_SAMPLES).Val)

End Function
Function Isi1Calibrated() As Boolean
// Return a general indication of the EyeOne is calibrated
Return (IsCalibrated)

End Function
End Class





Links
MBS Filemaker Plugins - Pfarrgemeinde Ministranten Nickenich