USB portでPCと通信してみます

〔Seeeduino XIAOの使い方に戻る〕


このページでは"Seeeduino XIAO"の(USB port)を使ってパソコンと通信をしてみます。
・CDCクラスでのシリアル通信
・HIDクラスでのマウスとキーボードのエミュレーション
又このUSB portは周辺機器用のUSBホスト(OTG)として動作すると思いますが、この記事は後日追記します。

《シリアル通信(CDC)》

@ XIAOの"USB port"とPCをUSB Type-Cコネクターケーブルで繋ぎます。

A ArduinoIDEを起動させ、ボードとポート設定を"Seeeduino XIAO"に設定します。

B IDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
---------------------------------------------------------------------
void setup()
{
     // USBでCDCクラスの初期化を行う
     SerialUSB.begin(9600);  // シリアル通信の速度は9600bps
     while (!SerialUSB) {
        ; // シリアルポートが接続するのを待ちます(ネイティブUSBポートにのみ必要)
     }
}
void loop()
{
     char inChar;

     if (SerialUSB.available() > 0) {
          // データが受信されたら1バイト読み込む
          while( -1 == (inChar = SerialUSB.read()) );
          // 読み込んだ"データ+1"で返す
          SerialUSB.println((char)(inChar+1));
     }
     delay(10);
}
---------------------------------------------------------------------
C スケッチをコンパイルして書き込みます。

D "Tera Term"等のターミナルツール等で操作しても良いのですが、ここは簡単にIDEのシリアルモニタを
  使いましょう。

E シリアルモニタを表示させ、送信ボックスに"a"を入れて[ENTER]を押して見て下さい。
  "b"が返されて表示されると思います。(送信データ+1の内容で返されます)

何とも簡単に出来てしまいました、流石Arduinoと言った所ですね、PICで苦労したのは何だったのぉ。

SerialUSBライブラリのの使い方説明

 void SerialUSB.begin(speed)
  USBでCDCクラスによるシリアル通信の初期化を行います。
   uint32_t speed:通信する速度を指定します

 SerialUSB(又はSerial)
  指定されたシリアルポートの準備ができているかどうかを調べます。
  ネイティブUSBを搭載したボードでは、if(Serial)(又はDue/Zero(SerialUSB)は、
  USB CDCシリアル接続が開いているかどうかを示します。
  他の全てのボード、及びUSB以外のCDCポートでは、これは常にtrueを返します。
   bool Returns:指定されたシリアルポートが使用可能な場合はtrueを返します
   例)
     SerialUSB.begin(9600) ;
     while(!SerialUSB) ; // USBポートが開くまで待つ、それ以外は常にtrueを返す

 void SerialUSB.end( )
  シリアル通信の終了を行います、再度シリアル通信を有効にしたい時は、
  SerialUSB.begin( )をコールして下さい。
  終了した場合はボードがリセットされないと新しいプログラムをアップロードする事が出来ません。

 ans = SerialUSB.available( )
  シリアルポートに何バイトのデータが到着しているかを返します、バッファは64byteまでです。
   int ans:シリアルバッファに有るデータのバイト数を返します

 ans = SerialUSB.availableForWrite( )
  シリアルバッファーに書き込む事ができるバイト数(文字)を取得します。
   int ans:シリアルバッファに書き込み可能なデータのバイト数を返します

 ans = SerialUSB.find(char *target)
 ans = SerialUSB.find(char *target, size_t length)
  "target"の文字列が見つかるまでシリアルバッファーからデータを読み取ります。(検索のみ)
   char *target:検索する文字列を指定します
   size_t length:検索する文字列の長さを指定します
   bool ans  :検索文字列が見つかった場合はtrue、タイムアウト(Default:1秒)した場合はfalse
   例)
     boolean ans = Serial.find("OK\r\n") ;

 ans = SerialUSB.findUntil(char *target,char *terminal)
  "target"の文字列が見つかるか,"terminal"の文字が見つかるまで読み取ります。(検索のみ)
   char *target :検索する文字列を指定します
   char *terminal:検索する終端文字列を指定します
   bool ans   :検索文字列が見つかった場合はtrue、タイムアウト(Default:1秒)した場合はfalse
   例)
     boolean ans = Serial.find("END","\r\n") ;

 ansString = SerialUSB.readString( )
  シリアルバッファーからStringクラスに文字を読み込みます。
  タイムアウト(Default:1秒)した場合は終了します。
   String ansString:String変数にシリアルバッファーから読み込まれた文字列
   例)
     String ansString = Serial.readString() ;

 ansString = SerialUSB.readStringUntil(char *terminal)
  シリアルバッファーから"terminal"の文字列が見つかるまでStringクラスに文字を読み込みます。
  終端文字列は読み捨てます、又、タイムアウト(Default:1秒)した場合は終了します。
   char *terminal :検索する終端文字列を指定します
   String ansString:String変数にシリアルバッファーから読み込まれた文字列
   例)
     String ansString = Serial.readStringUntil("\r\n") ;

 ans = SerialUSB.parseInt( )
 ans = SerialUSB.parseInt(lookahead)
 ans = SerialUSB.parseInt(lookahead, char ignore)
  シリアルバッファー内の数字文字列を整数に変換します。
  シリアルバッファー内で最初に出会えた数字文字からが変換開始で、数字以外が読み取られた場合、
  解析はそこまでの値で変換されます。
  又、タイムアウトで文字が読み取られなかった場合、0が返されます。
  例)"START1234END"の文字列を受信した場合なら"1234"が変換され、
    "START"は読み捨てられます、"END"はシリアルバッファー内に残ります。
   LookaheadMode lookahead:
    SKIP_ALL  整数のストリームをスキャンする時、数字又はマイナス記号以外の全ての文字
           無視されます、これがデフォルトのモードです。
    SKIP_NONE 最初の受信文字が有効でない限り何もスキップされず読み出されません。            "123mA"は"123"のみ読み出され有効ですが、
           "DC123mA"なら無効で読出されずシリアルバッファー内に残り、0が返されます
    SKIP_WHITESPACE タブ、スペース、及び改行のみがスキップされます。                "DC123mA"なら無効で読出されずシリアルバッファー内に残り、
               0が返されます。
   char ignore:指定された文字を検索でスキップ(有効文字内)する為に使用されます
                   例)
                      ans = Serial.parseInt(SKIP_WHITESPACE,'*') ;
                      と指定した場合、受信データが"5*9**6"であれば、"596"が変換される
                      因みに、"*596"は無効、最初の受信文字が有効でない限りなのでぇ

 ans = SerialUSB.parseFloat( )
 ans = SerialUSB.parseFloat(lookahead)
 ans = SerialUSB.parseFloat(lookahead, char ignore)
  シリアルバッファー内の数字文字列を浮動小数点数に変換します。
  ルールはSerialUSB.parseInt()と同じですが、有効文字に小数点が加わります。
  戻り値は勿論 float型ですね。

  parseFloat/parseInt 共に無効時は"0"が返るがぁ、"0(ゼロ)"を有効数字にしたい場合は
   区別がつかない如何したもんだろうか?

 void SerialUSB.setTimeout(long time)
  シリアルデータを待機する最大ミリ秒を設定します。 デフォルトは1000ミリ秒です。
   long time:ミリ秒単位のタイムアウト期間を指定します
   例)
     boolean ans = Serial.find("END","\r\n") ;

 SerialUSB.accept( )
  データを受信するまで待ちます、データはSerialUSB.read( )で取り出します。
   bool Returns:Clientオブジェクト
          読み取り可能なデータがクライアントにない場合、
          このオブジェクトは ifステートメントでfalseと評価されます。(EthernetClient)

 ans = SerialUSB.peek( )
  受信データを1バイト読み込みますが、バッファ中の読み取り位置は変更しません。
  つまり、peek()は同じ文字を繰り返し読み取ります。
   int ans:読込み可能なデータの最初の1バイトを返します、-1の場合は、データが存在しません

 ans = SerialUSB.read( )
  受信データを読み込みます。
   int ans:読み込み可能なデータの最初の1バイトを返します、-1の場合は、データが存在しません

 ans = SerialUSB.readBytes(char *buffer, size_t count)
  指定した数(count)の分だけ受信データを読み込むまで待ちますが、1秒でタイムアウトです。
   uint8_t *buffer :受信したデータを格納する場所を指定します
   size_t count  :受信するデータのバイト数を指定します
   size_t ans    :実際に受信したバイト数を返します

 void SerialUSB.flush( )
  送信シリアルデータの送信が完了するのを待ちます。
  (Arduino 1.0より前のバージョンでは、バッファーされた着信シリアルデータが削除されました。)


 ans = SerialUSB.write(uint8_t c)
 ans = SerialUSB.write(const uint8_t *buffer, size_t size)
  シリアルポートにバイナリデータを出力します。
  1バイトずつ、あるいは複数バイトの送信が可能です。
   uint8_t c    :送信する1バイトのデータを指定します
   uint8_t *buffer:送信するデータを格納した場所を指定します
   size_t size   :送信するデータのバイト数を指定します
   size_t ans   :実際に送信したバイト数を返します

 ans = SerialUSB.print( )
 ans = SerialUSB.println( )
  データの送信ですが、使い方は、Serial.print( )と同じです。
  byte ans:送信したバイト数を返します

 void serialEvent( )
  データが利用可能になった時に呼び出されます。
  新しいデータがハードウェアシリアルRXに着信する度々に発生します。
  このルーチンはloop()が実行される度々に実行される為、ループ内で遅延を使用すると応答が遅延する
  可能性があります。
  String inputString = "";       // 入力データを保持する文字列
  bool stringComplete = false;   // 文字列が読み取り完了かどうか

  void serialEvent() {
    while (Serial.available()) {
      // 新しいバイトを取得します。
      char inChar = (char)Serial.read();
      // それをinputStringに追加します。
      inputString += inChar;
      // 着信文字が改行の場合は、メインループがそれについて何かできるようにフラグを設定します。
      if (inChar == '\n') {
           stringComplete = true;
      }
    }
  }
  ※ serialEvent()は、Leonardo、Micro、又はYunでは機能しません。
  ※ serialEvent()、及びserialEvent1()は、Arduino SAMDボードでは機能しません。
  ※ serialEvent()、及びserialEvent1/2/3()は、Arduino Dueでは機能しません。

以下の記事は動作させられなかったので記事は中断したままです。m(_ _)m

《キーボード(HID)》

詳しくは、本家の"Mouse and Keyboard libraries"リファレンスマニュアルを参照しましょう。

@ XIAOの"Seeeduino XIAO"のピンD4とスイッチを配線(プルダウンで配線)します。

A "USB port"とPCをUSB Type-Cコネクターケーブルで繋ぎます。

B ArduinoIDEを起動させ、ボードとポート設定を"Seeeduino XIAO"に設定します。

C IDEのメニューバーから[ファイル]→[スケッチ例]→[09.USB]→[Keybord]→[KeyboardMessage]を
  順番にクリックします。

D スケッチをコンパイルして書き込みます。

E IDEのシリアルモニタを起動させます。
---------------------------------------------------------------------
const int buttonPin = 2 ;         // input pin for pushbutton
int previousButtonState = HIGH ;  // for checking the state of a pushButton
int counter = 0;                  // button push counter

void setup()
{
     // キーボードスイッチの代わり
     pinMode(buttonPin, INPUT) ;
     // USBでHIDクラスのキーボードで初期化を行う
     Keyboard.begin() ;
}
void loop()
{
     int buttonState ;

     // read the pushbutton:
     buttonState = digitalRead(buttonPin);
     // if the button state has changed, and it's currently pressed:
     if ((buttonState != previousButtonState) && (buttonState == HIGH))
     {
          // increment the button counter
          counter++;
          // type out a message
          Keyboard.print("You pressed the button ");
          Keyboard.print(counter);
		Keyboard.println(" times.");
	}
	// save the current button state for comparison next time:
	previousButtonState = buttonState;
}
---------------------------------------------------------------------
C スケッチをコンパイルして書き込みます。

《マウス(HID)》




"Serial"関数を追加(*1) 2020/05/15


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.