プロトタイピング向けマイコンボード「Wio シリーズ」の UART ポート(シリアルポート)の操作方法

プロトタイピング向けマイコンボード Wio シリーズにはシリアルデータをやり取りすることができる UART ポートがついています。これで RS-232C 等のI/Fを持っている機器との通信も可能でしょう。

ちなみに検証は [M5Stack Basic と UART 通信](https://qiita.com/ma2shita/items/37d403fb7a79814d4d4c)して確認しました。

## Wio シリーズ

MCU + LTE/3G モデムが一体化されたボードです。現在3種類あります。

* [Wio LTE JP Version](https://soracom.jp/products/module/wio_lte/)
    * Arm Cortex-M4 + LTE Cat.1 モデム + スロット型 SIM (NTT DOCOMO 系)
* [Wio 3G SORACOM Edition](https://soracom.jp/products/module/wio_3g_soracom_edition/)
    * Arm Cortex-M4 + 3G モデム + チップ型 SIM (SORACOM)
* [Wio LTE M1/NB1(BG96)]()
    * Arm Cortex-M4 + LTE-M モデム + スロット型 SIM (KDDI LTE-M)

## Wio シリーズの UART ポート操作

Grove UART ポートはモデルによって定義名が異なりますが、操作は同じとなります。

| モデル | UART 名 |
|-------|---------------|
| Wio LTE JP Version | `Serial` |
| Wio 3G SORACOM Edition および Wio LTE M1/NB1(BG96) | `SerialUART` |

`#define GroveUARTPort hogehoge` としておけば、後方のコードは共通化できるので便利でしょう。
(ちなみに Wio LTE のシリアルモニタは  `CONSOLE` としています。(ややこしいから))

#### Wio LTE JP Version 用

```c++:UARTread_for_WioLTE.ino
#include <WioLTEforArduino.h>
WioLTE Wio;
#define GroveUARTPort Serial
#define CONSOLE SerialUSB

void setup() {
  Wio.Init();
  Wio.PowerSupplyGrove(true);
  CONSOLE.begin(115200);
  GroveUARTPort.begin(57600);
  delay(5000);
  CONSOLE.println("-- HELLO (baud rate = 57600)");
}

void loop() {
  while (GroveUARTPort.available()) {
    String recv_str = GroveUARTPort.readStringUntil('\n');
    CONSOLE.print("Recv: ");
    CONSOLE.println(recv_str);
  }
  /* Send using `GroveAPort.println("foobar");` */
}
```

#### Wio 3G SORACOM Edition および Wio LTE M1/NB1(BG96) 用

```c++:UARTread_for_Wio3G.ino
#include <WioCellLibforArduino.h>
WioCellular Wio;
#define GroveUARTPort SerialUART
#define CONSOLE SerialUSB

void setup() {
  Wio.Init();
  Wio.PowerSupplyGrove(true);
  CONSOLE.begin(115200);
  GroveUARTPort.begin(57600);
  delay(5000);
  CONSOLE.println("-- HELLO (baud rate = 57600)");
}

void loop() {
  while (GroveUARTPort.available()) {
    String recv_str = GroveUARTPort.readStringUntil('\n');
    CONSOLE.print("Recv: ");
    CONSOLE.println(recv_str);
  }
  /* Send using `GroveAPort.println("foobar");` */
}
```

異なるのは冒頭3行分のみですね。
コードは Read のみとなっていますが `println()` や `write()` を遣えば送信ももちろん可能です。

### `String` から `char` へのキャスト(変換)は？

https://code.i-harness.com/ja/q/70aa36 あたりを見てやってください。

### Grove-D38 も HardwareSerial として利用可能です。

UART だけでなく D38 も HardwareSerial として使うことができます。
詳しくは [[Wio LTE Cat.1] Grove-D38でシリアル通信](https://qiita.com/matsujirushi/items/4c19cd5b73705ebe2b18) をご覧ください。

※ Wio LTE JP Version 用となっていますが、Wio 3G SORACOM Edition および Wio LTE M1/NB1(BG96) 用でもできるようです（未検証）

### ハードウェア的な話

Wio シリーズの動作電圧は 3.3V です。
そのため RS-232C との入出力は [電圧レベル変換](http://akizukidenshi.com/catalog/g/gK-06464/) を入れるようにしましょう。

## (過去の情報) Wio 3G SORACOM Edition, Wio LTE M1/NB1(BG96) での UART ポート操作

**この情報は Obsolete です。**

Wio 3G SORACOM Edition および Wio LTE M1/NB1(BG96) の `SerialUART` では `readBytesUntil()` などの Stream 由来のメソッドが使えなかったので `read()` を駆使する必要がありましたが、**最近使えるようになったので、この情報は不要となりました。**
歴史として残しておきます。

```c++:UARTread.ino
#include <WioCellLibforArduino.h>
WioCellular Wio;

#define BUFFER_SIZE 128
char UART_buf[BUFFER_SIZE];
int UART_buf_len = 0;
const char* UART_Reader(HardwareSerial* serial, char terminator = '\n') {
  while (serial->available()) {
    char data = serial->read();
    if (data == terminator) {
      UART_buf[UART_buf_len] = '\0';
      UART_buf_len = 0;
      return UART_buf;
    }
    
    if (UART_buf_len > (int)sizeof(UART_buf) - 1) { // Overflow
      UART_buf_len = 0;
      return NULL;
    }
    UART_buf[UART_buf_len++] = data;
  }
  return NULL;
}

void setup() {
  delay(200);
  SerialUSB.begin(115200);
  SerialUSB.println("");
  SerialUSB.println("--- START ---");
  Wio.Init();
  Wio.PowerSupplyGrove(true);
  delay(500);
  SerialUART.begin(9600); /* `SerialUART` = UART port */
}

void loop() {
  const char* data = UART_Reader(&SerialUART);
  if (data != NULL) {
    SerialUSB.println(data);
  }
}
```

## あとがき

ひび更新されてますね。

EoT