「Qtの基礎 - Bluetooth Low Energy」の版間の差分

ナビゲーションに移動 検索に移動
166行目: 166行目:
==== 使用例 ====
==== 使用例 ====
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
// BLEデバイスのスキャンを管理するクラス
// BLEデバイスの検出と監視, 継続的なスキャンモード, デバイス情報の重複排除, 自動リカバリを行う
  #include <QObject>
  #include <QObject>
  #include <QBluetoothDeviceDiscoveryAgent>
  #include <QBluetoothDeviceDiscoveryAgent>
  #include <QBluetoothDeviceInfo>
  #include <QBluetoothDeviceInfo>
#include <memory>
  #include <QTimer>
  #include <QTimer>
  #include <QDebug>
  #include <QDebug>
178行目: 180行目:
   
   
  private:
  private:
     std::unique_ptr<QBluetoothDeviceDiscoveryAgent> discoveryAgent;
     QBluetoothDeviceDiscoveryAgent discoveryAgent; // BLEデバイス探索用エージェント
     std::unique_ptr<QTimer> rescanTimer;
     QTimer rescanTimer;                             // 継続的スキャン用タイマ
     bool isContinuousScan = false;
     bool   isContinuousScan = false;               // 継続的スキャンモードのフラグ
    QMap<QBluetoothAddress, QBluetoothDeviceInfo> knownDevices;  // 既知デバイスのキャッシュ
   
   
    // デバイス探索エージェントとタイマーのシグナルを適切なスロットに接続
    // デバイス発見時の処理, スキャン完了時の処理, エラー発生時の処理, 定期的な再スキャンの制御を行う
     void connectSignals()
     void connectSignals()
     {
     {
191行目: 196行目:
   
   
       // 再スキャンタイマのシグナル接続
       // 再スキャンタイマのシグナル接続
       connect(rescanTimer.get(), &QTimer::timeout, this, [this]() {
       connect(&rescanTimer, &QTimer::timeout, this, [this]() {
           if (isContinuousScan) {
           if (isContinuousScan) {
             discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
             discoveryAgent.start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
           }
           }
       });
       });
     }
     }
   
   
    // エラーコード
     QString getErrorMessage(QBluetoothDeviceDiscoveryAgent::Error error)
     QString getErrorMessage(QBluetoothDeviceDiscoveryAgent::Error error)
     {
     {
208行目: 214行目:
           case QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod:  return "未対応の探索方法";
           case QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod:  return "未対応の探索方法";
           default:                                                          return "不明なエラー";
           default:                                                          return "不明なエラー";
      }
    }
    // 発見されたデバイスの詳細情報をログに出力
    // デバイス名, MACアドレス, 電波強度 (RSSI), 提供サービスのUUID, メーカー固有データを表示
    void logDeviceInfo(const QBluetoothDeviceInfo& device)
    {
      qDebug() << "BLEデバイスを発見:";
      qDebug() << "  名前:" << device.name();
      qDebug() << "  アドレス:" << device.address().toString();
      qDebug() << "  RSSI:" << device.rssi();
      // サービスUUIDのログ出力
      const QList<QBluetoothUuid> serviceUuids = device.serviceUuids();
      if (!serviceUuids.isEmpty()) {
          qDebug() << "  提供サービス:";
          for (const QBluetoothUuid& uuid : serviceUuids) {
            qDebug() << "    -" << uuid.toString();
          }
      }
      // マニファクチャラーデータのログ出力
      const QMap<quint16, QByteArray> manufacturerData = device.manufacturerData();
      if (!manufacturerData.isEmpty()) {
          qDebug() << "  マニファクチャラーデータ:";
          QMap<quint16, QByteArray>::const_iterator i = manufacturerData.constBegin();
          while (i != manufacturerData.constEnd()) {
            qDebug() << "    ID: " << i.key() << "データ: " << i.value().toHex();
            i++;
          }
       }
       }
     }
     }
214行目: 250行目:
     explicit BLEDeviceScanner(QObject* parent = nullptr) : QObject(parent)
     explicit BLEDeviceScanner(QObject* parent = nullptr) : QObject(parent)
     {
     {
      // デバイス探索エージェントの初期化
      discoveryAgent = std::make_unique<QBluetoothDeviceDiscoveryAgent>(this);
       // BLEデバイスのみをスキャンするように設定
       // BLEデバイスのみをスキャンするように設定
       discoveryAgent->setLowEnergyDiscoveryTimeout(10000);  // 10秒のタイムアウト
       discoveryAgent.setLowEnergyDiscoveryTimeout(10000);  // 10秒のタイムアウト
   
   
       // 自動再スキャンタイマの設定
       // 自動再スキャンタイマの設定
       rescanTimer = std::make_unique<QTimer>(this);
       rescanTimer.setInterval(30000);  // 30秒間隔で再スキャン
      rescanTimer->setInterval(30000);  // 30秒間隔で再スキャン
   
   
       connectSignals();
       connectSignals();
     }
     }
   
   
     // スキャンを開始
     // BLEデバイスのスキャンを開始
     void startScan(bool continuous = false)
     void startScan(bool continuous = false)
     {
     {
233行目: 265行目:
           qDebug() << "BLEデバイススキャンを開始...";
           qDebug() << "BLEデバイススキャンを開始...";
           isContinuousScan = continuous;
           isContinuousScan = continuous;
           discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
           discoveryAgent.start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
   
   
           if (continuous) rescanTimer->start();
           if (continuous) rescanTimer.start();
   
   
           emit scanStarted();
           emit scanStarted();
251行目: 283行目:
       try {
       try {
           qDebug() << "BLEデバイススキャンを停止...";
           qDebug() << "BLEデバイススキャンを停止...";
           discoveryAgent->stop();
           discoveryAgent.stop();
           rescanTimer->stop();
           rescanTimer.stop();
           isContinuousScan = false;
           isContinuousScan = false;
           emit scanStopped();
           emit scanStopped();
264行目: 296行目:
   
   
  signals:
  signals:
     void deviceDiscovered(const QBluetoothDeviceInfo& device);
     void deviceDiscovered(const QBluetoothDeviceInfo& device); // 新規デバイス発見時
     void scanStarted();
     void scanStarted();   // スキャン開始時
     void scanStopped();
     void scanStopped();   // スキャン停止時
     void scanFinished();
     void scanFinished();   // スキャン完了時
     void errorOccurred(const QString& error);
     void errorOccurred(const QString& error); // エラー発生時
   
   
  private slots:
  private slots:
    // デバイス発見時の処理
    // BLEデバイスのフィルタリング, 重複デバイスの検出と更新, デバイス情報のログ出力, 新規 / 更新デバイスの通知
     void onDeviceDiscovered(const QBluetoothDeviceInfo& device)
     void onDeviceDiscovered(const QBluetoothDeviceInfo& device)
     {
     {
       // BLEデバイスのみを処理
       // BLEデバイスのみを処理
      if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
        if (!(device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration)) {
          qDebug() << "BLEデバイスを発見:";
          return;
          qDebug() << "  名前:" << device.name();
        }
          qDebug() << "  アドレス:" << device.address().toString();
          qDebug() << "  RSSI:" << device.rssi();
          // アドバタイズメントデータの解析
          const QList<QBluetoothUuid> serviceUuids = device.serviceUuids();
          if (!serviceUuids.isEmpty()) {
            qDebug() << "  提供サービス:";
            for (const QBluetoothUuid& uuid : serviceUuids) {
                qDebug() << "    -" << uuid.toString();
            }
          }
   
   
          // マニファクチャラーデータの解析
        // デバイスの重複確認
          const QMap<quint16, QByteArray> manufacturerData = device.manufacturerData();
        const QBluetoothAddress& address = device.address();
          if (!manufacturerData.isEmpty()) {
        if (!knownDevices.contains(address) || knownDevices[address].rssi() != device.rssi()) {
            qDebug() << "  マニファクチャラーデータ:";
            knownDevices[address] = device;
            QMap<quint16, QByteArray>::const_iterator i = manufacturerData.constBegin();
            while (i != manufacturerData.constEnd()) {
                qDebug() << "    ID: " << i.key() << "データ: " << i.value().toHex();
                ++i;
            }
          }
   
   
          emit deviceDiscovered(device);
            // デバイス情報のログ出力と通知
      }
            logDeviceInfo(device);
            emit deviceDiscovered(device);
        }
     }
     }
   
   
    // スキャン完了時の処理
    // 完了通知の発行, 継続的スキャンモードの場合は1秒後に再スキャン
     void onScanFinished()
     void onScanFinished()
     {
     {
317行目: 338行目:
     }
     }
   
   
    // エラー発生時の処理 (エラーメッセージの生成とログ出力)
    // 継続的スキャンモードの場合は5秒後に自動再試行
     void onError(QBluetoothDeviceDiscoveryAgent::Error error)
     void onError(QBluetoothDeviceDiscoveryAgent::Error error)
     {
     {

案内メニュー