npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

com.xrlab.labframe_brainbit

v1.1.2

Published

BrainBit Support for LabFrame2023. Note: Currently only supports BrainBit in lab!!

Readme

LabFrame BrainBit Package

LabFrame BrainBit Package 是給 LabFrame 2023 專案使用的 BrainBit 腦波儀套件。它負責搜尋與連接 BrainBit、讀取 EEG 腦波與阻抗資料,並可把資料自動寫入 LabFrame 的資料系統。套件也整合 NeuroSDK 的情緒與頻譜分析,讓實驗或互動專案可以直接取得專注、放鬆與五頻段腦波比例。

這份文件面向使用者與實驗操作人員,重點是怎麼安裝、怎麼戴、怎麼開始錄資料,以及錄出來的資料代表什麼。

支援功能

  • 搜尋並連接 BrainBit 藍牙低功耗裝置。
  • 讀取 4 通道 EEG:T3T4O1O2
  • 檢查 4 通道阻抗,協助確認電極與頭皮接觸狀態。
  • 依實驗階段用不同 tag 自動寫入 LabFrame 資料。
  • 即時取得專注、放鬆與 DeltaThetaAlphaBetaGamma 五頻段百分比。
  • 提供阻抗檢查 UI 控制器與範例場景。

設備說明

本套件主要支援實驗室使用的 BrainBit Headband。BrainBit 是 4 通道乾式 EEG 頭帶,透過 Bluetooth LE 連線。官方文件標示 BrainBit 有 O1O2T3T4 四個資料通道,每個通道取樣頻率為 250 Hz。

| 通道 | 位置 | 常見用途 | |---|---|---| | T3 | 左側顳葉區 | 常用於注意、專注相關節律觀察 | | T4 | 右側顳葉區 | 常用於注意、專注相關節律觀察 | | O1 | 左側枕葉區 | 常用於 alpha、放鬆相關節律觀察 | | O2 | 右側枕葉區 | 常用於 alpha、放鬆相關節律觀察 |

配戴時,前額的參考/共用電極要貼在額頭,T3T4 靠近左右顳側,O1O2 靠近後腦枕側。頭帶要貼合但不需要勒緊;如果阻抗過高,通常代表接觸不穩、頭髮擋住電極、頭帶位置偏移,或裝置電極沒有確實貼到皮膚。

本套件不是醫療診斷工具。EEG、專注、放鬆與頻譜資料適合用於研究、教育、互動體驗與實驗紀錄,不應直接解讀為醫療結論。

安裝

1. Unity 與 LabFrame

  • 建議 Unity 版本:2022.3.62f2,或同系列 2022.3 LTS。
  • 需要 LabFrame package:com.xrlab.labframe
  • 本 package 的 package.json 已依賴 BrainBit NeuroSDK2

2. 安裝情緒/頻譜分析套件

此 package 的情緒與頻譜功能會使用 SignalMath,請在 Unity Package Manager 加入下列 Git URL:

https://github.com/BrainbitLLC/unity_em_st_artifacts.git#a04238a934b3da0494dd9120a489005277063a1f

目前建議使用上面的固定 commit。開發時曾遇過較新的 Android 版本套件相容性問題,因此不要任意升級到最新版,除非你已經重新測試 Android build。

3. 平台權限

Android 權限已放在:

Packages/LabFrame_Brainbit/Runtime/Plugins/Android/AndroidManifest.xml

它包含定位、Bluetooth scan、Bluetooth connect 等權限。實機第一次啟動時仍可能需要使用者允許權限。

iOS build 後處理會自動加入藍牙用途文字:

NSBluetoothAlwaysUsageDescription
NSBluetoothPeripheralUsageDescription

建議使用流程

  1. 開啟 BrainBit,確認電量足夠。
  2. 在手機、平板或電腦開啟藍牙,並允許 App 使用藍牙與定位權限。
  3. 戴上 BrainBit,調整前額與左右/後方電極位置。
  4. 呼叫 ManualConnect() 或使用範例 UI 連線。
  5. 先開啟阻抗檢查,確認 4 個通道接觸穩定。
  6. 停止阻抗檢查。
  7. 開始 EEG 錄製,並用 tag 標示實驗階段。
  8. 若需要專注、放鬆或頻譜資料,啟動情緒處理並等待校正完成。
  9. 實驗階段切換時,用 SetEEGTag()SetMindTag()SetSpectralTag() 切換資料 tag。
  10. 結束時停止情緒處理、EEG 與阻抗串流,必要時斷線。

快速開始

連接設備

預設不會在遊戲啟動時自動連線。請在開始畫面、準備階段或使用者按下按鈕時呼叫:

BrainBitManager.Instance.ManualConnect();

斷線:

BrainBitManager.Instance.ManualDisconnect();

常用狀態:

bool connected = BrainBitManager.Instance.IsConnected;
bool scanning = BrainBitManager.Instance.IsScanning;
string deviceName = BrainBitManager.Instance.ConnectedDeviceName;
string deviceAddress = BrainBitManager.Instance.ConnectedDeviceAddress;

阻抗檢查

阻抗資料用來確認電極接觸品質。建議在正式錄 EEG 前先檢查阻抗,確認通道穩定後再開始實驗。

BrainBitManager.Instance.StartImpedanceStream(
    autoWriteToLabData: false,
    tag: "precheck_impedance");

讀取目前阻抗:

var impedance = BrainBitManager.Instance.GetLatestImpedanceData();
if (impedance != null)
{
    Debug.Log(impedance.ToString());

    if (impedance.IsImpedanceGood)
    {
        Debug.Log("All channels are ready.");
    }
    else
    {
        Debug.LogWarning(impedance.GetImpedanceStatus());
    }
}

停止阻抗檢查:

BrainBitManager.Instance.StopImpedanceStream();

本套件目前用 200000 ohm 作為預設警示門檻。若任何通道高於此值,IsImpedanceGood 會是 false

EEG 錄製

開始 EEG:

BrainBitManager.Instance.StartEEGStream(
    autoWriteToLabData: true,
    tag: "baseline_eeg");

取得最新 EEG:

var eeg = BrainBitManager.Instance.GetLatestEEGData();
if (eeg != null)
{
    Debug.Log($"T3:{eeg.T3} T4:{eeg.T4} O1:{eeg.O1} O2:{eeg.O2}");
}

切換實驗階段時,不需要停止 EEG,可以直接改 tag:

BrainBitManager.Instance.SetEEGTag("task1_eeg");

停止 EEG:

BrainBitManager.Instance.StopEEGStream();

專注、放鬆與五頻段資料

情緒處理會使用 EEG 訊號計算 MindData 與 SpectralData。啟動後需要先校正,預設校正時間為 6 秒。校正完成前 GetLatestMindData()GetLatestSpectralData() 可能回傳 null

啟動:

BrainBitManager.Instance.StartEmotionsProcessing(
    autoWriteToLabData: true,
    mindTag: "baseline_mind",
    spectralTag: "baseline_spectral");

監聽校正:

BrainBitManager.Instance.OnCalibrationProgress += progress =>
{
    Debug.Log($"Calibration: {progress}%");
};

BrainBitManager.Instance.OnCalibrationFinished += () =>
{
    Debug.Log("Calibration finished.");
};

讀取專注與放鬆:

if (BrainBitManager.Instance.IsEmotionsCalibrated)
{
    var mind = BrainBitManager.Instance.GetLatestMindData();
    if (mind != null)
    {
        Debug.Log($"Attention:{mind.Attention:F1} Relaxation:{mind.Relaxation:F1}");
    }
}

讀取五頻段百分比:

var spectral = BrainBitManager.Instance.GetLatestSpectralData();
if (spectral != null)
{
    Debug.Log(
        $"Delta:{spectral.Delta:F1} " +
        $"Theta:{spectral.Theta:F1} " +
        $"Alpha:{spectral.Alpha:F1} " +
        $"Beta:{spectral.Beta:F1} " +
        $"Gamma:{spectral.Gamma:F1}");
}

切換 tag:

BrainBitManager.Instance.SetMindTag("task1_mind");
BrainBitManager.Instance.SetSpectralTag("task1_spectral");

停止:

BrainBitManager.Instance.StopEmotionsProcessing();

若中途換受測者、頭帶取下後重新戴上,或資料明顯不穩,可以重新校正:

BrainBitManager.Instance.RestartCalibration();

完整範例程式

以下範例示範一個常見實驗流程:連線、檢查阻抗、開始錄 EEG 與情緒資料、切換階段、結束錄製。

using UnityEngine;

public class BrainBitSessionExample : MonoBehaviour
{
    private void OnEnable()
    {
        BrainBitManager.Instance.OnConnectionStatusChanged += HandleConnectionChanged;
        BrainBitManager.Instance.OnCalibrationProgress += HandleCalibrationProgress;
        BrainBitManager.Instance.OnCalibrationFinished += HandleCalibrationFinished;
        BrainBitManager.Instance.OnError += HandleError;
    }

    private void OnDisable()
    {
        if (BrainBitManager.Instance == null) return;

        BrainBitManager.Instance.OnConnectionStatusChanged -= HandleConnectionChanged;
        BrainBitManager.Instance.OnCalibrationProgress -= HandleCalibrationProgress;
        BrainBitManager.Instance.OnCalibrationFinished -= HandleCalibrationFinished;
        BrainBitManager.Instance.OnError -= HandleError;
    }

    public void ConnectBrainBit()
    {
        BrainBitManager.Instance.ManualConnect();
    }

    private void HandleConnectionChanged(bool connected)
    {
        if (!connected) return;

        Debug.Log($"Connected: {BrainBitManager.Instance.ConnectedDeviceName}");

        BrainBitManager.Instance.StartImpedanceStream(
            autoWriteToLabData: false,
            tag: "precheck_impedance");
    }

    public void StartRecordingIfReady()
    {
        var impedance = BrainBitManager.Instance.GetLatestImpedanceData();
        if (impedance == null || !impedance.IsImpedanceGood)
        {
            Debug.LogWarning("BrainBit impedance is not ready. Adjust the headband first.");
            return;
        }

        BrainBitManager.Instance.StopImpedanceStream();

        BrainBitManager.Instance.StartEEGStream(
            autoWriteToLabData: true,
            tag: "baseline_eeg");

        BrainBitManager.Instance.StartEmotionsProcessing(
            autoWriteToLabData: true,
            mindTag: "baseline_mind",
            spectralTag: "baseline_spectral");
    }

    public void SetExperimentPhase(string phaseName)
    {
        BrainBitManager.Instance.SetEEGTag($"{phaseName}_eeg");
        BrainBitManager.Instance.SetMindTag($"{phaseName}_mind");
        BrainBitManager.Instance.SetSpectralTag($"{phaseName}_spectral");
    }

    private void Update()
    {
        if (!BrainBitManager.Instance.IsEmotionsCalibrated) return;

        var mind = BrainBitManager.Instance.GetLatestMindData();
        var spectral = BrainBitManager.Instance.GetLatestSpectralData();

        if (mind != null)
        {
            Debug.Log($"Attention:{mind.Attention:F1} Relaxation:{mind.Relaxation:F1}");
        }

        if (spectral != null)
        {
            Debug.Log($"Alpha:{spectral.Alpha:F1} Beta:{spectral.Beta:F1}");
        }
    }

    public void StopRecording()
    {
        BrainBitManager.Instance.StopEmotionsProcessing();
        BrainBitManager.Instance.StopEEGStream();
        BrainBitManager.Instance.StopImpedanceStream();
    }

    private void HandleCalibrationProgress(int progress)
    {
        Debug.Log($"Calibration progress: {progress}%");
    }

    private void HandleCalibrationFinished()
    {
        Debug.Log("BrainBit emotion calibration finished.");
    }

    private void HandleError(string message)
    {
        Debug.LogError($"BrainBit error: {message}");
    }
}

範例場景

本 repo 內有一個範例場景:

Packages/LabFrame_Brainbit/Sample/SampleScene.unity

範例場景使用 BrainBitCheckController 顯示連線狀態、阻抗數值與阻抗警示。它適合拿來做實驗前的配戴檢查畫面,也可以直接參考按鈕如何呼叫 BrainBitManager

資料格式

autoWriteToLabData 設為 trueLabDataManager 已初始化時,套件會把資料物件寫入 LabFrame。實際檔案位置與檔案格式由 LabFrame 專案設定決定;下面列的是本套件交給 LabFrame 的資料欄位。

EEG:BrainBit_EEGData

| 欄位 | 型別 | 單位 | 說明 | |---|---|---|---| | T3 | double | V | 左側顳葉通道 EEG | | T4 | double | V | 右側顳葉通道 EEG | | O1 | double | V | 左側枕葉通道 EEG | | O2 | double | V | 右側枕葉通道 EEG | | EEGValues | List<double> | V | 順序為 T3T4O1O2 |

BrainBit 官方資料流每通道為 250 samples/sec。本套件保留最新一筆 EEG,可用 GetLatestEEGData() 取得。

阻抗:BrainBit_ImpedanceData

| 欄位 | 型別 | 單位 | 說明 | |---|---|---|---| | T3 | double | ohm | 左側顳葉通道阻抗 | | T4 | double | ohm | 右側顳葉通道阻抗 | | O1 | double | ohm | 左側枕葉通道阻抗 | | O2 | double | ohm | 右側枕葉通道阻抗 | | ImpedanceValues | List<double> | ohm | 順序為 T3T4O1O2 | | IsImpedanceGood | bool | 無 | 4 通道都低於 200000 ohm 時為 true |

輔助方法:

string status = impedance.GetImpedanceStatus();
var values = impedance.GetImpedanceValues();

專注與放鬆:BrainBit_MindData

| 欄位 | 型別 | 範圍 | 說明 | |---|---|---|---| | Attention | double | 約 0-100 | 相對專注度,較平滑,建議顯示給使用者 | | Relaxation | double | 約 0-100 | 相對放鬆度,較平滑,建議顯示給使用者 | | InstAttention | double | 約 0-100 | 瞬時專注度,波動較大 | | InstRelaxation | double | 約 0-100 | 瞬時放鬆度,波動較大 |

MindData 必須等 IsEmotionsCalibrated == true 後才有穩定意義。

五頻段百分比:BrainBit_SpectralData

| 欄位 | 型別 | 單位 | 說明 | |---|---|---|---| | Delta | double | percent | Delta 波百分比 | | Theta | double | percent | Theta 波百分比 | | Alpha | double | percent | Alpha 波百分比 | | Beta | double | percent | Beta 波百分比 | | Gamma | double | percent | Gamma 波百分比 |

連線事件:BrainBit_ConnectionData

| 欄位 | 型別 | 說明 | |---|---|---| | IsConnected | bool | 連線狀態 | | DeviceName | string | BrainBit 裝置名稱 | | DeviceAddress | string | BrainBit 裝置位址 | | EventType | string | ConnectedDisconnectedEEG_Stream_Started 等事件 |

Tag 與資料分段

tag 是寫入 LabFrame 時用來區分資料階段的名稱。建議使用清楚且穩定的命名,例如:

baseline_eeg
baseline_mind
baseline_spectral
task1_eeg
task1_mind
task1_spectral
rest_impedance

EEG、MindData、SpectralData 都可以在不中斷串流的情況下切換 tag:

BrainBitManager.Instance.SetEEGTag("task2_eeg");
BrainBitManager.Instance.SetMindTag("task2_mind");
BrainBitManager.Instance.SetSpectralTag("task2_spectral");

下一筆寫入的資料會使用新的 tag。

事件 API

若你不想在 Update() 裡輪詢,可以訂閱事件:

BrainBitManager.Instance.OnEEGDataReceived += data =>
{
    Debug.Log(data.ToString());
};

BrainBitManager.Instance.OnImpedanceDataReceived += data =>
{
    Debug.Log(data.GetImpedanceStatus());
};

BrainBitManager.Instance.OnMindDataReceived += data =>
{
    Debug.Log($"Attention:{data.Attention:F1}");
};

BrainBitManager.Instance.OnSpectralDataReceived += data =>
{
    Debug.Log($"Alpha:{data.Alpha:F1}");
};

BrainBitManager.Instance.OnEmotionsArtifact += hasArtifact =>
{
    if (hasArtifact)
    {
        Debug.LogWarning("BrainBit signal artifact detected.");
    }
};

設定項目

BrainBitConfig 可控制掃描、重連與情緒校正行為。

| 欄位 | 預設 | 說明 | |---|---:|---| | AutoConnectOnInit | false | Manager 初始化後是否自動掃描連線 | | DisconnectNotification | true | 斷線時是否顯示提示 | | ScanTimeoutSeconds | 10.0 | 掃描逾時秒數 | | ImpedanceWarningThreshold | 200000.0 | 阻抗警示參考門檻,單位 ohm | | AutoReconnectAttempts | 3 | 斷線後自動重連嘗試次數 | | ReconnectIntervalSeconds | 2.0 | 重連間隔秒數 | | AutoSelectBestSignal | false | 多台 BrainBit 時是否選 RSSI 最強者 | | TargetDeviceAddress | "" | 優先連線的 BrainBit MAC;留空時維持原本選台行為 | | ConnectDelaySeconds | 1.0 | 停止掃描後等待多久才建立連線 | | EmotionsCalibrationLength | 6 | 情緒處理校正秒數 | | EmotionsMentalEstimation | false | 是否啟用 Mental Estimation | | EmotionsPrioritySide | SideType.NONE | 情緒分析優先腦側:NONELEFTRIGHT |

如果現場同時有多台 BrainBit,建議用 TargetDeviceAddress 優先指定 MAC。設定後,掃描會先尋找該 MAC;如果連續 3 次、每次間隔 2 秒的掃描結果都沒有看到目標,系統會改用原本的選台策略尋找其他 BrainBit。AutoSelectBestSignal 只建議在沒有指定 MAC、或目標 MAC 找不到後可接受用 RSSI 選台時使用。

Android 實機若要每台頭顯綁定不同 BrainBit,請在各裝置的 Application.persistentDataPath/Config/BrainBitConfig.json 放完整設定檔,例如:

{
    "AutoConnectOnInit": false,
    "DisconnectNotification": true,
    "ScanTimeoutSeconds": 20.0,
    "ImpedanceWarningThreshold": 200000.0,
    "AutoReconnectAttempts": 3,
    "ReconnectIntervalSeconds": 2.0,
    "AutoSelectBestSignal": false,
    "ConnectDelaySeconds": 1.0,
    "EmotionsCalibrationLength": 6,
    "EmotionsMentalEstimation": false,
    "EmotionsPrioritySide": 0,
    "TargetDeviceAddress": "E0:39:7A:68:75:58"
}

若裝置上已有舊版 BrainBitConfig.json,請整檔覆蓋成最新欄位;磁碟上的設定會優先於內建範本。

目前 BrainBit_ImpedanceData.IsImpedanceGood 使用 200000 ohm 作為判斷門檻;若你的實驗需要不同標準,請在 UI 或檢查流程中使用自訂門檻判斷。

設備資訊查詢

需要查看電量、韌體版本、硬體版本、取樣頻率等資訊時,可使用 SensorInfoProvider

using NeuroSDK;
using System.Collections.Generic;

void ShowDeviceInfo(BrainBitSensor sensor)
{
    Dictionary<string, string> parameters =
        SensorInfoProvider.GetBrainBitSensorParameters(sensor);

    foreach (var item in parameters)
    {
        Debug.Log($"{item.Key}: {item.Value}");
    }
}

一般使用者不一定需要呼叫這段。它比較適合現場除錯、確認電量與確認裝置版本。

常見問題

掃不到設備

  • 確認 BrainBit 已開機且有電。
  • 確認 App 已允許藍牙、定位與附近裝置權限。
  • 確認 BrainBit 沒有被其他 App 或其他手機連線。
  • 把 BrainBit 靠近執行 App 的裝置後再掃描。
  • 如果現場有多台 BrainBit,優先在 TargetDeviceAddress 填入指定 MAC;若目標連續 3 次、每次間隔 2 秒的掃描都找不到,Manager 會改找其他設備。

阻抗一直太高

  • 調整頭帶位置,讓 T3T4O1O2 更貼近頭皮。
  • 撥開頭髮,避免頭髮卡在電極與頭皮之間。
  • 確認前額參考電極有貼住皮膚。
  • 讓受測者先保持不動,再觀察數值是否下降。
  • 若只有單一通道高,優先調整該通道所在的位置。

MindData 或 SpectralData 一直是空的

  • 確認已呼叫 StartEmotionsProcessing()
  • 確認 EEG 正在輸入。
  • 等待 OnCalibrationFinishedIsEmotionsCalibrated == true
  • 校正期間請受測者保持安靜、少眨眼、少咬牙、少說話。
  • 若中途重新配戴,呼叫 RestartCalibration()

資料沒有寫入 LabFrame

  • 確認呼叫串流時 autoWriteToLabDatatrue
  • 確認 LabDataManager.Instance.IsInitedtrue
  • 確認 tag 不為空字串。
  • 確認有呼叫 StartEEGStream()StartEmotionsProcessing()

Android build 或執行出錯

  • 確認已安裝 unity_em_st_artifacts 固定 commit。
  • 確認 Android 權限已在實機上允許。
  • 若使用較新的 Android 版本,請特別檢查 BLUETOOTH_SCANBLUETOOTH_CONNECT 權限。

官方參考

  • BrainBit SDK - Receiving data: https://sdk.brainbit.com/sdk2_bb/
  • BrainBit SDK - Device recommendation: https://sdk.brainbit.com/device-recommendation/
  • BrainBit SDK - Emotions library: https://sdk.brainbit.com/lib-emotions/
  • BrainBit SDK - Overview and supported platforms: https://sdk.brainbit.com/sdk2_overview/