# WirelessUART

WirelessUARTはシリアル通信を行います。

{% hint style="success" %}
このアクトの解説の前に[BRD\_APPTWELITEの解説](https://mwx.twelite.info/v0.1.7/act_samples/brd_apptwelite)をご覧ください。
{% endhint %}

## アクトの機能

* ２台のUART接続のTWELITE同士をアスキー書式で通信する。

## アクトの使い方

### 必要なTWELITE

いずれかを２台。

* [MONOSTICK BLUE または RED](https://mono-wireless.com/jp/products/MoNoStick/index.html)
* [TWELITE R](https://mono-wireless.com/jp/products/TWE-LITE-R/index.html) でUART接続されている[TWELITE DIP](https://mono-wireless.com/jp/products/TWE-Lite-DIP/index.html)など

## アクトの解説

### setup()

```cpp
void setup() {
	/*** SETUP section */
	// the twelite main class
	the_twelite
		<< TWENET::appid(APP_ID)    // set application ID (identify network group)
		<< TWENET::channel(CHANNEL) // set channel (pysical channel)
		<< TWENET::rx_when_idle();  // open receive circuit (if not set, it can't listen packts from others)

	// Register Network
	auto&& nwk = the_twelite.network.use<NWK_SIMPLE>();
	
	uid = random(1, 5); // set uid by random() (1..4)
	nwk	<< NWK_SIMPLE::logical_id(uid); // set Logical ID. (0xFE means a child device with no ID)

	/*** BEGIN section */
	SerialParser.begin(PARSER::ASCII, 128); // Initialize the serial parser
	the_twelite.begin(); // start twelite!

	/*** INIT message */
	Serial << "--- WirelessUart (id=" << int(uid) << ") ---" << mwx::crlf;
}
```

論理IDは`random(1,5)`により1,2,3,4のいずれかの値に割り当てています。通常は、論理IDを設定保存したデータ、またはDIP SWといったハードウェアの情報から生成します。

```cpp
SerialParser.begin(PARSER::ASCII, 128); 
```

[シリアルパーサー](https://mwx.twelite.info/v0.1.7/api-reference/predefined_objs/serialparser)を初期化します。

### loop()

```cpp
while(Serial.available())  {
	if (SerialParser.parse(Serial.read())) {
		Serial << ".." << SerialParser;
		const uint8_t* b = SerialParser.get_buf().begin();
		uint8_t addr = *b; ++b; // the first byte is destination address.
		transmit(addr, b, SerialParser.get_buf().end());
	}
}
```

シリアルからのデータ入力があった時点で、シリアルパーサーに１バイト入力します。アスキー形式が最後まで受け付けられた時点で`SerialParser.parse()`は`true`を戻します。

`SerialParser`は内部バッファに対して`smplbuf`でアクセスできます。上の例ではバッファの１バイト目を送信先のアドレスとして取り出し、２バイト目から末尾までを`transmit()`関数に渡します。

パケットを受信したときには、送信元を先頭バイトにし続くペイロードを格納したバッファ`smplbuf_u8<128> buf`を生成し、出力用のシリアルパーサー`serparser_attach pout`からシリアルに出力しています。

```cpp
if (the_twelite.receiver.available()) {
	auto&& rx = the_twelite.receiver.read();
	
	// check the packet header.
	const uint8_t* p = rx.get_payload().begin();
	if (rx.get_length() > 4 && !strncmp((const char*)p, (const char*)FOURCHARS, 4)) {
		Serial << format("..rx from %08x/%d", rx.get_addr_src_long(), rx.get_addr_src_lid()) << mwx::crlf;

		smplbuf_u8<128> buf;
		mwx::pack_bytes(buf			
				, uint8_t(rx.get_addr_src_lid())            // src addr (LID)
				, make_pair(p+4, rx.get_payload().end()) );	// data body

		serparser_attach pout;
		pout.begin(PARSER::ASCII, buf.begin(), buf.size(), buf.size());
		Serial << pout;
	}
}
```

## テスト用のコマンド

{% hint style="warning" %}
テストデータは必ず**ペースト機能**を用いてターミナルに入力してください。入力にはタイムアウトがあるためです。

参考： TWE ProgrammerやTeraTermでのペーストはAlt+Vを用います。
{% endhint %}

{% hint style="info" %}
入力の末尾にCR LFが必要です。

最初はCR LFが省略できるXで終わる系列を試してください。終端文字列が入力されない場合は、その系列は無視されます。
{% endhint %}

### 例

```
:FE00112233X

:FE001122339C

```

任意の子機宛に`00112233`を送付します。

### 例

```
:03AABBCC00112233X

:03AABBCC0011223366

```

子機３番に対して`AABBCC00112233`を送付します。

{% hint style="info" %}
TWE Programmerのターミナル機能を用いて送付する場合は、Alt+Vキーを用いてペーストします。
{% endhint %}
