「Qtの基礎 - シリアル通信」の版間の差分

ナビゲーションに移動 検索に移動
109行目: 109行目:
<br>
<br>
まず、<code>QObject</code>クラスを継承したクラスを定義する。<br>
まず、<code>QObject</code>クラスを継承したクラスを定義する。<br>
シリアルポートからのデータの受信を管理するためのスロットを用意する。<br>
シリアルポートからのデータの送受信を管理するためのスロットを用意する。<br>
以下の例では、シリアルポートがデータを受信したことを検出するために、<code>readyRead</code>シグナルを使用している。<br>
<br>
* シリアルポートがデータを受信したことを検出するために、<code>readyRead</code>シグナルを使用する。
*: <br>
* シリアルポートがデータを送信完了したことを検出するために、<code>QIODevice::bytesWritten</code>シグナルを使用する。
*: <code>QIODevice::bytesWritten</code>シグナルは、データがデバイスのバッファに書き込まれた時に発生する。
*: これは必ずしも物理的な送信完了を意味するわけではない。
*: 大量のデータを送信する場合、<code>QIODevice::bytesWritten</code>シグナルは複数回発生する可能性がある。
*: <br>
*: 必要に応じて、送信データのサイズを記録して、
*: <code>QIODevice::bytesWritten</code>シグナルで受信したバイト数の合計がそのサイズに達した時に"送信完了"とみなすロジックを追加することもできる。
<br>
以下の例では、8N1設定の非同期シリアル通信を行っている。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // Sample.hファイル
  // SerialCommunication.hファイル
   
   
  #include <QCoreApplication>
  #include <QCoreApplication>
118行目: 129行目:
  #include <QDebug>
  #include <QDebug>
   
   
  class SerialPortReader : public QObject
  class SerialCommunication : public QObject
  {
  {
     Q_OBJECT
     Q_OBJECT
private:
    QSerialPort *m_serialPort;
  public:
  public:
     SerialPortReader(QSerialPort *serialPort, QObject *parent = nullptr) : QObject(parent), m_serialPort(serialPort)
     explicit SerialCommunication(QObject *parent = nullptr) : QObject(parent)
    {
      m_serialPort = new QSerialPort(this);
      connect(m_serialPort, &QSerialPort::readyRead, this, &SerialCommunication::handleReadyRead);
      connect(m_serialPort, &QSerialPort::errorOccurred, this, &SerialCommunication::handleError);
    }
    bool openPort(const QString &portName)
     {
     {
       connect(m_serialPort, &QSerialPort::readyRead, this, &SerialPortReader::handleReadyRead);
       m_serialPort->setPortName(portName);
      m_serialPort->setBaudRate(QSerialPort::Baud9600);
      m_serialPort->setDataBits(QSerialPort::Data8);
      m_serialPort->setParity(QSerialPort::NoParity);
      m_serialPort->setStopBits(QSerialPort::OneStop);
      m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
      if (m_serialPort->open(QIODevice::ReadWrite)) {
          qDebug() << "シリアルポートのオープンに成功";
          return true;
      }
      else {
          qDebug() << "シリアルポートのオープンに失敗: " << m_serialPort->errorString();
          return false;
      }
    }
    void sendData(const QByteArray &data)
    {
      if (m_serialPort->isOpen()) {
          qint64 bytesWritten = m_serialPort->write(data);
          if (bytesWritten == -1) {
            qDebug() << "ポートへのデータの書き込みに失敗: " << m_serialPort->errorString();
          }
          else if (bytesWritten != data.size()) {
            qDebug() << "ポートへの全データの書き込みに失敗 - 書き込まれたバイト数: " << bytesWritten;
          }
          m_serialPort->flush();
      }
      else {
          qDebug() << "データの送信に失敗 : シリアルポートがオープンされていない";
      }
     }
     }
   
   
130行目: 183行目:
     void handleReadyRead()
     void handleReadyRead()
     {
     {
       const QByteArray data = m_serialPort->readAll();
       QByteArray data = m_serialPort->readAll();
       qDebug() << "Recieved data : " << data;
       qDebug() << "受信データ: " << data;
      // ここで受信したデータを処理する
      // ...略
    }
    void handleBytesWritten(qint64 bytes)
    {
      qDebug() << "送信データ: " << bytes;
      // ここで送信完了後の処理を行う
      // ...略
     }
     }
   
   
  private:
    void handleError(QSerialPort::SerialPortError error)
    QSerialPort *m_serialPort;
    {
      if (error == QSerialPort::NoError) {
          return;
      }
   
      qDebug() << "予期せぬエラー: " << m_serialPort->errorString();
      switch (error) {
          case QSerialPort::DeviceNotFoundError:
            qDebug() << "デバイスが見つからない : 接続を確認すること";
            break;
          case QSerialPort::PermissionError:
            qDebug() << "パーミッションエラー : 他のアプリケーションがそのポートを使用していないか確認すること";
            break;
          case QSerialPort::OpenError:
            qDebug() << "ポートのオープンに失敗 : 既に使用されていないか確認すること";
            break;
          case QSerialPort::WriteError:
            qDebug() << "送信エラー : 接続を確認して、再度送信できるかどうかを試すこと";
            break;
          case QSerialPort::ReadError:
            qDebug() << "受信エラー : 接続を確認して、再度受信できるかどうかを試すこと";
            break;
          case QSerialPort::ResourceError:
            qDebug() << "The port has been unexpectedly removed. Check the connection.";
            m_serialPort->close();
            break;
          default:
            qDebug() << "不明なエラー : 設定を確認すること";
      }
    }
  };
  };
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // Sample.cppファイル
  // main.cppファイル
   
   
  #include <QCoreApplication>
  #include "SerialCommunication.h"
#include <QSerialPort>
#include <QDebug>
   
   
  int main(int argc, char *argv[])
  int main(int argc, char *argv[])
  {
  {
     QCoreApplication app(argc, argv);
     QCoreApplication a(argc, argv);
   
   
     QSerialPort serial;
     SerialCommunication serialComm;
    serial.setPortName("/dev/ttyUSB0");                // シリアルポート名 (環境に合わせて変更すること)
    serial.setBaudRate(QSerialPort::Baud9600);        // ボーレート 9600[bps]
    serial.setDataBits(QSerialPort::Data8);            // データビット 8[ビット]
    serial.setParity(QSerialPort::NoParity);          // パリティなし
    serial.setStopBits(QSerialPort::OneStop);          // ストップビット 1[ビット]
    serial.setFlowControl(QSerialPort::NoFlowControl); // フロー制御なし
   
   
     if (!serial.open(QIODevice::ReadWrite)) {
    // 任意のポート名を指定すること
       qDebug() << "Could not open serial port : " << serial.errorString();
     if (serialComm.openPort("COM1")) {  
      return -1;
       serialComm.sendData("Hello, Serial Port!");
     }
     }
   
   
    SerialPortReader reader(&serial);
     return a.exec();
     return app.exec();
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

案内メニュー