feat: release card reader SDK v0.1.0
This commit is contained in:
commit
7d2b65ff38
19
CHANGELOG.md
Normal file
19
CHANGELOG.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
### 中文
|
||||
|
||||
- 初始发布 AISU 830T Card Reader Unity Package。
|
||||
- 支持读卡器打开、关闭和串口参数配置。
|
||||
- 支持连接异常后的自动重连。
|
||||
- 支持接收卡片信息和十进制 `CardNumber`。
|
||||
- 提供 Unity 事件 API、Basic Sample 和 Console Demo。
|
||||
|
||||
### English
|
||||
|
||||
- Initial release of the AISU 830T Card Reader Unity package.
|
||||
- Reader open/close and serial configuration.
|
||||
- Automatic reconnect after connection failures.
|
||||
- Card reading with decimal `CardNumber` values.
|
||||
- Unity event API, Basic Sample, and Console Demo.
|
||||
7
CHANGELOG.md.meta
Normal file
7
CHANGELOG.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dcfefc0d619a834e87b1e62740cfa3d
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Documentation~.meta
Normal file
8
Documentation~.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6837a6f6e2f24393a5f8b5ae32d59098
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
136
Documentation~/API.en.md
Normal file
136
Documentation~/API.en.md
Normal file
@ -0,0 +1,136 @@
|
||||
# API Reference
|
||||
|
||||
This document covers the Unity-facing public API of AISU 830T Card Reader SDK v0.1.0. The namespace is `Aisu.CardReader`.
|
||||
|
||||
## CardReaderManager
|
||||
|
||||
`CardReaderManager` is the scene-level reader component. Add it to a GameObject and keep one instance in the scene.
|
||||
|
||||
### Main properties
|
||||
|
||||
```csharp
|
||||
public static CardReaderManager Instance { get; }
|
||||
public SerialDeviceOptions SerialOptions { get; set; }
|
||||
public bool IsConnected { get; }
|
||||
```
|
||||
|
||||
- `Instance`: the current scene Manager.
|
||||
- `SerialOptions`: serial configuration used by the Inspector and by code.
|
||||
- `IsConnected`: whether the reader is currently connected.
|
||||
|
||||
### Main methods
|
||||
|
||||
```csharp
|
||||
public void OpenReader();
|
||||
public void CloseReader();
|
||||
```
|
||||
|
||||
`OpenReader()` starts the reader connection. `CloseReader()` closes the current connection and stops automatic reconnect; `OpenReader()` can be called again later.
|
||||
|
||||
### Events
|
||||
|
||||
```csharp
|
||||
public UnityEvent OnConnected { get; }
|
||||
public UnityEvent OnDisconnected { get; }
|
||||
public UnityEvent<SerialDeviceState> OnStateChanged { get; }
|
||||
public UnityEvent<CardInfo> OnCardReceived { get; }
|
||||
public UnityEvent<CardReaderErrorEventArgs> OnError { get; }
|
||||
```
|
||||
|
||||
Use `AddListener` and `RemoveListener` for event subscription. UnityEvents raised through the Manager are dispatched on the Unity main thread.
|
||||
|
||||
## CardReaderApi
|
||||
|
||||
`CardReaderApi` is the static access point for the current `CardReaderManager` and is convenient for application scripts.
|
||||
|
||||
```csharp
|
||||
public static bool IsConnected { get; }
|
||||
public static void Open();
|
||||
public static void Close();
|
||||
|
||||
public static UnityEvent OnConnected { get; }
|
||||
public static UnityEvent OnDisconnected { get; }
|
||||
public static UnityEvent<SerialDeviceState> OnStateChanged { get; }
|
||||
public static UnityEvent<CardInfo> OnCardReceived { get; }
|
||||
public static UnityEvent<CardReaderErrorEventArgs> OnError { get; }
|
||||
```
|
||||
|
||||
`Open()` starts the connection and `Close()` closes it. Calling either method or accessing an event without an active `CardReaderManager` throws `InvalidOperationException`.
|
||||
|
||||
## SerialDeviceOptions
|
||||
|
||||
`SerialDeviceOptions` is the configuration type of `CardReaderManager.SerialOptions`. The currently exposed fields are:
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `PortName` | `string` | none | Windows COM-port name. |
|
||||
| `BaudRate` | `int` | `9600` | Baud rate. |
|
||||
| `Parity` | `Parity` | `None` | Parity mode. |
|
||||
| `DataBits` | `int` | `8` | Number of data bits. |
|
||||
| `StopBits` | `StopBits` | `One` | Stop-bit setting. |
|
||||
| `Handshake` | `Handshake` | `None` | Handshake mode. |
|
||||
| `ReadTimeout` | `int` | `100` | Read timeout in milliseconds. |
|
||||
| `WriteTimeout` | `int` | `1000` | Write timeout in milliseconds. |
|
||||
| `RtsEnable` | `bool` | `true` | Whether RTS is enabled. |
|
||||
| `DtrEnable` | `bool` | `true` | Whether DTR is enabled. |
|
||||
| `AutoReconnect` | `bool` | `true` | Whether to keep retrying after a connection failure. |
|
||||
| `ReconnectInterval` | `int` | `1000` | Automatic reconnect interval in milliseconds. |
|
||||
| `MaxPendingSendCount` | `int` | `256` | Pending-data capacity. |
|
||||
|
||||
The actual COM port and UART settings depend on the connected reader.
|
||||
|
||||
## CardInfo
|
||||
|
||||
`CardInfo` is the card data supplied by `OnCardReceived`:
|
||||
|
||||
```csharp
|
||||
public CardType CardType { get; }
|
||||
public byte CardTypeCode { get; }
|
||||
public string CardNumber { get; }
|
||||
```
|
||||
|
||||
- `CardType`: the currently mapped type is `CardType.EM4100`.
|
||||
- `CardTypeCode`: the raw type code reported by the device. Unknown values are preserved.
|
||||
- `CardNumber`: a decimal card-number string.
|
||||
|
||||
### CardNumber rules
|
||||
|
||||
`CardNumber` is a `string` containing the decimal card number. Its default minimum width is 10 digits: values shorter than 10 digits are left-padded with `0`, and values longer than 10 digits are not truncated.
|
||||
|
||||
## CardType
|
||||
|
||||
```csharp
|
||||
public enum CardType
|
||||
{
|
||||
Unknown = 0,
|
||||
EM4100 = 0x02
|
||||
}
|
||||
```
|
||||
|
||||
## Error events
|
||||
|
||||
`OnError` provides `CardReaderErrorEventArgs`:
|
||||
|
||||
```csharp
|
||||
public CardReaderException Exception { get; }
|
||||
```
|
||||
|
||||
`Exception` is the actual exception object. Common causes include a missing COM port, a port already in use, and a failed connection. Identical connection errors are not repeatedly emitted, while automatic reconnect continues when `AutoReconnect` is enabled.
|
||||
|
||||
## Event usage
|
||||
|
||||
Register listeners with `AddListener` in `OnEnable` and remove them with `RemoveListener` in `OnDisable`:
|
||||
|
||||
```csharp
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
}
|
||||
```
|
||||
|
||||
`CardReaderManager` releases serial resources when it is destroyed or when the application exits.
|
||||
136
Documentation~/API.zh-CN.md
Normal file
136
Documentation~/API.zh-CN.md
Normal file
@ -0,0 +1,136 @@
|
||||
# API 参考
|
||||
|
||||
本文仅记录 AISU 830T Card Reader SDK v0.1.0 中面向 Unity 使用者的公开 API。命名空间为 `Aisu.CardReader`。
|
||||
|
||||
## CardReaderManager
|
||||
|
||||
`CardReaderManager` 是场景级读卡器管理组件。将它添加到场景中的 GameObject,并保持一个实例。
|
||||
|
||||
### 主要属性
|
||||
|
||||
```csharp
|
||||
public static CardReaderManager Instance { get; }
|
||||
public SerialDeviceOptions SerialOptions { get; set; }
|
||||
public bool IsConnected { get; }
|
||||
```
|
||||
|
||||
- `Instance`:当前场景中的 Manager。
|
||||
- `SerialOptions`:Inspector 和代码使用的串口配置。
|
||||
- `IsConnected`:当前是否已连接。
|
||||
|
||||
### 主要方法
|
||||
|
||||
```csharp
|
||||
public void OpenReader();
|
||||
public void CloseReader();
|
||||
```
|
||||
|
||||
`OpenReader()` 启动读卡器连接。`CloseReader()` 关闭当前连接并停止自动重连;之后可以再次调用 `OpenReader()`。
|
||||
|
||||
### 事件
|
||||
|
||||
```csharp
|
||||
public UnityEvent OnConnected { get; }
|
||||
public UnityEvent OnDisconnected { get; }
|
||||
public UnityEvent<SerialDeviceState> OnStateChanged { get; }
|
||||
public UnityEvent<CardInfo> OnCardReceived { get; }
|
||||
public UnityEvent<CardReaderErrorEventArgs> OnError { get; }
|
||||
```
|
||||
|
||||
事件使用 `AddListener` 和 `RemoveListener`。通过 Manager 接收的 UnityEvent 在 Unity 主线程派发。
|
||||
|
||||
## CardReaderApi
|
||||
|
||||
`CardReaderApi` 是当前 `CardReaderManager` 的静态访问入口,适合在业务脚本中使用。
|
||||
|
||||
```csharp
|
||||
public static bool IsConnected { get; }
|
||||
public static void Open();
|
||||
public static void Close();
|
||||
|
||||
public static UnityEvent OnConnected { get; }
|
||||
public static UnityEvent OnDisconnected { get; }
|
||||
public static UnityEvent<SerialDeviceState> OnStateChanged { get; }
|
||||
public static UnityEvent<CardInfo> OnCardReceived { get; }
|
||||
public static UnityEvent<CardReaderErrorEventArgs> OnError { get; }
|
||||
```
|
||||
|
||||
`Open()` 与 `Close()` 的行为分别是启动连接和关闭连接。没有活动的 `CardReaderManager` 时,调用方法或访问事件会抛出 `InvalidOperationException`。
|
||||
|
||||
## SerialDeviceOptions
|
||||
|
||||
`SerialDeviceOptions` 是 `CardReaderManager.SerialOptions` 的配置类型。当前公开字段如下:
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `PortName` | `string` | 无 | Windows COM 端口名称。 |
|
||||
| `BaudRate` | `int` | `9600` | 波特率。 |
|
||||
| `Parity` | `Parity` | `None` | 校验方式。 |
|
||||
| `DataBits` | `int` | `8` | 数据位。 |
|
||||
| `StopBits` | `StopBits` | `One` | 停止位。 |
|
||||
| `Handshake` | `Handshake` | `None` | 握手方式。 |
|
||||
| `ReadTimeout` | `int` | `100` | 读超时,单位毫秒。 |
|
||||
| `WriteTimeout` | `int` | `1000` | 写超时,单位毫秒。 |
|
||||
| `RtsEnable` | `bool` | `true` | 是否启用 RTS。 |
|
||||
| `DtrEnable` | `bool` | `true` | 是否启用 DTR。 |
|
||||
| `AutoReconnect` | `bool` | `true` | 连接异常后是否继续自动重连。 |
|
||||
| `ReconnectInterval` | `int` | `1000` | 自动重连间隔,单位毫秒。 |
|
||||
| `MaxPendingSendCount` | `int` | `256` | 待发送数据容量。 |
|
||||
|
||||
实际设备的 COM 口和 UART 参数可能不同,请以设备配置为准。
|
||||
|
||||
## CardInfo
|
||||
|
||||
`CardInfo` 是 `OnCardReceived` 提供的卡片信息:
|
||||
|
||||
```csharp
|
||||
public CardType CardType { get; }
|
||||
public byte CardTypeCode { get; }
|
||||
public string CardNumber { get; }
|
||||
```
|
||||
|
||||
- `CardType`:当前已知类型为 `CardType.EM4100`。
|
||||
- `CardTypeCode`:设备上报的原始类型码。未知类型不会丢失。
|
||||
- `CardNumber`:十进制卡号字符串。
|
||||
|
||||
### CardNumber 规则
|
||||
|
||||
`CardNumber` 的类型为 `string`,表示十进制卡号字符串。默认最小长度为 10 位:不足 10 位时左侧补 `0`,超过 10 位时不截断。
|
||||
|
||||
## CardType
|
||||
|
||||
```csharp
|
||||
public enum CardType
|
||||
{
|
||||
Unknown = 0,
|
||||
EM4100 = 0x02
|
||||
}
|
||||
```
|
||||
|
||||
## 错误事件
|
||||
|
||||
`OnError` 提供 `CardReaderErrorEventArgs`:
|
||||
|
||||
```csharp
|
||||
public CardReaderException Exception { get; }
|
||||
```
|
||||
|
||||
`Exception` 是真实异常对象。常见原因包括 COM 端口不存在、端口被其他程序占用和连接失败。相同的连接错误不会持续重复派发,但在 `AutoReconnect` 开启时 SDK 仍会继续尝试连接。
|
||||
|
||||
## 事件使用约定
|
||||
|
||||
推荐在 `OnEnable` 中使用 `AddListener` 注册,在 `OnDisable` 中使用 `RemoveListener` 解除。生命周期示例:
|
||||
|
||||
```csharp
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
}
|
||||
```
|
||||
|
||||
`CardReaderManager` 销毁或应用退出时会自动释放串口资源。
|
||||
88
Documentation~/GettingStarted.en.md
Normal file
88
Documentation~/GettingStarted.en.md
Normal file
@ -0,0 +1,88 @@
|
||||
# Getting Started
|
||||
|
||||
This guide describes the actual usage flow for AISU 830T Card Reader SDK v0.1.0.
|
||||
|
||||
## 1. Install the package
|
||||
|
||||
In Unity Package Manager, choose **Add package from git URL...** and enter:
|
||||
|
||||
```text
|
||||
https://git.aisu.xin/aisu-sdk/card-reader-830t-package.git
|
||||
```
|
||||
|
||||
The Package ID is `xin.aisu.card-reader-830t`. The minimum Unity version is 2021.3, and the current supported platform is Windows.
|
||||
|
||||
## 2. Import the Basic Sample
|
||||
|
||||
Open the package details, find the **Samples** section, and click **Import** for **Basic**. Open the imported `Scenes/CardReaderSample.unity` scene.
|
||||
|
||||
## 3. Add CardReaderManager
|
||||
|
||||
Create a GameObject in the scene and add the `CardReaderManager` component. Keep one Manager instance in the scene.
|
||||
|
||||
## 4. Configure the serial port
|
||||
|
||||
Configure `SerialOptions` in the Manager Inspector:
|
||||
|
||||
- `PortName`: the actual Windows COM port, for example `COM3`.
|
||||
- `BaudRate`, `Parity`, `DataBits`, and `StopBits`: use the reader's settings.
|
||||
- Keep the other defaults, or configure `ReadTimeout`, `WriteTimeout`, `AutoReconnect`, `ReconnectInterval`, and `MaxPendingSendCount` as needed.
|
||||
|
||||
## 5. Open and listen for events
|
||||
|
||||
Register listeners with `AddListener`, then call `CardReaderApi.Open()`:
|
||||
|
||||
```csharp
|
||||
using Aisu.CardReader;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class CardReaderUsage : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnError);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CardReaderApi.Open();
|
||||
}
|
||||
|
||||
private static void OnConnected()
|
||||
{
|
||||
Debug.Log("Reader connected.");
|
||||
}
|
||||
|
||||
private static void OnCardReceived(CardInfo card)
|
||||
{
|
||||
Debug.Log($"{card.CardType}: {card.CardNumber}");
|
||||
}
|
||||
|
||||
private static void OnError(CardReaderErrorEventArgs error)
|
||||
{
|
||||
Debug.LogError(error.Exception.Message);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnError);
|
||||
CardReaderApi.Close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Once connected, present a card to the reader and handle `OnCardReceived`. `CardInfo.CardNumber` is a decimal string with a default minimum width of 10 digits; shorter values are left-padded with `0`, and longer values are not truncated.
|
||||
|
||||
## 6. Close
|
||||
|
||||
Call `CardReaderApi.Close()` to close the current connection and stop automatic reconnect. You can call `Open()` again later.
|
||||
|
||||
You can also call `OpenReader()` and `CloseReader()` on the current Manager.
|
||||
|
||||
## Lifetime
|
||||
|
||||
`CardReaderManager` releases serial resources when it is destroyed or when the application exits. Register events in `OnEnable` and remove them with `RemoveListener` in `OnDisable`. Without an active Manager, `CardReaderApi.Open()`, `Close()`, and event access throw `InvalidOperationException`.
|
||||
88
Documentation~/GettingStarted.zh-CN.md
Normal file
88
Documentation~/GettingStarted.zh-CN.md
Normal file
@ -0,0 +1,88 @@
|
||||
# 快速开始
|
||||
|
||||
本文介绍 AISU 830T Card Reader SDK v0.1.0 的实际使用流程。
|
||||
|
||||
## 1. 安装 Package
|
||||
|
||||
在 Unity Package Manager 选择 **Add package from git URL...**,输入:
|
||||
|
||||
```text
|
||||
https://git.aisu.xin/aisu-sdk/card-reader-830t-package.git
|
||||
```
|
||||
|
||||
Package ID 为 `xin.aisu.card-reader-830t`,最低 Unity 版本为 2021.3,当前支持 Windows。
|
||||
|
||||
## 2. 导入 Basic Sample
|
||||
|
||||
打开包详情中的 **Samples** 区域,点击 **Import** 导入 **Basic**。使用导入后的 `Scenes/CardReaderSample.unity`。
|
||||
|
||||
## 3. 添加 CardReaderManager
|
||||
|
||||
在场景中创建一个 GameObject,添加 `CardReaderManager` 组件。场景中保持一个 Manager 实例。
|
||||
|
||||
## 4. 配置串口
|
||||
|
||||
在 Manager Inspector 中设置 `SerialOptions`:
|
||||
|
||||
- `PortName`:实际 Windows COM 端口,例如 `COM3`。
|
||||
- `BaudRate`、`Parity`、`DataBits`、`StopBits`:按读卡器参数设置。
|
||||
- 其他字段保留默认值,或按项目需要配置 `ReadTimeout`、`WriteTimeout`、`AutoReconnect`、`ReconnectInterval` 和 `MaxPendingSendCount`。
|
||||
|
||||
## 5. Open 与事件监听
|
||||
|
||||
使用 `AddListener` 注册事件,并调用 `CardReaderApi.Open()`:
|
||||
|
||||
```csharp
|
||||
using Aisu.CardReader;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class CardReaderUsage : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnError);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CardReaderApi.Open();
|
||||
}
|
||||
|
||||
private static void OnConnected()
|
||||
{
|
||||
Debug.Log("Reader connected.");
|
||||
}
|
||||
|
||||
private static void OnCardReceived(CardInfo card)
|
||||
{
|
||||
Debug.Log($"{card.CardType}: {card.CardNumber}");
|
||||
}
|
||||
|
||||
private static void OnError(CardReaderErrorEventArgs error)
|
||||
{
|
||||
Debug.LogError(error.Exception.Message);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnError);
|
||||
CardReaderApi.Close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
设备连接后,将卡片靠近读卡器即可收到 `OnCardReceived`。事件中的 `CardInfo.CardNumber` 是十进制字符串:默认最小 10 位,不足时左侧补 `0`,超过 10 位不截断。
|
||||
|
||||
## 6. Close
|
||||
|
||||
调用 `CardReaderApi.Close()` 关闭当前连接并停止自动重连。之后可以再次调用 `Open()`。
|
||||
|
||||
也可以直接调用当前 Manager 的 `OpenReader()` 和 `CloseReader()`。
|
||||
|
||||
## 生命周期
|
||||
|
||||
`CardReaderManager` 被销毁或应用退出时会自动释放串口资源。事件建议在 `OnEnable` 注册、在 `OnDisable` 使用 `RemoveListener` 解除。没有活动 Manager 时调用 `CardReaderApi.Open()`、`Close()` 或访问事件会抛出 `InvalidOperationException`。
|
||||
17
Documentation~/index.md
Normal file
17
Documentation~/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
# AISU 830T Card Reader SDK Documentation
|
||||
|
||||
## 中文
|
||||
|
||||
- [快速开始](GettingStarted.zh-CN.md)
|
||||
- [API 参考](API.zh-CN.md)
|
||||
- [Basic Sample](../Samples~/Basic/README.md)
|
||||
|
||||
## English
|
||||
|
||||
- [Getting Started](GettingStarted.en.md)
|
||||
- [API Reference](API.en.md)
|
||||
- [Basic Sample](../Samples~/Basic/README.en.md)
|
||||
|
||||
SDK version: `0.1.0`
|
||||
|
||||
Package ID: `xin.aisu.card-reader-830t`
|
||||
157
README.en.md
Normal file
157
README.en.md
Normal file
@ -0,0 +1,157 @@
|
||||
# AISU 830T Card Reader SDK
|
||||
|
||||
AISU 830T Card Reader SDK is a Unity UPM package for connecting an 830T card reader and receiving card data reported by the device.
|
||||
|
||||
## Supported environment
|
||||
|
||||
- Unity 2021.3 or later
|
||||
- AISU 830T Card Reader
|
||||
- Package ID: `xin.aisu.card-reader-830t`
|
||||
|
||||
Android, Wiegand, active card search/read/write commands, and ACK/NAK APIs are not supported in this release.
|
||||
|
||||
## Installation
|
||||
|
||||
In Unity Package Manager, choose **Add package from git URL...** and enter:
|
||||
|
||||
```text
|
||||
https://git.aisu.xin/aisu-sdk/card-reader-830t-package.git
|
||||
```
|
||||
|
||||
You can also add the package from a local folder. After installation, import **Basic** or **Console Demo** from the package's **Samples** section.
|
||||
|
||||
## Quick start
|
||||
|
||||
Place one `CardReaderManager` in the scene, configure `SerialOptions` in the Inspector, and use `CardReaderApi`:
|
||||
|
||||
```csharp
|
||||
using Aisu.CardReader;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class CardReaderExample : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnError);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CardReaderApi.Open();
|
||||
}
|
||||
|
||||
private static void OnConnected()
|
||||
{
|
||||
Debug.Log("Card reader connected.");
|
||||
}
|
||||
|
||||
private static void OnCardReceived(CardInfo card)
|
||||
{
|
||||
Debug.Log($"{card.CardType} ({card.CardTypeCode:X2}): {card.CardNumber}");
|
||||
}
|
||||
|
||||
private static void OnError(CardReaderErrorEventArgs error)
|
||||
{
|
||||
Debug.LogError(error.Exception.Message);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnError);
|
||||
CardReaderApi.Close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## CardReaderManager
|
||||
|
||||
`CardReaderManager` is the scene-level entry point. Keep one Manager instance in the scene. It exposes `SerialOptions`, `IsConnected`, `OpenReader()`, `CloseReader()`, and connection, disconnection, state, card, and error events.
|
||||
|
||||
## Inspector serial settings
|
||||
|
||||
`SerialOptions` uses `SerialDeviceOptions`. The currently exposed fields are:
|
||||
|
||||
- `PortName`: Windows COM port, for example `COM3`.
|
||||
- `BaudRate`: baud rate, default `9600`.
|
||||
- `Parity`: parity mode, default `None`.
|
||||
- `DataBits`: data bits, default `8`.
|
||||
- `StopBits`: stop bits, default `One`.
|
||||
- `Handshake`: handshake mode, default `None`.
|
||||
- `ReadTimeout`: read timeout in milliseconds, default `100`.
|
||||
- `WriteTimeout`: write timeout in milliseconds, default `1000`.
|
||||
- `RtsEnable` / `DtrEnable`: RTS/DTR flags, enabled by default.
|
||||
- `AutoReconnect`: whether to retry after a connection failure, enabled by default.
|
||||
- `ReconnectInterval`: retry interval in milliseconds, default `1000`.
|
||||
- `MaxPendingSendCount`: send queue capacity, default `256`.
|
||||
|
||||
Configure the UART fields for the actual device. The Samples do not contain a fixed local COM port.
|
||||
|
||||
## CardReaderApi and events
|
||||
|
||||
`CardReaderApi` is the static access point for the current Manager. It provides:
|
||||
|
||||
- `Open()`: starts the reader connection.
|
||||
- `Close()`: closes the current connection and stops automatic reconnect; `Open()` can be called again later.
|
||||
- `IsConnected`: current connection state.
|
||||
- `OnConnected`, `OnDisconnected`, `OnStateChanged`, `OnCardReceived`, and `OnError`.
|
||||
|
||||
Use `AddListener` to subscribe and `RemoveListener` to unsubscribe. Pair them in `OnEnable` and `OnDisable`. Accessing events or calling `Open`/`Close` without an active `CardReaderManager` throws `InvalidOperationException`.
|
||||
|
||||
## CardInfo and CardNumber
|
||||
|
||||
`CardInfo` contains:
|
||||
|
||||
- `CardType`: the currently mapped type is `CardType.EM4100`.
|
||||
- `CardTypeCode`: the raw type code reported by the device.
|
||||
- `CardNumber`: a decimal card-number string of type `string`.
|
||||
|
||||
`CardNumber` has a default minimum width of 10 digits. Values shorter than 10 digits are left-padded with `0`; longer values are not truncated.
|
||||
|
||||
## Automatic reconnect and errors
|
||||
|
||||
When `AutoReconnect` is enabled, the SDK continues retrying after a connection failure according to `ReconnectInterval`. `OnError` provides the actual `Exception`; common causes include a missing COM port, a port already in use, or a failed connection. Identical connection errors are not repeatedly emitted, while automatic reconnect continues.
|
||||
|
||||
## Samples
|
||||
|
||||
- **Basic**: full UI controls, COM-port selection, connection state, card information, and error log display.
|
||||
- **Console Demo**: minimal API calls and console logging.
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### No COM port is listed
|
||||
|
||||
Confirm that the reader is connected and its driver is installed. Check the actual COM name in Windows Device Manager. The Basic Sample's **Refresh** button rescans available ports.
|
||||
|
||||
### The COM port is already in use
|
||||
|
||||
Close other serial tools or applications using the port, then select it again and call `Open()`.
|
||||
|
||||
### The reader cannot connect
|
||||
|
||||
Check `PortName`, baud rate, parity, data bits, and stop bits against the device settings. Also confirm that no other program owns the port.
|
||||
|
||||
### How does automatic reconnect work?
|
||||
|
||||
With `AutoReconnect` enabled, the SDK retries at `ReconnectInterval`. Calling `Close()` stops the current connection and automatic reconnect.
|
||||
|
||||
### Are serial resources released when Unity exits?
|
||||
|
||||
`CardReaderManager` releases the serial resources when it is destroyed or when the application exits.
|
||||
|
||||
### How do I import the Basic Sample?
|
||||
|
||||
After installing the package, open its details in Package Manager, find **Samples**, and click **Import** for **Basic**. A version directory in the imported path is standard Unity behavior.
|
||||
|
||||
## Version
|
||||
|
||||
This documentation describes SDK `v0.1.0`.
|
||||
|
||||
More information:
|
||||
|
||||
- [Getting Started](Documentation~/GettingStarted.en.md)
|
||||
- [API reference](Documentation~/API.en.md)
|
||||
- [Basic Sample guide](Samples~/Basic/README.en.md)
|
||||
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# AISU 830T Card Reader SDK
|
||||
|
||||
Unity package for integrating AISU 830T card readers.
|
||||
|
||||
Language:
|
||||
|
||||
- [中文](README.zh-CN.md)
|
||||
- [English](README.en.md)
|
||||
7
README.md.meta
Normal file
7
README.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df6324a2d5fda2947a4601402d564451
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
157
README.zh-CN.md
Normal file
157
README.zh-CN.md
Normal file
@ -0,0 +1,157 @@
|
||||
# AISU 830T Card Reader SDK
|
||||
|
||||
AISU 830T Card Reader SDK 是一个面向 Unity 的 UPM Package,用于在 Windows 上连接 830T 读卡器,接收设备主动上报的卡片信息。
|
||||
|
||||
## 支持环境
|
||||
|
||||
- Unity 2021.3 或更高版本
|
||||
- AISU 830T Card Reader
|
||||
- Package ID:`xin.aisu.card-reader-830t`
|
||||
|
||||
当前不支持 Wiegand、主动寻卡/读卡/写卡命令或 ACK/NAK API。
|
||||
|
||||
## 安装
|
||||
|
||||
在 Unity Package Manager 中选择 **Add package from git URL...**,输入:
|
||||
|
||||
```text
|
||||
https://git.aisu.xin/aisu-sdk/card-reader-830t-package.git
|
||||
```
|
||||
|
||||
也可以将本地 Package 目录添加到 Unity 项目。安装后,在包详情的 **Samples** 区域导入 **Basic** 或 **Console Demo**。
|
||||
|
||||
## 快速开始
|
||||
|
||||
在场景中放置一个 `CardReaderManager`,在 Inspector 中配置 `SerialOptions`,然后使用 `CardReaderApi`:
|
||||
|
||||
```csharp
|
||||
using Aisu.CardReader;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class CardReaderExample : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnError);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CardReaderApi.Open();
|
||||
}
|
||||
|
||||
private static void OnConnected()
|
||||
{
|
||||
Debug.Log("Card reader connected.");
|
||||
}
|
||||
|
||||
private static void OnCardReceived(CardInfo card)
|
||||
{
|
||||
Debug.Log($"{card.CardType} ({card.CardTypeCode:X2}): {card.CardNumber}");
|
||||
}
|
||||
|
||||
private static void OnError(CardReaderErrorEventArgs error)
|
||||
{
|
||||
Debug.LogError(error.Exception.Message);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnError);
|
||||
CardReaderApi.Close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## CardReaderManager
|
||||
|
||||
`CardReaderManager` 是场景级入口。场景中应保持一个 Manager 实例。它提供 `SerialOptions`、`IsConnected`、`OpenReader()`、`CloseReader()` 以及连接、断开、状态、卡片和错误事件。
|
||||
|
||||
## Inspector 串口参数
|
||||
|
||||
`SerialOptions` 类型为 `SerialDeviceOptions`,当前公开字段如下:
|
||||
|
||||
- `PortName`:Windows COM 端口,例如 `COM3`。
|
||||
- `BaudRate`:波特率,默认 `9600`。
|
||||
- `Parity`:校验方式,默认 `None`。
|
||||
- `DataBits`:数据位,默认 `8`。
|
||||
- `StopBits`:停止位,默认 `One`。
|
||||
- `Handshake`:握手方式,默认 `None`。
|
||||
- `ReadTimeout`:读超时毫秒数,默认 `100`。
|
||||
- `WriteTimeout`:写超时毫秒数,默认 `1000`。
|
||||
- `RtsEnable` / `DtrEnable`:RTS/DTR,默认开启。
|
||||
- `AutoReconnect`:连接异常后是否自动重连,默认开启。
|
||||
- `ReconnectInterval`:重连间隔毫秒数,默认 `1000`。
|
||||
- `MaxPendingSendCount`:发送队列容量,默认 `256`。
|
||||
|
||||
请根据实际设备参数配置 UART 字段。Sample 不包含固定的本地 COM 端口。
|
||||
|
||||
## CardReaderApi 与事件
|
||||
|
||||
`CardReaderApi` 是当前 Manager 的静态访问入口,提供:
|
||||
|
||||
- `Open()`:启动 Reader 连接。
|
||||
- `Close()`:关闭当前连接并停止自动重连;之后可以再次 `Open()`。
|
||||
- `IsConnected`:当前连接状态。
|
||||
- `OnConnected`、`OnDisconnected`、`OnStateChanged`、`OnCardReceived`、`OnError`。
|
||||
|
||||
事件使用 `AddListener` 注册、`RemoveListener` 解除,建议在 `OnEnable` 和 `OnDisable` 中成对处理。没有活动的 `CardReaderManager` 时访问事件或调用 `Open`/`Close` 会抛出 `InvalidOperationException`。
|
||||
|
||||
## CardInfo 与 CardNumber
|
||||
|
||||
`CardInfo` 包含:
|
||||
|
||||
- `CardType`:当前已知类型为 `CardType.EM4100`。
|
||||
- `CardTypeCode`:设备上报的原始类型码。
|
||||
- `CardNumber`:类型为 `string` 的十进制卡号字符串。
|
||||
|
||||
`CardNumber` 默认最小长度为 10 位;不足 10 位时在左侧补 `0`,超过 10 位时不截断。
|
||||
|
||||
## 自动重连与错误处理
|
||||
|
||||
当 `AutoReconnect` 开启时,连接异常后 SDK 会按 `ReconnectInterval` 继续尝试连接。`OnError` 提供真实的 `Exception`,常见原因包括 COM 端口不存在、端口被占用或连接失败。相同的连接错误不会持续刷出重复事件,但 SDK 仍会继续自动重连。
|
||||
|
||||
## Samples
|
||||
|
||||
- **Basic**:完整 UI 操作、COM 端口选择、连接状态、卡片信息和错误日志显示。
|
||||
- **Console Demo**:最小 API 调用和日志输出示例。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 找不到 COM 端口
|
||||
|
||||
确认设备已连接、驱动已安装,并在 Windows 设备管理器中查看实际 COM 名称。Basic Sample 的 **Refresh** 会重新扫描端口。
|
||||
|
||||
### COM 端口被占用
|
||||
|
||||
关闭其他串口工具或正在使用该端口的程序,然后重新选择端口并调用 `Open()`。
|
||||
|
||||
### 无法连接 Reader
|
||||
|
||||
检查 `PortName`、波特率、Parity、DataBits 和 StopBits 是否与设备设置一致,并确认设备没有被其他程序占用。
|
||||
|
||||
### 自动重连如何工作
|
||||
|
||||
开启 `AutoReconnect` 后,SDK 会按 `ReconnectInterval` 重试。调用 `Close()` 会停止当前连接和自动重连。
|
||||
|
||||
### Unity 退出后是否释放串口
|
||||
|
||||
`CardReaderManager` 在销毁或应用退出时会自动释放串口资源。
|
||||
|
||||
### 如何导入 Basic Sample
|
||||
|
||||
安装 Package 后,在 Package Manager 的包详情中找到 **Samples**,点击 **Import** 导入 **Basic**。导入路径带有版本目录是 Unity 的标准行为。
|
||||
|
||||
## 版本
|
||||
|
||||
当前文档对应 SDK `v0.1.0`。
|
||||
|
||||
更多内容:
|
||||
|
||||
- [快速开始](Documentation~/GettingStarted.zh-CN.md)
|
||||
- [API 文档](Documentation~/API.zh-CN.md)
|
||||
- [Basic Sample 文档](Samples~/Basic/README.md)
|
||||
8
Runtime.meta
Normal file
8
Runtime.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04b022d97a25bee4f9c23b88297ff5a4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Plugins.meta
Normal file
8
Runtime/Plugins.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30b0694242524259a249d31bf2e082c5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Runtime/Plugins/Aisu.CardReader.Card830T.Runtime.dll
Normal file
BIN
Runtime/Plugins/Aisu.CardReader.Card830T.Runtime.dll
Normal file
Binary file not shown.
32
Runtime/Plugins/Aisu.CardReader.Card830T.Runtime.dll.meta
Normal file
32
Runtime/Plugins/Aisu.CardReader.Card830T.Runtime.dll.meta
Normal file
@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23419227fdc74ce8aa78b6eb70b2b722
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Standalone: Windows
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Samples~.meta
Normal file
8
Samples~.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1b1ba0e7a4541c9a518d103a0b2c355
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
25
Samples~/Basic/README.en.md
Normal file
25
Samples~/Basic/README.en.md
Normal file
@ -0,0 +1,25 @@
|
||||
# AISU 830T Basic Sample
|
||||
|
||||
The Basic Sample provides a complete Unity UI for Windows reader integration: COM-port selection, connection state, card information, and error logs.
|
||||
|
||||
## Import
|
||||
|
||||
1. Install `xin.aisu.card-reader-830t` through Unity Package Manager.
|
||||
2. Open the package details and import **Basic** from **Samples**.
|
||||
3. Open the imported `Scenes/CardReaderSample.unity` scene.
|
||||
|
||||
## Select a COM port and connect
|
||||
|
||||
1. Run the project on Windows in the Unity Editor or a Windows Standalone build.
|
||||
2. Click **Refresh** to scan the available COM ports.
|
||||
3. Select the COM port connected to the AISU 830T reader.
|
||||
4. Confirm the UART settings in the scene's `CardReaderManager.SerialOptions`.
|
||||
5. Click **Open**.
|
||||
|
||||
## Present a card
|
||||
|
||||
After the reader connects, present a card. The UI displays `CardType`, `CardTypeCode`, and the decimal `CardNumber` when the reader reports card data.
|
||||
|
||||
## Disconnect
|
||||
|
||||
Click **Close** to close the connection and stop automatic reconnect. The Manager also releases serial resources when the scene or application is destroyed.
|
||||
7
Samples~/Basic/README.en.md.meta
Normal file
7
Samples~/Basic/README.en.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f4e2c1a7b6d4e90a3c5f1d2e6b8a407
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Samples~/Basic/README.md
Normal file
28
Samples~/Basic/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# AISU 830T Basic Sample
|
||||
|
||||
该 Sample 用于 Windows + Unity Editor/Standalone 的实机联调,使用包内已提供的 `Scenes/CardReaderSample.unity` 和 `Scripts/CardReaderSampleUI.cs`。
|
||||
|
||||
## 导入
|
||||
|
||||
1. 在 Package Manager 安装 `xin.aisu.card-reader-830t`。
|
||||
2. 在包详情的 **Samples** 区域导入 **Basic**。
|
||||
3. 打开导入后的 `Scenes/CardReaderSample.unity`。
|
||||
|
||||
## 选择 COM 与连接
|
||||
|
||||
1. 运行 Windows Unity Editor 或 Windows Standalone。
|
||||
2. 点击 **Refresh**,Sample 使用 `SerialPort.GetPortNames()` 扫描当前 COM 端口。
|
||||
3. 选择 830T 对应的 COM 口,并按实际设备参数确认 UART 配置。
|
||||
4. 点击 **Open**。端口不存在、被占用或参数不完整时,错误会显示在 Sample 日志中。
|
||||
|
||||
## 刷卡
|
||||
|
||||
连接成功后,将卡片靠近已连接的 830T 读卡器。设备主动上报完整帧时,界面显示 `CardType`、原始 `CardTypeCode` 和 `CardNumber`。Sample 不发送寻卡或读卡命令。
|
||||
|
||||
## 断开
|
||||
|
||||
点击 **Close** 停止接收并关闭串口。切换场景或销毁组件时,Manager 也会执行清理和资源释放。
|
||||
|
||||
## Console Demo
|
||||
|
||||
包内另有 **Console Demo** Sample,使用 `CardReaderApi` 的 `Open`、`Close`、`OnConnected`、`OnCardReceived`、`OnDisconnected` 和 `OnError`。导入后请在场景中的 `CardReaderManager.SerialOptions.PortName` 选择实际 COM 口。
|
||||
7
Samples~/Basic/README.md.meta
Normal file
7
Samples~/Basic/README.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a71e3c5f8b2d4a609c1e7f3b5d8a2c40
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
5126
Samples~/Basic/Scenes/CardReaderSample.unity
Normal file
5126
Samples~/Basic/Scenes/CardReaderSample.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Samples~/Basic/Scenes/CardReaderSample.unity.meta
Normal file
7
Samples~/Basic/Scenes/CardReaderSample.unity.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9191a9de2297dad41840d247eeadb6d7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
234
Samples~/Basic/Scripts/CardReaderSampleUI.cs
Normal file
234
Samples~/Basic/Scripts/CardReaderSampleUI.cs
Normal file
@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Aisu.CardReader.Samples
|
||||
{
|
||||
/// <summary>用于 Windows 实机联调的最小 Unity UI 示例。</summary>
|
||||
public sealed class CardReaderSampleUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Dropdown portDropdown;
|
||||
[SerializeField] private Button refreshButton;
|
||||
[SerializeField] private Button openButton;
|
||||
[SerializeField] private Button closeButton;
|
||||
[SerializeField] private Text stateText;
|
||||
[SerializeField] private Text portText;
|
||||
[SerializeField] private Text cardTypeText;
|
||||
[SerializeField] private Text cardNumberText;
|
||||
[SerializeField] private Text lastEventTimeText;
|
||||
[SerializeField] private Text errorText;
|
||||
[SerializeField] private Text logText;
|
||||
private readonly List<string> portNames = new List<string>();
|
||||
private readonly List<string> logLines = new List<string>();
|
||||
private CardReaderManager manager;
|
||||
private bool operationInProgress;
|
||||
private bool destroying;
|
||||
private bool apiSubscribed;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
manager = CardReaderManager.Instance;
|
||||
SetText(stateText, "状态:未连接");
|
||||
SetText(portText, "端口:-");
|
||||
SetText(cardTypeText, "CardType:-");
|
||||
SetText(cardNumberText, "CardNumber:-");
|
||||
SetText(lastEventTimeText, "最后事件:-");
|
||||
SetText(errorText, "错误:-");
|
||||
SetText(logText, "日志:-");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
refreshButton?.onClick.AddListener(RefreshPorts);
|
||||
openButton?.onClick.AddListener(OpenSelectedPort);
|
||||
closeButton?.onClick.AddListener(CloseReader);
|
||||
SubscribeApiEvents();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Manager 与 Sample 的 Awake 顺序不应影响事件订阅和首次端口扫描。
|
||||
SubscribeApiEvents();
|
||||
RefreshPorts();
|
||||
}
|
||||
|
||||
private void SubscribeApiEvents()
|
||||
{
|
||||
if (apiSubscribed) return;
|
||||
if (manager == null) manager = CardReaderManager.Instance;
|
||||
if (manager == null) return;
|
||||
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnDisconnected.AddListener(OnDisconnected);
|
||||
CardReaderApi.OnStateChanged.AddListener(OnStateChanged);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnReaderError);
|
||||
apiSubscribed = true;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
refreshButton?.onClick.RemoveListener(RefreshPorts);
|
||||
openButton?.onClick.RemoveListener(OpenSelectedPort);
|
||||
closeButton?.onClick.RemoveListener(CloseReader);
|
||||
if (!apiSubscribed || manager == null) return;
|
||||
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnDisconnected.RemoveListener(OnDisconnected);
|
||||
CardReaderApi.OnStateChanged.RemoveListener(OnStateChanged);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnReaderError);
|
||||
apiSubscribed = false;
|
||||
}
|
||||
|
||||
public void RefreshPorts()
|
||||
{
|
||||
if (destroying || operationInProgress) return;
|
||||
var previousPort = GetSelectedPort();
|
||||
portNames.Clear();
|
||||
portNames.AddRange(SerialPort.GetPortNames());
|
||||
portNames.Sort(StringComparer.OrdinalIgnoreCase);
|
||||
if (portDropdown != null)
|
||||
{
|
||||
var options = portNames.Count == 0
|
||||
? new List<string> { "No Ports" }
|
||||
: new List<string>(portNames);
|
||||
portDropdown.ClearOptions();
|
||||
portDropdown.AddOptions(options);
|
||||
var selectedIndex = previousPort == null ? 0 : portNames.IndexOf(previousPort);
|
||||
portDropdown.value = selectedIndex < 0 ? 0 : selectedIndex;
|
||||
portDropdown.RefreshShownValue();
|
||||
}
|
||||
SetText(portText, portNames.Count == 0 ? "端口:未发现串口" : "端口:" + GetSelectedPort());
|
||||
if (portNames.Count == 0) SetStateText("未发现串口");
|
||||
AppendLog(portNames.Count == 0 ? "未发现可用串口。" : "发现串口:" + string.Join(", ", portNames));
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
public void OpenSelectedPort()
|
||||
{
|
||||
if (destroying || operationInProgress || manager == null || portDropdown == null || portNames.Count == 0)
|
||||
return;
|
||||
|
||||
operationInProgress = true;
|
||||
UpdateButtons();
|
||||
try
|
||||
{
|
||||
var selectedPort = GetSelectedPort();
|
||||
if (string.IsNullOrEmpty(selectedPort)) return;
|
||||
var current = manager.SerialOptions;
|
||||
manager.SerialOptions = new SerialDeviceOptions
|
||||
{
|
||||
PortName = selectedPort, BaudRate = current.BaudRate,
|
||||
Parity = current.Parity, DataBits = current.DataBits, StopBits = current.StopBits,
|
||||
Handshake = current.Handshake, RtsEnable = current.RtsEnable, DtrEnable = current.DtrEnable,
|
||||
ReadTimeout = current.ReadTimeout, WriteTimeout = current.WriteTimeout,
|
||||
AutoReconnect = current.AutoReconnect, ReconnectInterval = current.ReconnectInterval,
|
||||
MaxPendingSendCount = current.MaxPendingSendCount
|
||||
};
|
||||
CardReaderApi.Open();
|
||||
SetText(portText, "端口:" + selectedPort);
|
||||
AppendLog("已打开读卡器:" + selectedPort);
|
||||
}
|
||||
catch (Exception exception) { ShowError("连接失败", exception); }
|
||||
finally { operationInProgress = false; UpdateButtons(); }
|
||||
}
|
||||
|
||||
public void CloseReader()
|
||||
{
|
||||
if (destroying || operationInProgress || manager == null) return;
|
||||
operationInProgress = true;
|
||||
try
|
||||
{
|
||||
CardReaderApi.Close();
|
||||
AppendLog("已关闭读卡器。");
|
||||
}
|
||||
catch (Exception exception) { ShowError("断开失败", exception); }
|
||||
finally { operationInProgress = false; UpdateButtons(); }
|
||||
}
|
||||
|
||||
private void OnConnected()
|
||||
{
|
||||
SetStateText("Connected");
|
||||
AppendLog("读卡器已连接。");
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void OnDisconnected()
|
||||
{
|
||||
SetStateText("Disconnected");
|
||||
AppendLog("读卡器已断开。");
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void OnStateChanged(SerialDeviceState state)
|
||||
{
|
||||
SetStateText(state.ToString());
|
||||
AppendLog("状态:" + state);
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void OnCardReceived(CardInfo card)
|
||||
{
|
||||
SetText(cardTypeText, $"CardType:{card.CardType} (0x{card.CardTypeCode:X2})");
|
||||
SetText(cardNumberText, $"CardNumber:{card.CardNumber}");
|
||||
SetText(lastEventTimeText, $"最后事件:{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
|
||||
AppendLog("收到卡片:" + card.CardNumber);
|
||||
}
|
||||
private void OnReaderError(CardReaderErrorEventArgs args) { ShowError("Transport/Core 错误", args.Exception); }
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
destroying = true;
|
||||
}
|
||||
|
||||
private void UpdateButtons()
|
||||
{
|
||||
var connected = manager != null && manager.IsConnected;
|
||||
if (refreshButton != null) refreshButton.interactable = !operationInProgress && !connected;
|
||||
if (openButton != null) openButton.interactable = !operationInProgress && !connected && portNames.Count > 0;
|
||||
if (closeButton != null) closeButton.interactable = !operationInProgress && connected;
|
||||
}
|
||||
|
||||
private void ShowError(string message, Exception exception)
|
||||
{
|
||||
var text = exception == null ? message : message + ":" + FormatException(exception);
|
||||
SetText(errorText, "错误:" + text);
|
||||
AppendLog(text);
|
||||
Debug.LogError("[AISU 830T Sample] " + text, this);
|
||||
}
|
||||
|
||||
private string GetSelectedPort()
|
||||
{
|
||||
if (portDropdown == null || portDropdown.value < 0 || portDropdown.value >= portNames.Count)
|
||||
return null;
|
||||
return portNames[portDropdown.value];
|
||||
}
|
||||
|
||||
private void SetStateText(string state) { SetText(stateText, "状态:" + state); }
|
||||
|
||||
private void AppendLog(string message)
|
||||
{
|
||||
if (logText == null) return;
|
||||
logLines.Add(DateTime.Now.ToString("HH:mm:ss.fff") + " " + message);
|
||||
if (logLines.Count > 40) logLines.RemoveAt(0);
|
||||
SetText(logText, "日志:\n" + string.Join("\n", logLines));
|
||||
}
|
||||
|
||||
private static string FormatException(Exception exception)
|
||||
{
|
||||
var current = exception;
|
||||
var result = exception.GetType().Name + ": " + exception.Message;
|
||||
while (current.InnerException != null)
|
||||
{
|
||||
current = current.InnerException;
|
||||
result += " | " + current.GetType().Name + ": " + current.Message;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetText(Text target, string value) { if (target != null) target.text = value; }
|
||||
}
|
||||
}
|
||||
11
Samples~/Basic/Scripts/CardReaderSampleUI.cs.meta
Normal file
11
Samples~/Basic/Scripts/CardReaderSampleUI.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d9c4f0bca3e4dbd8b2f7c4d9e1a6f20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
12
Samples~/Console Demo/README.en.md
Normal file
12
Samples~/Console Demo/README.en.md
Normal file
@ -0,0 +1,12 @@
|
||||
# AISU 830T Console Demo
|
||||
|
||||
Console Demo is a minimal logging sample that demonstrates `CardReaderApi` connection, disconnection, event subscription, and card-data output.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Install `xin.aisu.card-reader-830t`.
|
||||
2. Import **Console Demo** from the package's **Samples** section in Package Manager.
|
||||
3. Open the imported `Scenes/SampleScene.unity` scene.
|
||||
4. Set the actual COM port and UART settings in `CardReaderManager.SerialOptions`.
|
||||
5. Run the scene. The sample uses `CardReaderApi.Open()` and writes connection, card, error, and disconnection messages to the Unity Console.
|
||||
6. When the scene stops, the sample calls `CardReaderApi.Close()` and removes its listeners.
|
||||
7
Samples~/Console Demo/README.en.md.meta
Normal file
7
Samples~/Console Demo/README.en.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d1f8a3c5b7e4290a2c4f6d8b1e3a750
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
12
Samples~/Console Demo/README.zh-CN.md
Normal file
12
Samples~/Console Demo/README.zh-CN.md
Normal file
@ -0,0 +1,12 @@
|
||||
# AISU 830T Console Demo
|
||||
|
||||
Console Demo 是最小 API 调用和日志输出示例,用于演示 `CardReaderApi` 的连接、断开、事件监听和卡片信息输出。
|
||||
|
||||
## 使用
|
||||
|
||||
1. 安装 `xin.aisu.card-reader-830t`。
|
||||
2. 在 Package Manager 的 **Samples** 区域导入 **Console Demo**。
|
||||
3. 打开导入后的 `Scenes/SampleScene.unity`。
|
||||
4. 在场景中的 `CardReaderManager.SerialOptions` 设置实际 COM 端口和 UART 参数。
|
||||
5. 运行场景。示例使用 `CardReaderApi.Open()`,并将连接、卡片、错误和断开信息输出到 Unity Console。
|
||||
6. 停止场景时示例调用 `CardReaderApi.Close()` 并解除监听。
|
||||
7
Samples~/Console Demo/README.zh-CN.md.meta
Normal file
7
Samples~/Console Demo/README.zh-CN.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a7c9e4f1b6d4380a5e2c7f9b3d81460
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Samples~/Console Demo/Scenes.meta
Normal file
8
Samples~/Console Demo/Scenes.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a2787d9312860343befc5d46c9545de
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
359
Samples~/Console Demo/Scenes/SampleScene.unity
Normal file
359
Samples~/Console Demo/Scenes/SampleScene.unity
Normal file
@ -0,0 +1,359 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 9
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
m_FogDensity: 0.01
|
||||
m_LinearFogStart: 0
|
||||
m_LinearFogEnd: 300
|
||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 0
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
m_HaloTexture: {fileID: 0}
|
||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_DefaultReflectionMode: 0
|
||||
m_DefaultReflectionResolution: 128
|
||||
m_ReflectionBounces: 1
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 705507994}
|
||||
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 12
|
||||
m_GIWorkflowMode: 1
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_FinalGather: 0
|
||||
m_FinalGatherFiltering: 1
|
||||
m_FinalGatherRayCount: 256
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 500
|
||||
m_PVRBounces: 2
|
||||
m_PVREnvironmentSampleCount: 500
|
||||
m_PVREnvironmentReferencePointCount: 2048
|
||||
m_PVRFilteringMode: 2
|
||||
m_PVRDenoiserTypeDirect: 0
|
||||
m_PVRDenoiserTypeIndirect: 0
|
||||
m_PVRDenoiserTypeAO: 0
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVREnvironmentMIS: 0
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_LightProbeSampleCountMultiplier: 4
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_LightingSettings: {fileID: 0}
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &705507993
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 705507995}
|
||||
- component: {fileID: 705507994}
|
||||
m_Layer: 0
|
||||
m_Name: Directional Light
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!108 &705507994
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 705507993}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 10
|
||||
m_Type: 1
|
||||
m_Shape: 0
|
||||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
|
||||
m_Intensity: 1
|
||||
m_Range: 10
|
||||
m_SpotAngle: 30
|
||||
m_InnerSpotAngle: 21.80208
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_CullingMatrixOverride:
|
||||
e00: 1
|
||||
e01: 0
|
||||
e02: 0
|
||||
e03: 0
|
||||
e10: 0
|
||||
e11: 1
|
||||
e12: 0
|
||||
e13: 0
|
||||
e20: 0
|
||||
e21: 0
|
||||
e22: 1
|
||||
e23: 0
|
||||
e30: 0
|
||||
e31: 0
|
||||
e32: 0
|
||||
e33: 1
|
||||
m_UseCullingMatrixOverride: 0
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingLayerMask: 1
|
||||
m_Lightmapping: 1
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_UseBoundingSphereOverride: 0
|
||||
m_UseViewFrustumForShadowCasterCull: 1
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
--- !u!4 &705507995
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 705507993}
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &963194225
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 963194228}
|
||||
- component: {fileID: 963194227}
|
||||
- component: {fileID: 963194226}
|
||||
- component: {fileID: 963194230}
|
||||
- component: {fileID: 963194229}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!81 &963194226
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &963194227
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 1
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_FocalLength: 50
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &963194228
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &963194229
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 8d870f68f8917954ba64b45d81cffc2c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &963194230
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 23419227fdc74ce8aa78b6eb70b2b722, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
serialOptions:
|
||||
PortName:
|
||||
BaudRate: 9600
|
||||
Parity: 0
|
||||
DataBits: 8
|
||||
StopBits: 1
|
||||
Handshake: 0
|
||||
ReadTimeout: 100
|
||||
WriteTimeout: 1000
|
||||
RtsEnable: 1
|
||||
DtrEnable: 1
|
||||
AutoReconnect: 1
|
||||
ReconnectInterval: 1000
|
||||
MaxPendingSendCount: 256
|
||||
openOnStart: 0
|
||||
onConnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
onDisconnected:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
onStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
onCardReceived:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
onError:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
7
Samples~/Console Demo/Scenes/SampleScene.unity.meta
Normal file
7
Samples~/Console Demo/Scenes/SampleScene.unity.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fc0d4010bbf28b4594072e72b8655ab
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Samples~/Console Demo/Scripts.meta
Normal file
8
Samples~/Console Demo/Scripts.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe930ff4a01082c46a7763a7047dc4f5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
43
Samples~/Console Demo/Scripts/CardReaderConsoleTest.cs
Normal file
43
Samples~/Console Demo/Scripts/CardReaderConsoleTest.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using Aisu.CardReader;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class CardReaderConsoleTest : MonoBehaviour
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
CardReaderApi.OnConnected.AddListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.AddListener(OnCardReceived);
|
||||
CardReaderApi.OnError.AddListener(OnError);
|
||||
CardReaderApi.OnDisconnected.AddListener(OnDisconnected);
|
||||
CardReaderApi.Open();
|
||||
}
|
||||
|
||||
private static void OnConnected()
|
||||
{
|
||||
Debug.Log("On Connected.");
|
||||
}
|
||||
|
||||
private static void OnCardReceived(CardInfo card)
|
||||
{
|
||||
Debug.Log($"{card.CardType} ({card.CardTypeCode:X2}): {card.CardNumber}");
|
||||
}
|
||||
|
||||
private static void OnError(CardReaderErrorEventArgs error)
|
||||
{
|
||||
Debug.LogError(error.Exception.Message);
|
||||
}
|
||||
|
||||
private static void OnDisconnected()
|
||||
{
|
||||
Debug.Log("On Disconnected.");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CardReaderApi.OnConnected.RemoveListener(OnConnected);
|
||||
CardReaderApi.OnCardReceived.RemoveListener(OnCardReceived);
|
||||
CardReaderApi.OnError.RemoveListener(OnError);
|
||||
CardReaderApi.OnDisconnected.RemoveListener(OnDisconnected);
|
||||
CardReaderApi.Close();
|
||||
}
|
||||
}
|
||||
11
Samples~/Console Demo/Scripts/CardReaderConsoleTest.cs.meta
Normal file
11
Samples~/Console Demo/Scripts/CardReaderConsoleTest.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d870f68f8917954ba64b45d81cffc2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
25
package.json
Normal file
25
package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "xin.aisu.card-reader-830t",
|
||||
"displayName": "AISU 830T Card Reader SDK",
|
||||
"version": "0.1.0",
|
||||
"unity": "2021.3",
|
||||
"description": "AISU 830T card reader SDK for Unity on Windows.",
|
||||
"samples": [
|
||||
{
|
||||
"displayName": "Basic",
|
||||
"description": "Basic Card Reader usage sample.",
|
||||
"path": "Samples~/Basic"
|
||||
},
|
||||
{
|
||||
"displayName": "Console Demo",
|
||||
"description": "Minimal console-style sample demonstrating the Card Reader SDK API.",
|
||||
"path": "Samples~/Console Demo"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"com.unity.ugui": "1.0.0"
|
||||
},
|
||||
"author": {
|
||||
"name": "AISU"
|
||||
}
|
||||
}
|
||||
7
package.json.meta
Normal file
7
package.json.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bae067ad5ccd4f44e893d57f7f231c2a
|
||||
PackageManifestImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
x
Reference in New Issue
Block a user