This package contains a library that allows you .net app to communicate to a FTDI USB chip. It wraps the D2XX API into a nice OO .net library. The Library can also be used on Linux and MacOS.
Get Started
| Product | Versions |
|---|---|
| .NET | |
| .NET Standard | |
| Other |
README
Essy.FTDIWrapper
A small, opinionated .NET wrapper around the FTDI D2XX (ftd2xx) native library.
It lets you enumerate FTDI devices, open them by serial number, configure the UART,
read/write data, work with events, and access EEPROM/user area ā all from managed C# code.
Namespace:
Essy.FTDIWrapper
Features
- Enumerate all connected FTDI devices (with description, serial number, IDs, flags).
- Open a device by serial number and manage its lifetime via
IDisposable. - Synchronous read/write of raw bytes with fullālength checks.
- Query and purge RX/TX buffers.
- Configure baud rate, data bits, parity, stop bits, and flow control.
- Wait for incoming data or modem/pin changes via OS events (sync + async helpers).
- Access user area EEPROM (read/write string or binary, query capacity).
- Read and modify the device Product ID in the EEPROM while preserving user area.
- Reset / cycle port / tweak latency and USB buffer sizes (where supported by the OS).
- Strongly-typed enums for parity, stop bits, data length, flow control, and status pins.
- Rich exception hierarchy for low-level and enumeration errors.
The native interop is centralized in a single internal FTDIFunctions class that P/Invokes into ftd2xx.
Installation
Once published to NuGet:
dotnet add package Essy.FTDIWrapper
Or via the NuGet Package Manager UI in Visual Studio: search for Essy.FTDIWrapper.
Requirements
- .NET (classic Framework or modern .NET) with support for P/Invoke.
- The FTDI D2XX driver installed on the system.
- The
ftd2xxnative library (ftd2xx.dll/libftd2xx.so/libftd2xx.dylib) available on the library load path.
Some features (port cycling, driver version, reset pipe retry count) are only supported on Windows and are no-ops or shortācircuit on Unix-like platforms.
Getting started
1. Enumerate devices
using System;
using System.Collections.Generic;
using Essy.FTDIWrapper;
class Program
{
static void Main()
{
List<FTDI_DeviceInfo> devices = FTDI_DeviceInfo.EnumerateDevices();
if (devices.Count == 0)
{
Console.WriteLine("No FTDI devices found.");
return;
}
foreach (var dev in devices)
{
Console.WriteLine(dev.ToString());
}
}
}
FTDI_DeviceInfo.EnumerateDevices() calls FT_CreateDeviceInfoList and FT_GetDeviceInfoDetail under the hood and converts the C strings to managed strings.
2. Open a device and configure the port
A device is opened by serial number via FT_OpenEx and wrapped in FTDI_Device, which is IDisposable.
using System;
using System.Text;
using Essy.FTDIWrapper;
class Program
{
static void Main()
{
var devices = FTDI_DeviceInfo.EnumerateDevices();
if (devices.Count == 0)
{
Console.WriteLine("No FTDI devices found.");
return;
}
var info = devices[0];
using var dev = new FTDI_Device(info);
// Basic UART configuration
dev.SetBaudrate(115200);
dev.SetParameters(DataLength.EightBits, Parity.None, StopBits.OneStopBit);
dev.SetFlowControl(FlowControl.None);
// Clear buffers (optional)
dev.ClearReceiveBuffer();
dev.ClearSendBuffer();
// Send some data
var payload = Encoding.ASCII.GetBytes("Hello FTDI!");
dev.WriteBytes(payload);
// Read back anything available
uint available = dev.NumberOfBytesInReceiveBuffer();
if (available > 0)
{
byte[] response = dev.ReadBytes(available);
Console.WriteLine("Read: " + BitConverter.ToString(response));
}
}
}
The WriteBytes and ReadBytes methods validate that the requested number of bytes were actually transmitted/received, and throw a FTDIDeviceNotAllBytesTransmittedException otherwise.
3. Waiting for incoming data
FTDI_Device can use event notifications to wait for RX data. On EnableWaitForDataEvent, it sets up an event with FT_SetEventNotification and waits on it via EventWaitHandle. īfileciteīturn0file0īL168-L191īturn0file3īL60-L73ī
using System;
using System.Text;
using System.Threading.Tasks;
using Essy.FTDIWrapper;
class Program
{
static async Task Main()
{
var devInfo = FTDI_DeviceInfo.EnumerateDevices()[0];
using var dev = new FTDI_Device(devInfo);
dev.SetBaudrate(115200);
dev.EnableWaitForDataEvent();
Console.WriteLine("Waiting for data...");
// Asynchronously wait until the RXCHAR event is signalled
await dev.WaitForDataAsync();
uint available = dev.NumberOfBytesInReceiveBuffer();
if (available > 0)
{
byte[] data = dev.ReadBytes(available);
Console.WriteLine("Received: " + BitConverter.ToString(data));
}
}
}
There is also a synchronous WaitForData(int timeoutMs) plus equivalent methods for modem/pināchange events (EnableWaitForPinChangeEvent, WaitForPinChange, WaitForPinChangeAsync).
4. Working with the user EEPROM area
The library exposes helpers to read/write the user area (UA) EEPROM as either text or raw bytes:
using System;
using Essy.FTDIWrapper;
class Program
{
static void Main()
{
var info = FTDI_DeviceInfo.EnumerateDevices()[0];
using var dev = new FTDI_Device(info);
// Get capacity
uint capacity = dev.GetSizeOfUAEEProm();
Console.WriteLine($"User EEPROM size: {capacity} bytes");
// Store a label
dev.WriteToUAEEProm("My FTDI Device");
// Read it back as string
string label = dev.ReadFromUAEEProm();
Console.WriteLine($"Label: {label}");
// Or as raw bytes
byte[] raw = dev.ReadBinaryFromUAEEProm(16);
Console.WriteLine("Raw: " + BitConverter.ToString(raw));
}
}
The implementation ensures that the requested size fits within the available user area and throws an FTDIDeviceLowLevelException if not.
5. Error handling
Most failures wrap the FT_STATUS code returned from ftd2xx in a typed exception:
FTDIExceptionā base type, exposes theStatusproperty.FTDIEnumerationExceptionā for enumeration problems.FTDIDeviceExceptionand its children:FTDIDeviceLowLevelExceptionFTDIDeviceNotAllBytesTransmittedException
Example:
try
{
using var dev = new FTDI_Device(info);
dev.SetBaudrate(9600);
dev.WriteBytes(new byte[] { 0x01, 0x02, 0x03 });
}
catch (FTDIException ex)
{
Console.Error.WriteLine($"FTDI error: {ex.Message}");
Console.Error.WriteLine($"Status: {ex.Status}");
}
Advanced operations
Some additional APIs you can call on FTDI_Device:
Reset()/TryReset()ā reset the device.ResetPort(),TryResetPort()ā reset the USB port (Windows only).CyclePort(),TryCyclePort()ā cycle the USB port (Windows only).SetResetPipeRetryCount(uint)ā configure retry behaviour when resetting pipes.SetBufferFlushTimer(byte)ā configure latency timer.SetBufferSizes(uint tx, uint rx)ā change USB transfer sizes.GetStatusPins()ā read modem pins (CTS,DSR,RI,DCD).SetRTS(bool)ā assert/deassert RTS.GetDriverVersion()ā retrieve FTDI driver version (Windows only).GetDeviceProductID()/SetDeviceProductID(ushort)ā read or reprogram the Product ID in EEPROM, preserving the user area data.
Design notes
- The wrapper is intentionally thin: all P/Invoke declarations live in
FTDIFunctions, while public, userāfriendly APIs live inFTDI_DeviceandFTDI_DeviceInfo. - The library does not hide the
FT_STATUScodes; instead it surfaces them via exceptions so advanced users can still reason about exact driver failures. - Device opening is based on serial numbers for deterministic device selection; if you need a different strategy you can select a device from the enumeration list by description or ID.
License
This library is licensed under the MIT License See the source files for the full license text.
Downloads by Version
Similar & Alternative Packages
Hand-picked matching NuGet libraries based on tags & ecosystem
Depended On By
Find packages that declare this package as a dependency. NuGet does not provide a reverse-dependency endpoint, so candidates are checked on demand.
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.