Technical Information/etc.

Edit  

Seeeduino XIAO のSerialの増設方法

2020/12/21

XIAOのUARTペリフェラルは公式ではSerial (USB) 、Serial1 (6,7pin) の2つしかありませんが、CPUのデータシートをみるとI2C、SPIの2箇所に増設できそうなので、検討してみました。

WSB000008.JPG
WSB000557.PNG

 
Edit  

方針

  • 既存の公式ライブラリを流用する

 
Edit  

調査内容

  • XIAOで使用しているマイコン ATSAMD21G18 のデータシートより各ピンへ割り当てられるペリフェラルを調査すると、4pin, 5pin,9pin,10pinにシリアルペリフェラルが割り当てられそうです。

    SAMD215_Port.png

    WSB000562.PNG

 
Edit  

ライブラリ変更内容

  • C:\Users\Username\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.7.8\variants\XIAO_m0\variant.cpp *1の67行目(Uart Serial1のあと)に、下記内容を追加:
    Uart Serial2( &sercom2, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ) ;
    Uart Serial3( &sercom0, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX ) ;
  • 同じファイルの最後に、下記内容を追加:
    void SERCOM2_Handler()
    {
      Serial2.IrqHandler();
    }
    void SERCOM0_Handler()
    {
      Serial3.IrqHandler();
    }
  • C:\Users\Username\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.7.8\variants\XIAO_m0\variant.h の172行目(// Serial1 の一連の記述のあとで、#endif // __cplusplus の前) に、下記内容を追加:
    // Serial2
    extern Uart Serial2;
    #define PIN_SERIAL2_TX       (4ul)
    #define PIN_SERIAL2_RX       (5ul)
    #define PAD_SERIAL2_TX       (UART_TX_PAD_0)
    #define PAD_SERIAL2_RX       (SERCOM_RX_PAD_1)
    // Serial3
    extern Uart Serial3;
    #define PIN_SERIAL3_TX       (10ul)
    #define PIN_SERIAL3_RX       (9ul)
    #define PAD_SERIAL3_TX       (UART_TX_PAD_2)
    #define PAD_SERIAL3_RX       (SERCOM_RX_PAD_1)


    以上の変更で、XIAOで Serial2 と Serial3 が使えるようになります。

    Serial2 TX4 pin
    Serial2 RX5 pin
    Serial3 TX10 pin
    Serial3 RX9 pin

 
Edit  

使用方法

  • Serial2, Serial3 の使い方は、Serial1と同じです。

 
Edit  

動作確認

  • 下記の配線でSerial1~Serial3のすべてのTX/RX端子の動作確認を行いました。
XIAO_Serial23.PNG
  • サンプルコードは以下のとおりです。外部配線は上の図の通りとします。
    //
    // Serial2, Serial3 機能追加 動作確認
    //
    // 接続 および USBシリアルへの表示(1秒毎)
    // 開始表示                          "Start"
    // Serial1-Tx (6) - Serial2-Rx (5)  "Send 1->2"
    // Serial2-Tx (4) - Serial3-Rx (9)  "Send 1->2->3"
    // Serial3-Tx (10)- Serial1-Rx (7)  "Send 1->2->3->1"
    // -> Serial0-Tx 結果表示            "send 1->2->3->1->0"
    
    
    #include <TimerTC3.h>
    int sendflag = 0;
    
    void sendmsg(void){
      sendflag = 1;
    }
    
    void setup() {
        Serial.begin(115200);
        Serial1.begin(115200);
        Serial2.begin(115200);
        Serial3.begin(115200);
        delay(3000);
        while (!Serial);
        Serial.println("Serial ready.");
        while (!Serial1);
        Serial.println("Serial1 ready");
        while (!Serial2);
        Serial.println("Serial2 ready");
        while (!Serial3);
        Serial.println("Serial3 ready");
    
        TimerTc3.initialize(1000000);  // 1000,000us = 1s
        TimerTc3.attachInterrupt(sendmsg);
        TimerTc3.start();
    }
    
    void loop() {
      char rxchr;
      static char buff1[256];
      static char buff2[256];
      static char buff3[256];
      static int i1=0;
      static int i2=0;
      static int i3=0;
    
      if (sendflag==1){
        sendflag=0;
        Serial.println("Start");
        Serial1.println("send 1->2"); // 1->2
      }
      if (Serial2.available() > 0) {
        // データが受信されたら1バイト読み込む
        while( -1 == (rxchr = Serial2.read()) );
          buff2[i2++] = rxchr;
          if(rxchr == '\n'){
          buff2[i2-2]=0x00; //delete \r\n
          strcat(buff2,"->3\r\n");
          Serial2.print(buff2); // 2->3
          i2=0;
        }
      }
      delay(1);
      if (Serial3.available() > 0) {
        // データが受信されたら1バイト読み込む
        while( -1 == (rxchr = Serial3.read()) );
          buff3[i3++] = rxchr;
          if(rxchr == '\n'){
          buff3[i3-2]=0x00; // delete \r\n
          strcat(buff3,"->1\r\n");
          Serial3.print(buff3); // 3->1
          i3=0;
        }
      }
      delay(1);
      if (Serial1.available() > 0) {
        // データが受信されたら1バイト読み込む
        while( -1 == (rxchr = Serial1.read()) );
          buff1[i1++] = rxchr;
          if(rxchr == '\n'){
          buff1[i1-2]=0x00; // delete \r\n
          strcat(buff1,"->0\r\n");
          Serial.print(buff1); // 1->0(usb)
          i1=0;
        }
      }
      delay(1);
    }
 
Edit  

実行結果

  • 約1秒ごとに「send 1->2->3->1->0」がシリアルコンソールに表示されます。

    P1080936.JPG

    WSB000561.PNG


*1 1.7.8の部分はボード情報追加時のバージョンで、タイミングによっては変更される場合があります。また、WindowsでOneDriveを使っている方は \AppData\Local\Arduino15\ の部分が \OneDrive\ドキュメント\ArduinoData\ 等になる場合がありますので、適宜変更してください。

トップ   リロード   一覧 単語検索