usb1808

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

mcc-usb-1808

Go mascot

Go Reference

This library helps you write applications that interface with the Measurement Computing Corporation USB 1808 and 1808X DAQs.

Prerequisites

  • Go 1.24+
  • libusb 1.0 (brew install libusb on macOS, apt install libusb-1.0-0-dev on Debian/Ubuntu)

Installation

go get github.com/borud/mcc-usb-1808

Quick Start

package main

import (
    "fmt"
    "log"

    "github.com/borud/mcc-usb-1808"
)

func main() {
    dev, err := usb1808.Open()
    if err != nil {
        log.Fatal(err)
    }
    defer dev.Close()

    if err := dev.Init(); err != nil {
        log.Fatal(err)
    }

    // Configure all channels for ±10V differential.
    configs := make([]usb1808.AnalogInChannelConfig, usb1808.NumAInChannels)
    for i := range configs {
        configs[i] = usb1808.AnalogInChannelConfig{
            Channel: i,
            Range:   usb1808.BP10V,
            Mode:    usb1808.Differential,
        }
    }
    if err := dev.ConfigureAnalogIn(configs); err != nil {
        log.Fatal(err)
    }

    volts, err := dev.AnalogIn()
    if err != nil {
        log.Fatal(err)
    }
    for i, v := range volts {
        fmt.Printf("CH%d: %+9.4f V\n", i, v)
    }
}

CLI Tool

A command-line tool is included for quick testing. Install it with:

go install github.com/borud/mcc-usb-1808/cmd/daq@latest

Example usage:

daq info                                                # Device info
daq blink --count 5                                     # Blink LED
daq analog read --range bp10v                           # Single read (±10V)
daq analog scan --channels 0-3 --rate 10000 --count 100 # Continuous scan

Documentation

See the docs/ directory for the full manual:

If you use this

If you use this it would be really nice if you dropped me a line to let me know, or sent a PR so I can include a link to your application below.

Documentation

Overview

Package usb1808 provides a Go driver for the Measurement Computing USB-1808 and USB-1808X multifunction DAQ devices.

The library communicates with the device over USB using vendor control transfers and bulk endpoints. All operations are methods on the Device type, obtained via Open.

Quick Start

dev, err := usb1808.Open()
if err != nil {
	log.Fatal(err)
}
defer dev.Close()

if err := dev.Init(); err != nil {
	log.Fatal(err)
}

serial, err := dev.SerialNumber()
fmt.Println("Serial:", serial)

Index

Constants

View Source
const (
	VendorID = 0x09DB // Measurement Computing Corporation

	PID1808  = 0x013D // USB-1808
	PID1808X = 0x013E // USB-1808X
)

USB vendor and product IDs.

View Source
const (
	StatusAInScanRunning  = 0x0002 // Analog input pacer running
	StatusAInScanOverrun  = 0x0004 // Analog input scan FIFO overrun
	StatusAOutScanRunning = 0x0008 // Analog output scan running
	StatusAOutScanUnder   = 0x0010 // Analog output scan FIFO underrun
	StatusAInScanDone     = 0x0020 // Analog input scan completed
	StatusAOutScanDone    = 0x0040 // Analog output scan completed
	StatusFPGAConfigured  = 0x0100 // FPGA is configured and ready
	StatusFPGAConfigMode  = 0x0200 // Device is in FPGA configuration mode
)

Status bits returned by the STATUS command.

View Source
const (
	Counter0 = 0
	Counter1 = 1
	Encoder0 = 2
	Encoder1 = 3
	Timer0   = 0
	Timer1   = 1
)

Counter and timer indices.

View Source
const (
	CounterTotalize   = 0x00
	CounterPeriod     = 0x01
	CounterPulseWidth = 0x02
	CounterTiming     = 0x03
	PeriodMode1X      = 0x00
	PeriodMode10X     = 0x04
	PeriodMode100X    = 0x08
	PeriodMode1000X   = 0x0C
	TickSize20NS      = 0x00
	TickSize200NS     = 0x10
	TickSize2000NS    = 0x20
	TickSize20000NS   = 0x30
)

Counter mode bits.

View Source
const (
	CounterClearOnRead = 0x01
	CounterNoRecycle   = 0x02
	CounterCountDown   = 0x04
	CounterRangeLimit  = 0x08
	CounterFallingEdge = 0x10
)

Counter options bits (for counters 0-1).

View Source
const (
	EncoderX1         = 0x00
	EncoderX2         = 0x01
	EncoderX4         = 0x02
	EncoderClearOnZ   = 0x04
	EncoderLatchOnZ   = 0x08
	EncoderNoRecycle  = 0x10
	EncoderRangeLimit = 0x20
)

Encoder options bits (for encoders 2-3).

View Source
const (
	TimerEnable     = 0x01
	TimerRunning    = 0x02
	TimerInverted   = 0x04
	TimerOTrigBegin = 0x10
	TimerOTrig      = 0x40
)

Timer control bits.

View Source
const (
	ScanOptExternalTrigger  = 0x01
	ScanOptPatternDetection = 0x02
	ScanOptRetriggerMode    = 0x04
	ScanOptCounterValue     = 0x08 // maintain counter value on scan start
	ScanOptSingleIO         = 0x10
)

Analog input scan options.

View Source
const (
	AOutOptTrigger   = 0x10
	AOutOptRetrigger = 0x20
)

Analog output scan options.

View Source
const (
	ScanChanAIn0     = 0
	ScanChanAIn1     = 1
	ScanChanAIn2     = 2
	ScanChanAIn3     = 3
	ScanChanAIn4     = 4
	ScanChanAIn5     = 5
	ScanChanAIn6     = 6
	ScanChanAIn7     = 7
	ScanChanDIO      = 8
	ScanChanCounter0 = 9
	ScanChanCounter1 = 10
	ScanChanEncoder0 = 11
	ScanChanEncoder1 = 12
)

Scan queue channel selectors for AIn scan.

View Source
const (
	AOutScanChanAOut0 = 0
	AOutScanChanAOut1 = 1
	AOutScanChanDIO   = 2
)

Scan queue channel selectors for AOut scan.

View Source
const (
	TriggerEdge = 0x01 // bit 0: 0=level, 1=edge
	TriggerHigh = 0x02 // bit 1: 0=low/falling, 1=high/rising
)

Trigger configuration bits.

View Source
const (
	PatternEqual      = 0x00
	PatternNotEqual   = 0x02
	PatternGreaterThn = 0x04
	PatternLessThan   = 0x06
)

Pattern detection comparison modes (bits 1-2 of options byte).

View Source
const (
	NumAInChannels  = 8
	NumAInRanges    = 4
	NumAOutChannels = 2
	NumTimers       = 2
	NumCounters     = 4 // 2 counters + 2 encoders
	MaxAInQueue     = 13
	MaxAOutQueue    = 3
	MaxPacketSize   = 512
	BaseClock       = 100_000_000 // 100 MHz
)

Device limits.

Variables

View Source
var (
	ErrDeviceNotFound    = errors.New("usb1808: device not found")
	ErrFPGANotConfigured = errors.New("usb1808: FPGA not configured")
	ErrScanOverrun       = errors.New("usb1808: analog input scan FIFO overrun")
	ErrScanUnderrun      = errors.New("usb1808: analog output scan FIFO underrun")
	ErrScanRunning       = errors.New("usb1808: scan already running")
	ErrInvalidChannel    = errors.New("usb1808: invalid channel number")
	ErrInvalidRange      = errors.New("usb1808: invalid voltage range")
	ErrInvalidMode       = errors.New("usb1808: invalid input mode")
	ErrTransferFailed    = errors.New("usb1808: USB transfer failed")
	ErrTimeout           = errors.New("usb1808: USB transfer timeout")
	ErrNotInitialized    = errors.New("usb1808: device not initialized")
	ErrAOutScanRunning   = errors.New("usb1808: cannot write AOut while output scan is running")
	ErrInvalidTimer      = errors.New("usb1808: invalid timer number")
	ErrInvalidCounter    = errors.New("usb1808: invalid counter number")
)

Sentinel errors returned by Device methods.

Functions

This section is empty.

Types

type AnalogInChannelConfig

type AnalogInChannelConfig struct {
	Channel int
	Range   Range
	Mode    InputMode
}

AnalogInChannelConfig holds the range and mode for a single analog input channel.

type AnalogInScanConfig

type AnalogInScanConfig struct {
	Channels    []int   // Scan queue channel selectors (0-12).
	Rate        float64 // Sample rate in Hz per channel.
	Count       uint32  // Total number of scans (0 = continuous).
	RetrigCount uint32  // Scans per retrigger (0 = no retrigger).
	Options     uint8   // Scan option flags.
	PacketSize  uint8   // Samples-1 per USB packet (0xFF = max).
}

AnalogInScanConfig holds configuration for an analog input scan.

type AnalogOutScanConfig

type AnalogOutScanConfig struct {
	Channels    []int   // Scan queue channel selectors (0-2).
	Rate        float64 // Sample rate in Hz.
	Count       uint32  // Total number of scans (0 = continuous).
	RetrigCount uint32  // Scans per retrigger.
	Options     uint8   // Scan option flags.
}

AnalogOutScanConfig holds configuration for an analog output scan.

type Calibration

type Calibration struct {
	Slope  float32
	Offset float32
}

Calibration holds a single calibration coefficient pair read from EEPROM.

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device represents an open USB-1808 or USB-1808X. All methods are safe for concurrent use.

func NewDevice

func NewDevice(transport transport.Transport, model Model) *Device

NewDevice creates a Device using the given transport. This is primarily useful for testing with a mock transport.

func Open

func Open() (*Device, error)

Open discovers and opens the first USB-1808 or USB-1808X device found.

func OpenModel

func OpenModel(model Model) (*Device, error)

OpenModel opens a specific model variant.

func (*Device) AnalogIn

func (d *Device) AnalogIn() ([NumAInChannels]float64, error)

AnalogIn reads all 8 analog input channels and returns calibrated voltages. Channels must be configured first with ConfigureAnalogIn.

func (*Device) AnalogInCalTable

func (d *Device) AnalogInCalTable() [NumAInChannels][NumAInRanges]Calibration

AnalogInCalTable returns the analog input calibration table.

func (*Device) AnalogInConfig

func (d *Device) AnalogInConfig() ([NumAInChannels]AnalogInChannelConfig, error)

AnalogInConfig reads the current ADC configuration for all 8 channels.

func (*Device) AnalogInRaw

func (d *Device) AnalogInRaw() ([NumAInChannels]uint32, error)

AnalogInRaw performs a single asynchronous read of all 8 analog input channels. Returns the raw 18-bit values as uint32.

func (*Device) AnalogInScanConfig

func (d *Device) AnalogInScanConfig(numChannels int) ([]uint8, error)

AnalogInScanConfig reads the current input scan queue configuration.

func (*Device) AnalogInToVolts

func (d *Device) AnalogInToVolts(raw uint32, channel int, r Range) float64

AnalogInToVolts converts a raw 18-bit ADC value to voltage, applying calibration.

func (*Device) AnalogOut

func (d *Device) AnalogOut(channel int, voltage float64) error

AnalogOut writes a voltage to the specified analog output channel (0 or 1). The voltage is converted to a calibrated 16-bit DAC value.

func (*Device) AnalogOutCalTable

func (d *Device) AnalogOutCalTable() [NumAOutChannels]Calibration

AnalogOutCalTable returns the analog output calibration table.

func (*Device) AnalogOutRaw

func (d *Device) AnalogOutRaw(channel int, value uint16) error

AnalogOutRaw writes a raw 16-bit value to the specified analog output channel.

func (*Device) AnalogOutScanConfig

func (d *Device) AnalogOutScanConfig(numChannels int) ([]uint8, error)

AnalogOutScanConfig reads the current output scan queue configuration.

func (*Device) BlinkLED

func (d *Device) BlinkLED(count uint8) error

BlinkLED blinks the device LED the specified number of times.

func (*Device) CalibrationDate

func (d *Device) CalibrationDate() (time.Time, error)

CalibrationDate reads the factory calibration date from EEPROM.

func (*Device) Close

func (d *Device) Close() error

Close releases the USB device.

func (*Device) ConfigureAnalogIn

func (d *Device) ConfigureAnalogIn(configs []AnalogInChannelConfig) error

ConfigureAnalogIn configures the range and input mode for each analog input channel. Exactly 8 config bytes are sent (one per channel).

func (*Device) ConfigureAnalogInScan

func (d *Device) ConfigureAnalogInScan(channels []int) error

ConfigureAnalogInScan writes the input scan queue configuration.

func (*Device) ConfigureAnalogOutScan

func (d *Device) ConfigureAnalogOutScan(channels []int) error

ConfigureAnalogOutScan writes the output scan queue configuration.

func (*Device) CounterLimits

func (d *Device) CounterLimits(counter int, index uint16) (uint32, error)

CounterLimits reads the 32-bit limit value for the specified counter. index: 0 = minimum, 1 = maximum.

func (*Device) CounterMode

func (d *Device) CounterMode(counter int) (uint8, error)

CounterMode reads the mode byte for the specified counter.

func (*Device) CounterOptions

func (d *Device) CounterOptions(counter int) (uint8, error)

CounterOptions reads the options byte for the specified counter.

func (*Device) CounterParams

func (d *Device) CounterParams(counter int) ([]byte, error)

CounterParams reads the 2-byte counter parameters (mode + options combined).

func (*Device) DigitalDirection

func (d *Device) DigitalDirection() (uint16, error)

DigitalDirection reads the digital port tristate register. A '1' bit means the corresponding pin is an input.

func (*Device) DigitalLatch

func (d *Device) DigitalLatch() (uint8, error)

DigitalLatch reads the digital port output latch register.

func (*Device) FPGAVersion

func (d *Device) FPGAVersion() (uint8, uint8, error)

FPGAVersion reads the FPGA firmware version. Returns (major, minor).

func (*Device) Init

func (d *Device) Init() error

Init performs the full device initialization sequence. It checks whether the FPGA image has been loaded, and it it hasn't, takes care of loading it. This means that the first time we run Init after the device has been booted this will take a few seconds. It then builds the calibration tables from EPROM.

func (*Device) Model

func (d *Device) Model() Model

Model returns the device model.

func (*Device) PatternDetect

func (d *Device) PatternDetect() (PatternDetectConfig, error)

PatternDetect reads the pattern detection trigger configuration.

func (*Device) ReadAnalogInScan

func (d *Device) ReadAnalogInScan(ctx context.Context, nScans int) ([]float64, error)

ReadAnalogInScan reads scan data and returns calibrated voltages. The scan queue must be configured first with ConfigureAnalogInScan. Returns a flat slice organized as [scan0_ch0, scan0_ch1, ..., scan1_ch0, ...].

func (*Device) ReadAnalogInScanRaw

func (d *Device) ReadAnalogInScanRaw(_ context.Context, nChannels, nScans int, timeout time.Duration) ([]uint32, error)

ReadAnalogInScanRaw reads analog input scan data from the bulk endpoint. It requests nChannels * nScans * 4 bytes in a single bulk transfer. If the transfer times out but some data was received, the partial data is returned without error. Only a timeout with zero bytes is an error.

The returned slice may contain fewer samples than requested.

func (*Device) ReadCounter

func (d *Device) ReadCounter(counter int) (uint32, error)

ReadCounter reads the 32-bit value of the specified counter (0-3).

func (*Device) ReadDigital

func (d *Device) ReadDigital() (uint8, error)

ReadDigital reads the current state of the digital input pins.

func (*Device) Reset

func (d *Device) Reset() error

Reset resets the device.

func (*Device) ScanAnalogIn

func (d *Device) ScanAnalogIn(ctx context.Context, cfg AnalogInScanConfig) iter.Seq2[[]float64, error]

ScanAnalogIn returns a pull-based iterator that reads analog input scan data as calibrated voltages. Each iteration yields one scan frame (one value per channel in cfg.Channels). The iterator configures the scan queue, starts the scan, and stops it when iteration ends (via break, return, or error).

Channel ranges must be configured first with ConfigureAnalogIn.

func (*Device) ScanAnalogInRaw

func (d *Device) ScanAnalogInRaw(ctx context.Context, cfg AnalogInScanConfig) iter.Seq2[[]uint32, error]

ScanAnalogInRaw is like Device.ScanAnalogIn but yields raw uint32 values without voltage conversion. This is useful for capturing raw ADC codes.

func (*Device) SerialNumber

func (d *Device) SerialNumber() (string, error)

SerialNumber reads the 8-byte ASCII serial number.

func (*Device) SetCounterLimits

func (d *Device) SetCounterLimits(counter int, index uint16, value uint32) error

SetCounterLimits sets the 32-bit limit value for the specified counter. index: 0 = minimum, 1 = maximum.

func (*Device) SetCounterMode

func (d *Device) SetCounterMode(counter int, mode uint8) error

SetCounterMode sets the mode byte for the specified counter.

func (*Device) SetCounterOptions

func (d *Device) SetCounterOptions(counter int, options uint8) error

SetCounterOptions sets the options byte for the specified counter. For counters 0-1, use CounterClearOnRead, CounterNoRecycle, etc. For encoders 2-3, use EncoderX1, EncoderClearOnZ, etc.

func (*Device) SetCounterParams

func (d *Device) SetCounterParams(counter int, data []byte) error

SetCounterParams writes the 2-byte counter parameters.

func (*Device) SetDigitalDirection

func (d *Device) SetDigitalDirection(value uint16) error

SetDigitalDirection sets the digital port tristate register. A '1' bit makes the corresponding pin an input, '0' makes it an output.

func (*Device) SetLogger

func (d *Device) SetLogger(l *slog.Logger)

SetLogger sets the logger used by the device. If nil, slog.Default() is used.

func (*Device) SetPatternDetect

func (d *Device) SetPatternDetect(cfg PatternDetectConfig) error

SetPatternDetect writes the pattern detection trigger configuration.

func (*Device) SetTimerControl

func (d *Device) SetTimerControl(timer int, control uint8) error

SetTimerControl writes the timer control register.

func (*Device) SetTimerParams

func (d *Device) SetTimerParams(timer int, cfg TimerConfig) error

SetTimerParams writes timer parameters (frequency, duty cycle, count, delay). Parameters are cached locally because firmware returns incorrect values on read.

func (*Device) SetTriggerConfig

func (d *Device) SetTriggerConfig(config uint8) error

SetTriggerConfig writes the trigger configuration byte. Bit 0: mode (0=level, 1=edge). Bit 1: polarity (0=low/falling, 1=high/rising).

func (*Device) StartAnalogInScan

func (d *Device) StartAnalogInScan(cfg AnalogInScanConfig) error

StartAnalogInScan starts an analog input scan with the given configuration.

func (*Device) StartAnalogOutScan

func (d *Device) StartAnalogOutScan(cfg AnalogOutScanConfig) error

StartAnalogOutScan starts an analog output scan.

func (*Device) StartTimer

func (d *Device) StartTimer(timer int, cfg TimerConfig) error

StartTimer configures and enables the specified timer.

func (*Device) Status

func (d *Device) Status() (Status, error)

Status reads the 16-bit device status word.

func (*Device) StopAnalogInScan

func (d *Device) StopAnalogInScan() error

StopAnalogInScan stops a running analog input scan.

func (*Device) StopAnalogOutScan

func (d *Device) StopAnalogOutScan() error

StopAnalogOutScan stops a running analog output scan.

func (*Device) StopTimer

func (d *Device) StopTimer(timer int) error

StopTimer disables the specified timer.

func (*Device) TimerControl

func (d *Device) TimerControl(timer int) (uint8, error)

TimerControl reads the timer control register.

func (*Device) TimerParams

func (d *Device) TimerParams(timer int) (TimerConfig, error)

TimerParams returns the cached timer parameters. The firmware returns incorrect values for TIMER_PARAMETERS read, so this returns the last written values.

func (*Device) TriggerConfig

func (d *Device) TriggerConfig() (uint8, error)

TriggerConfig reads the trigger configuration byte.

func (*Device) VoltsToAnalogOut

func (d *Device) VoltsToAnalogOut(voltage float64, channel int) uint16

VoltsToAnalogOut converts a voltage to a 16-bit DAC value, applying calibration.

func (*Device) WriteAnalogOutScan

func (d *Device) WriteAnalogOutScan(data []byte) (int, error)

WriteAnalogOutScan sends output scan data to the bulk OUT endpoint. Data should be 16-bit LE samples, interleaved by queue position.

func (*Device) WriteCounter

func (d *Device) WriteCounter(counter int, value uint32) error

WriteCounter sets the 32-bit value of the specified counter.

func (*Device) WriteDigital

func (d *Device) WriteDigital(value uint8) error

WriteDigital sets the digital port output latch register.

type InputMode

type InputMode uint8

InputMode codes for analog input channels.

const (
	Differential InputMode = 0
	SingleEnded  InputMode = 1
	Grounded     InputMode = 3 // note: 2 is undefined and rejected
)

Analog input mode codes.

type Model

type Model uint16

Model identifies the hardware variant.

const (
	USB1808  Model = PID1808
	USB1808X Model = PID1808X
)

Model constants for USB-1808 variants.

func (Model) String

func (m Model) String() string

type PatternDetectConfig

type PatternDetectConfig struct {
	Value   uint8 // Pattern to match (DIO pin values).
	Mask    uint8 // Bits to compare.
	Options uint8 // Comparison mode (bits 1-2).
}

PatternDetectConfig holds pattern detection trigger configuration.

type Range

type Range uint8

Range codes for analog input channels.

const (
	BP10V Range = 0 // +/- 10V bipolar
	BP5V  Range = 1 // +/- 5V bipolar
	UP10V Range = 2 // 0-10V unipolar
	UP5V  Range = 3 // 0-5V unipolar
)

Analog input range codes.

func (Range) String

func (r Range) String() string

type Status

type Status uint16

Status represents the device status word.

func (Status) AInScanDone

func (s Status) AInScanDone() bool

AInScanDone reports whether the analog input scan has completed.

func (Status) AInScanOverrun

func (s Status) AInScanOverrun() bool

AInScanOverrun reports whether the analog input FIFO has overrun.

func (Status) AInScanRunning

func (s Status) AInScanRunning() bool

AInScanRunning reports whether the analog input scan pacer is active.

func (Status) AOutScanDone

func (s Status) AOutScanDone() bool

AOutScanDone reports whether the analog output scan has completed.

func (Status) AOutScanRunning

func (s Status) AOutScanRunning() bool

AOutScanRunning reports whether the analog output scan is active.

func (Status) AOutScanUnderrun

func (s Status) AOutScanUnderrun() bool

AOutScanUnderrun reports whether the analog output FIFO has underrun.

func (Status) FPGAConfigMode

func (s Status) FPGAConfigMode() bool

FPGAConfigMode reports whether the device is in FPGA configuration mode.

func (Status) FPGAConfigured

func (s Status) FPGAConfigured() bool

FPGAConfigured reports whether the FPGA is configured and ready.

type TimerConfig

type TimerConfig struct {
	Frequency float64 // Output frequency in Hz.
	DutyCycle float64 // Duty cycle 0.0 to 1.0.
	Count     uint32  // Number of pulses (0 = continuous).
	Delay     float64 // Initial delay in seconds.
}

TimerConfig holds timer configuration parameters.

Directories

Path Synopsis
Package capture provides types and encoding for DAQ capture data.
Package capture provides types and encoding for DAQ capture data.
export
Package export provides functions to export capture data to common file formats: CSV, Excel (.xlsx), SQLite, and WAV.
Package export provides functions to export capture data to common file formats: CSV, Excel (.xlsx), SQLite, and WAV.
cmd
daq command
Command daq is a CLI tool for interacting with MCC USB-1808/1808X DAQ devices.
Command daq is a CLI tool for interacting with MCC USB-1808/1808X DAQ devices.
internal
firmware
Package firmware holds the embedded FPGA bitstream for USB-1808 devices.
Package firmware holds the embedded FPGA bitstream for USB-1808 devices.
transport
Package transport defines the low-level USB transport interface used by the usb1808 driver.
Package transport defines the low-level USB transport interface used by the usb1808 driver.
wire
Package wire handles wire-level byte serialization for the USB-1808/1808X protocol.
Package wire handles wire-level byte serialization for the USB-1808/1808X protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL