advantech-automation 0.1.0
Add your description here
Requires Python: >=3.12

# pydaq

`pydaq` 是一个 Python 库（基于 `ctypes`），用于调用研华 Advantech DAQNavi / BioDAQ 的底层驱动接口，从而在 Python 中完成数据采集（DAQ）相关操作：

- 模拟量输入（AI）：`InstantAiCtrl` / `WaveformAiCtrl`
- 模拟量输出（AO）：`InstantAoCtrl` / `BufferedAoCtrl`
- 数字量输入/输出（DI/DO）：`InstantDiCtrl` / `InstantDoCtrl`
- 计数器/频率计等：`EventCounterCtrl` / `FreqMeterCtrl` / `TimerPulseCtrl` / `UdCounterCtrl` 等

本仓库的 Python 分发包名是 **pydaq**，但代码中的实际 import 根包是 **Automation**（例如 `Automation.BDaq.InstantAiCtrl`）。

> 重要：本库不包含研华的驱动/DLL/SO 文件。你必须先安装并正确配置 Advantech DAQNavi / BioDAQ 运行时。

---

## 环境与前置条件

### Python 版本

- Python >= 3.12（见 `pyproject.toml`）

### 系统与驱动

库会在导入阶段尝试加载动态库：

- Windows：加载 `biodaq`（等价于 `biodaq.dll`）
- 非 Windows：加载 `libbiodaq.so`

因此：

- Windows（推荐）：安装 DAQNavi / BioDAQ 驱动后，确保 `biodaq.dll` 在系统可搜索路径中（例如已安装到系统目录或 PATH 可找到）。
- Linux：需要 `libbiodaq.so`，并确保在 `LD_LIBRARY_PATH` 或系统库路径中可被找到。
- macOS：`platform.system()` 会走“非 Windows”分支并尝试加载 `libbiodaq.so`，通常没有对应官方库文件，因此默认不可用。

---

## 安装

本仓库使用 `setuptools` 打包，分发名为 `pydaq`，包目录在 `src/`。

开发/本地安装：

```bash
pip install -e .
```

或普通安装：

```bash
pip install .
```

安装完成后使用如下 import 路径：

```python
from Automation.BDaq.InstantAiCtrl import InstantAiCtrl
```

---

## 快速开始

### 1) 打开设备（按设备号或描述字符串）

所有控制器都继承自 `DaqCtrlBase`，通过 `selectedDevice` 选择设备：

- 传 `int`：按设备号（例如 `0`）
- 传 `str`：按设备描述字符串（例如 `"PCI-1716,BID#0"`，具体取决于驱动枚举结果）

示例：模拟量输入读取（Instant AI）

```python
from Automation.BDaq.InstantAiCtrl import InstantAiCtrl
from Automation.BDaq import ErrorCode


def main() -> None:
	ai = InstantAiCtrl()
	try:
		# 方式 A：按设备号（最简单）
		ai.selectedDevice = 0

		# 方式 B：按描述字符串（示例，实际字符串以系统枚举为准）
		# ai.selectedDevice = "PCI-1716,BID#0"

		err, values = ai.readDataF64(chStart=0, chCount=1)
		if err != ErrorCode.Success:
			raise RuntimeError(f"AI read failed: {err} (0x{err.value:08X})")

		print("AI[0] =", values[0])
	finally:
		# 释放底层句柄
		ai.dispose()


if __name__ == "__main__":
	main()
```

### 2) 数字量输入（DI）

```python
from Automation.BDaq.InstantDiCtrl import InstantDiCtrl
from Automation.BDaq import ErrorCode


di = InstantDiCtrl(0)
try:
	err, bit0 = di.readBit(port=0, bit=0)
	if err != ErrorCode.Success:
		raise RuntimeError(f"DI read failed: {err}")
	print("DI port0 bit0 =", bit0)
finally:
	di.dispose()
```

### 3) 数字量输出（DO）

```python
from Automation.BDaq.InstantDoCtrl import InstantDoCtrl
from Automation.BDaq import ErrorCode


do = InstantDoCtrl(0)
try:
	err = do.writeBit(port=0, bit=0, data=1)
	if err != ErrorCode.Success:
		raise RuntimeError(f"DO write failed: {err}")
finally:
	do.dispose()
```

### 4) 模拟量输出（AO）

```python
from Automation.BDaq.InstantAoCtrl import InstantAoCtrl
from Automation.BDaq import ErrorCode


ao = InstantAoCtrl(0)
try:
	# 输出 1 个通道的标定值（单位通常为 V；具体与设备量程/配置相关）
	err = ao.writeAny(chStart=0, chCount=1, dataRaw=None, dataScaled=[1.0])
	if err != ErrorCode.Success:
		raise RuntimeError(f"AO write failed: {err}")
finally:
	ao.dispose()
```

### 5) 波形采集（Waveform AI，缓冲采集）

`WaveformAiCtrl` 支持“准备 → 开始 → 取数 → 停止”的流程，并提供 `conversion`/`record` 等配置项：

```python
from Automation.BDaq.WaveformAiCtrl import WaveformAiCtrl
from Automation.BDaq import ErrorCode


wf = WaveformAiCtrl(0)
try:
	wf.conversion.channelStart = 0
	wf.conversion.channelCount = 1
	wf.conversion.clockRate = 1000  # 1 kHz（实际可用范围以设备为准）

	wf.record.sectionLength = 1000  # 每段采样点数
	wf.record.sectionCount = 1
	wf.record.cycles = 1

	if wf.prepare() != ErrorCode.Success:
		raise RuntimeError("prepare failed")
	if wf.start() != ErrorCode.Success:
		raise RuntimeError("start failed")

	err, returned, data, *_ = wf.getDataF64(count=1000, timeout=2000)
	if err != ErrorCode.Success:
		raise RuntimeError(f"getData failed: {err}")
	print("returned:", returned, "first:", data[:5])
finally:
	wf.stop()
	wf.dispose()
```

---

## API 概览（常用类）

控制器类大多位于 `Automation.BDaq.*`：

- AI
  - `InstantAiCtrl`: `readDataF64/readDataI32/readDataI16`
  - `WaveformAiCtrl`: `prepare/start/getData*/stop`，并通过 `conversion` / `record` 配置采集
- AO
  - `InstantAoCtrl`: `writeAny`
- DIO
  - `InstantDiCtrl`: `readAny/readBit`
  - `InstantDoCtrl`: `writeAny/writeBit`，并可 `readAny/readBit`
- 基类
  - `DaqCtrlBase`: 设备选择 `selectedDevice`、释放 `dispose()`、重置 `cleanup()`、读取 `state/device`

错误码使用 `Automation.BDaq.ErrorCode`，且很多方法返回 `(ErrorCode, data)` 或直接返回 `ErrorCode`。

---

## 目录结构

```text
src/
  Automation/
	BDaq/          # ctypes 封装与各类控制器
```

---

## 常见问题（Troubleshooting）

- 导入时报找不到 `biodaq` / `libbiodaq.so`
  - 说明驱动/运行时未安装或动态库不在系统搜索路径中。
- `ErrorDeviceNotOpened` / `ErrorDriverNotFound`
  - 检查 `selectedDevice` 是否正确、设备是否在系统中被驱动识别。
- 架构不匹配（32/64 位）
  - Python 解释器位数需要与驱动/DLL 位数一致。

---

## License

仅用于 Zengoldway 内部开发用，不得单独分发此包。