ToupTek.SDK 1.1.51

dotnet add package ToupTek.SDK --version 1.1.51
                    
NuGet\Install-Package ToupTek.SDK -Version 1.1.51
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ToupTek.SDK" Version="1.1.51" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ToupTek.SDK" Version="1.1.51" />
                    
Directory.Packages.props
<PackageReference Include="ToupTek.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ToupTek.SDK --version 1.1.51
                    
#r "nuget: ToupTek.SDK, 1.1.51"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ToupTek.SDK@1.1.51
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ToupTek.SDK&version=1.1.51
                    
Install as a Cake Addin
#tool nuget:?package=ToupTek.SDK&version=1.1.51
                    
Install as a Cake Tool

ToupTek.SDK

ToupTek cameras from .NET, and the rebadged families built on the same SDK, implementing SharpAstro's TianWen.DAL device abstraction so a ToupTek body is driven by the same code that drives a ZWO, QHY or Player One one.

Vendor SDK: 60.32549.20260908 (lib/SOURCE.txt names the zip and its sha256). The package does not track that number, because it is a build counter and a date rather than a version, and eleven libraries share it.

One binding, eleven libraries

ToupTek's SDK is rebadged by several vendors under their own library name and function prefix. Every entry point is resolved at run time against the library's own handle (NativeLibrary.GetExport into unmanaged function pointers, AOT-clean), so one binding covers all of them:

Brand Library Prefix
ToupTek toupcam Toupcam_
Altair altaircam Altaircam_
Bresser bressercam Bressercam_
MallinCam mallincam Mallincam_
Nn nncam Nncam_
OGMAVision ogmacam Ogmacam_
Omegon omegonprocam Omegonprocam_
Orion starshootg Starshootg_
Teleskop Service tscam Tscam_
SVBONY (ToupTek-based line) svbonycam Svbonycam_
Meade meadecam Toupcam_

The table is INDI's (indi-3rdparty/indi-toupbase/libtoupbase.h), not recalled. Meade exporting Toupcam_ symbols is why resolution is per handle rather than by global name. Only ToupTek ships with this package and only ToupTek is verified; the others work wherever their own library is installed beside the application, and are unverified until one is plugged in.

Verified on hardware

A ToupTek G3M678M (IMX678 mono, 2.0 um, 3840 x 2160, USB 0547:14BC, firmware 4.0.2.202300708) on Windows x64, 2026-09-23. Found through Toupcam_EnumV2 under Microsoft's in-box WinUSB driver, no vendor driver install.

  • Pixels are 12-bit LEFT-ALIGNED in 16, whatever the header's comment on TOUPCAM_OPTION_ZERO_PADDING suggests: 8,293,901 of 8,294,400 values a multiple of 16, clipping at exactly 65520 = 4095 x 16. The SDK reports 16 bits (get_MaxBitDepth, get_RawFormat, TOUPCAM_FLAG_RAW16) and 16 is what BitDepth declares, so the declared saturation (65535) is right; ToupcamCamera.DeliversContainerScaledPixels records the measurement.
  • Average binning (TOUPCAM_OPTION_BINNING = 0x80 | n) keeps the ADU scale; at bin 2 the step is 4, as on Player One.
  • Black level runs 0 to 7936 in this mode, confirmed by the SDK refusing 7937.
  • Serial TP250818143548A337C2B6718F4135B needs an open handle, and is the identity: the SDK's own id is a USB device path, which changes with the port.
  • No sensor temperature on this body; the SDK answers E_NOTIMPL and the binding reports that.

Frame rate, and recovering a stalled camera

Measured in video mode (TOUPCAM_OPTION_TRIGGER = 0, RAW, speed 2, the default), counting delivered frames over 3 s, no frames dropped:

Rows (width 3840) 8-bit fps 16-bit fps
2160 47 23
1080 93 45
256 362 177
128 658 323
40 1510 740

Height is what counts, width is not: at 40 rows the rate is identical at 3840, 1920 and 960 wide, so the ceiling is the sensor's row readout, not USB. 8-bit output runs the sensor about twice as fast as 16-bit. Below 40 rows it is exposure-bound (1 ms caps at about 925 fps; 500 us and shorter reach 1510).

The camera can stall, and a configuration change is what sets it off. The transfer from the camera stops: every call still succeeds, no frame arrives, and with the no-packet timeout armed the SDK raises TOUPCAM_EVENT_NOPACKETTIMEOUT every ~0.5 s. Measured 2026-09-23:

Path Runs Stalls
Video, fresh open per run, resolution, bit depth and speed rotating 80 2: once after 895 frames of a stream, once at the start
Video, a sweep of the same changes 48 3, all 8-bit
Software trigger (the DAL's path), ROI changed every 5 frames 400 at 8-bit, 400 at 16-bit 0
Software trigger, bit depth flipped by a close and reopen every 20 frames 600 1 frame never arrived, with NO event, and the next trigger worked

The stall at the start of a video run survived both a restart of the stream on the same handle and a close and reopen. TOUPCAM_OPTION_DEVICE_RESET ("simulate a replug") cleared it: the camera re-enumerated under the same serial and streamed again after 2.8 s (0.6 s on another occasion).

What the binding does about it:

  • Both timeouts are armed on every stream (no-packet 1 s, no-frame 2 s), and either one, as well as a trigger failure or a generic error, fails the exposure in progress. The SDK arms them against when a frame is due, not wall time: three 5 s triggered exposures under tighter values (0.5 s and 1 s) raised nothing but the frame, and 3 s idle between triggers raised nothing.
  • The reset is exposed as the DAL's ResetDevice() (CanResetDevice is true), and never fired from here. TianWen's DAL camera driver gives up a frame the camera never delivers at a deadline, and resets the camera before the next exposure after two losses in a row, then finds it again and restores its gain, offset, white balance and cooler. A lost trigger with no event can only be caught by that deadline, which is why it lives in the driver rather than here.

How capture works

Software trigger over pull mode: the camera starts in TOUPCAM_OPTION_TRIGGER = 1, so it produces nothing until Toupcam_Trigger(h, 1); an [UnmanagedCallersOnly] event callback marks the frame ready on TOUPCAM_EVENT_IMAGE; Toupcam_PullImageV4 copies it into the caller's buffer. That is the DAL's start / poll / read shape with no video stream running between exposures.

Things that are easy to get wrong, each handled once in ToupcamSession:

  • TOUPCAM_OPTION_UPSIDE_DOWN defaults to 1 on Windows (the bottom-up DIB convention) and 0 elsewhere. It is set to 0 before the stream starts, since it cannot change while running, or every Windows frame would arrive flipped.
  • TOUPCAM_OPTION_RAW = 1, not -1: -1 applies the SDK's own flat, dark and white balance corrections. RAW mode applies no white balance, so none is reported.
  • put_Roi takes SENSOR coordinates even under digital binning; the DAL's are binned, so the session multiplies back. The size wins over a stale start, since the DAL sets size before start.
  • The DAL's device type is a struct, copied freely, while a ToupTek camera has live state (the handle, the ready flag). The struct carries only a key into a reference-counted session registry.

Conversion gain (TOUPCAM_OPTION_CG: LCG, HCG, HDR) is read, never set. The G3M678M starts in HCG and also has an HDR mode (TOUPCAM_FLAG_CGHDR). SharpCap keeps this behind an opt-in "Read Mode" setting, and HDR on this family has depended on matching camera firmware and SDK versions (SharpCap forum, t=8307), so the camera's default is left alone until the DAL has a read-mode control.

Vendor drops

tools/fetch-natives.ps1 unpacks the SDK zip into lib/<rid>/, include/ and reference/, and writes lib/SOURCE.txt. Re-run it against a new zip and commit what changed.

Licence

The ToupTek SDK is closed source and proprietary to ToupTek; its binaries, header and manual are redistributed here as other open-source astronomy software does (INDIGO vendors the same files under indigo_drivers/ccd_touptek/bin_externals/libtoupcam). The wrapper code is SharpAstro's.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ToupTek.SDK:

Package Downloads
TianWen.Devices.Native

Native vendor device drivers for TianWen: ZWO (ASI cameras, EAF focusers, EFW filter wheels) and QHYCCD (cameras, filter wheels, QFOC focusers), over the vendors' own SDKs. Reference this alongside TianWen.Lib to drive that hardware; TianWen.Lib alone covers ASCOM, Alpaca and the serial-native drivers and carries no vendor binaries.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.51 859 9/23/2026
1.0.31 77 9/23/2026
1.0.11 50 9/23/2026