Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ac54766
Add EvidentIX85 device adapter for Evident IX85 microscope
nicost Nov 5, 2025
9140f12
Fix build errors in EvidentIX85
nicost Nov 5, 2025
baed8d8
EvidentIX85: Build with C++14, add dependency on MMDevice
nicost Nov 5, 2025
a7d7cd5
EvidentIX85: Fix compile problems related to MMTime.
nicost Nov 5, 2025
83b3220
EvidentI85: Devices are now correctly registered.
nicost Nov 6, 2025
8bbda0e
Clear Busy state when Focus/Nosepiece reach target position
nicost Nov 6, 2025
7bf86f9
Fix race condition between command and monitoring threads
nicost Nov 6, 2025
a0e942a
Fix notification filtering to not skip acknowledgment responses
nicost Nov 6, 2025
4c385bb
Refactor to single-threaded serial port reading architecture
nicost Nov 6, 2025
efbbc15
Make parameter parsing functions robust to prevent crashes
nicost Nov 6, 2025
470bab2
Fix notification detection to distinguish acknowledgments from data
nicost Nov 6, 2025
195d110
Fix Focus Busy state with tolerance-based position comparison
nicost Nov 6, 2025
ff67eea
Set target position and busy state before sending command
nicost Nov 6, 2025
92f1a47
Convert EvidentMagnification to use CMagnifierBase
nicost Nov 6, 2025
438c197
Fix build errors and runtime issues in Magnification device
nicost Nov 6, 2025
2fea358
Add OnMagnifierChanged callback for magnification changes
nicost Nov 6, 2025
f47f32f
Fix shutdown timeout by stopping monitoring thread last
nicost Nov 6, 2025
22bd052
EvidentIX85: Add SafeNosepieceChange feature
nicost Nov 6, 2025
21b2f1e
EvidentIX85: Implement all remaining device classes
nicost Nov 6, 2025
ab09234
EvidentIX85: Fix MirrorUnit1 to use query-based position tracking
nicost Nov 6, 2025
436ce4d
EvidentIX85: Fix missing SetNumPositions calls in Query functions
nicost Nov 6, 2025
f820162
EvidentIX85: Remove incorrect EnableNotifications calls
nicost Nov 6, 2025
de1bfbc
EvidentIX85: Restore EnableNotifications with correct CondenserTurret…
nicost Nov 6, 2025
06ccd91
EvidentIX85: Fix CondenserTurret timeout by clearing busy after TR+ ack
nicost Nov 7, 2025
916739a
EvidentIX85: Fixes bug in DiaShutter detection.
nicost Nov 7, 2025
6837af3
EvidentIX85: Fix multiple device bugs found during hardware testing
nicost Nov 7, 2025
cbf3ce1
EvidentIX85: Use V command for device detection and add firmware vers…
nicost Nov 7, 2025
d4e4005
EvidentIX85: Add MirrorUnit2, EPIShutter2, and Manual Control Unit in…
nicost Nov 8, 2025
51d216b
EvidentIX85: Add encoder support, MCU indicators I4/I5, and stage cal…
nicost Nov 9, 2025
c957e88
EvidentIX85: Add focus jog controls and fix DIA brightness display
nicost Nov 10, 2025
f38a039
EvidentIX85: Convert CorrectionCollar to Stage device with linking su…
nicost Nov 10, 2025
8a807e9
EvidentIX85: add orphaned addition of DeviceType_DIABrightness
nicost Nov 10, 2025
2ae86a6
EvidentIX85: Add initialization robustness and serial port auto-detec…
nicost Nov 11, 2025
de922e5
EvidentIX85: Fix CorrectionCollar linking failure due to double termi…
nicost Nov 11, 2025
aed21e4
EvidentIX85: bug fixes.
nicost Nov 15, 2025
8b378c6
EvidentIX5SSA - XYStage - first version.
nicost Nov 15, 2025
aeaf765
IX85XYSTage: fixed limits, renamed device.
nicost Nov 16, 2025
a5d71b4
EvidentIX85: rename IX5SSA to IX85XYStage
nicost Nov 17, 2025
8f221c7
EvidentIX85: Fixed bug: MIRROR_UNIT_MAX_POS equals 8 rather than 6.
nicost Nov 17, 2025
eeeea59
EvidentIX85Win: start.
nicost Nov 18, 2025
0f98910
EvidentIX85Win: Progress.
nicost Nov 18, 2025
f9dd1a9
EvidentIX85Win: more progress
nicost Nov 18, 2025
a89fd2f
EvidenIX85Win: ZDC somewhat working, several fixes to other devices.
nicost Nov 19, 2025
01a758d
EvidentIX85Win: Add Tracking Mode property for ZDC autofocus
nicost Nov 20, 2025
7aa7494
EvidentIX85Win: Add Focus Near Limit properties to Nosepiece
nicost Nov 20, 2025
a7d0ab2
EvidentIX85Win: Add parfocal settings and escape distance, switch to …
nicost Nov 20, 2025
8485465
EvidentIX85Win: Implement ZDC autofocus workflow modes
nicost Nov 21, 2025
45378e5
EvidentIX85Win: Add ObjectiveSetup device for microscope configuration
nicost Nov 21, 2025
2b8d4b7
EvidenIX85Win-ObjectiveSetup - remove rednundant FinalSpecs property.
nicost Nov 21, 2025
9260f9a
EvidentIX85Win: Refactor ObjectiveSetup handlers to use CPropertyActi…
nicost Nov 21, 2025
a8c61e4
EvidentIX85Win AF: FinFocusWithOffset no longer needs the offset to b…
nicost Nov 22, 2025
f586d48
EvidentIX85Win: Add PropertyChanged callbacks for AF Status updates
nicost Nov 24, 2025
1a4b0eb
EvidentIX85Win: Adds Serial port detection so that available
nicost Nov 25, 2025
b7057f0
EvidentIX85Win: ZDCVirtualOffset. WIP.
nicost Nov 27, 2025
16d1ef6
EvidentIX85Win: Added ZDCVirtualOffset. Needs testing with hardware.
nicost Nov 27, 2025
2738da4
EvidentIX85Win: changed default path to SDK dll to be relative to the…
nicost Dec 3, 2025
e32bb69
EvidentIX85Win: fix not waiting for focus drive to move into the corr…
nicost Dec 4, 2025
1013bc7
EvidentIX85Win: make sure that ZDC is busy whenever the focus drive i…
nicost Dec 4, 2025
6eb3cb2
EvidentIX85Win: adds neede header from secret repo.
nicost Dec 5, 2025
04421b9
EvidentIX85Win: Change autofocus mode default to Find-Focus-With-Offset.
nicost Dec 8, 2025
80fc0cc
EvidentIX85Win: made debug mode compile correcyly.
nicost Dec 17, 2025
5785155
EvidentIX85Win: handles busy error message from SDK by trying the com…
nicost Dec 17, 2025
fe3b90e
EvidentIX85WIN: Provide a mechanism to Execute Commands
nicost Dec 18, 2025
3290ee0
EvidentIX85Win: formatting only.
nicost Dec 18, 2025
5f8673f
EvidentIX85Win: Made parfocal settings work.
nicost Dec 19, 2025
9b7632b
EvidentIX85Win: Ensure default serial oirt tiomeout is correct.
nicost Dec 19, 2025
1cc0949
EvidentIX85: Hardcoded path to the default micro-manager installation…
nicost Dec 19, 2025
607be70
EvidentIX85 Addresses most PR comments.
nicost Feb 18, 2026
ee5396c
Add EvidentIX85 adapters to solution
marktsuchida Feb 19, 2026
dd25ac8
Add EvidentIX85 to Makefile.am
marktsuchida Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,170 changes: 2,170 additions & 0 deletions DeviceAdapters/EvidentIX85/EvidentHub.cpp

Large diffs are not rendered by default.

152 changes: 152 additions & 0 deletions DeviceAdapters/EvidentIX85/EvidentHub.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
///////////////////////////////////////////////////////////////////////////////
// FILE: EvidentHub.h
// PROJECT: Micro-Manager
// SUBSYSTEM: DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION: Evident IX85 microscope hub
//
// COPYRIGHT: University of California, San Francisco, 2025
//
// LICENSE: This file is distributed under the BSD license.
// License text is included with the source distribution.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
//
// AUTHOR: Nico Stuurman, 2025

#pragma once

#include "DeviceBase.h"
#include "EvidentModel.h"
#include "EvidentProtocol.h"
#include "EvidentIX85.h"
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <string>
#include <vector>

class EvidentHub : public HubBase<EvidentHub>
{
public:
EvidentHub();
~EvidentHub();

// MMDevice API
int Initialize();
int Shutdown();
void GetName(char* pszName) const;
bool Busy();

bool SupportsDeviceDetection(void) { return true; }
MM::DeviceDetectionStatus DetectDevice(void);
// Hub API
int DetectInstalledDevices();

// Action handlers
int OnPort(MM::PropertyBase* pProp, MM::ActionType eAct);
int OnAnswerTimeout(MM::PropertyBase* pProp, MM::ActionType eAct);

// Hub interface for devices to access state
EvidentIX85::MicroscopeModel* GetModel() { return &model_; }

// Command execution (thread-safe)
int ExecuteCommand(const std::string& command, std::string& response);
int SendCommand(const std::string& command);
int GetResponse(std::string& response, long timeoutMs = -1);

// Device discovery
bool IsDevicePresent(EvidentIX85::DeviceType type) const;
std::string GetDeviceVersion(EvidentIX85::DeviceType type) const;

// Notification control
int EnableNotification(const char* cmd, bool enable);

void RegisterDeviceAsUsed(EvidentIX85::DeviceType type, MM::Device* device) { usedDevices_[type] = device;};
void UnRegisterDeviceAsUsed(EvidentIX85::DeviceType type) { usedDevices_.erase(type); };

int UpdateMirrorUnitIndicator(int position);
int UpdateLightPathIndicator(int position);
int UpdateEPIShutter1Indicator(int state);
int UpdateDIABrightnessIndicator(int brightness);

// DIA brightness memory for logical shutter
int GetRememberedDIABrightness() const { return rememberedDIABrightness_; }
void SetRememberedDIABrightness(int brightness) { rememberedDIABrightness_ = brightness; }

private:
// Initialization helpers
int SetRemoteMode();
int GetVersion(std::string& version);
int GetUnit(std::string& unit);
int GetUnitDirect(std::string& unit);
int ClearPort();
int DoDeviceDetection();
int QueryDevicePresenceByVersion(int unitNumber, std::string& version);

// Device query helpers
int QueryFocus();
int QueryNosepiece();
int QueryMagnification();
int QueryLightPath();
int QueryCondenserTurret();
int QueryDIAAperture();
int QueryDIAShutter();
int QueryPolarizer();
int QueryDICPrism();
int QueryDICRetardation();
int QueryEPIShutter1();
int QueryEPIShutter2();
int QueryMirrorUnit1();
int QueryMirrorUnit2();
int QueryEPIND();
int QueryRightPort();
int QueryCorrectionCollar();
int QueryManualControl();

// Manual Control Unit (MCU) helpers
int UpdateNosepieceIndicator(int position);

// Monitoring thread
void StartMonitoring();
void StopMonitoring();
void MonitorThreadFunc();
void ProcessNotification(const std::string& message);
bool IsNotificationTag(const std::string& message) const;

// Member variables
bool initialized_;
std::string port_;
long answerTimeoutMs_;
EvidentIX85::MicroscopeModel model_;

// Threading
std::thread monitorThread_;
std::atomic<bool> stopMonitoring_;
mutable std::mutex commandMutex_; // Protects command sending only

// Response handling (monitoring thread passes responses to command thread)
std::mutex responseMutex_;
std::condition_variable responseCV_;
std::string pendingResponse_;
bool responseReady_;

// State
std::string version_;
std::string unit_;
std::vector<EvidentIX85::DeviceType> availableDevices_;
std::vector<std::string> detectedDevicesByName_;

// MCU switch state
int rememberedDIABrightness_; // Remembered brightness for DIA switch toggle

// Child devices
std::map<EvidentIX85::DeviceType, MM::Device*> usedDevices_;
};
Loading