Arduino Yun使い方

# Hardware
Arduino Yunは無線LANモジュールを組み込んだArduino
無線LANモジュールにはLinuxが搭載されている
![image](https://qiita-image-store.s3.amazonaws.com/0/95321/eabbf70a-58e2-5ebd-0d82-5d257e34bffa.png)

基本的には他のArduino同様Micro USBでPCと接続すれば電源供給、スケッチの書き込み、シリアルモニタができる。

# Getting Started
## 無線LANの設定
- Micro USBでPCと接続
- しばらくするとWifiのSSID "Arduino Yun-XXXXX..."が見えるので選択
- 繋いだら "http://arduino.local/" にアクセス
- Passwordに"arduino"
- "CONFIGURE"を押すと、無線LANの設定画面にいくので、そこから繋ぎたい無線LANのSSIDを選択、パスを入力して”configure & restart”
- Arduinoに設定したものと同じネットワークにPCを繋ぎなおし、再度 "http://arduino.local/" にアクセス。きちんとつながれば設定終了。

## Arduino.local にアクセスできない(DNSエラーになる)場合
そもそもなぜArduino YunのipアドレスではなくArduino.localでアクセスできるのか？（DNSの設定なんてしていないはず）
Arduino Yunは、Bonjour(mDNS)という仕組みを使っており、YunそのものがDNSサーバーとして機能している。
この仕組みを導入することによってArduino Yunのipを固定する手間や、Yunを別の場所に持っていきipを再設定する必要がなくなる。

本題に戻すと、DNSエラーになる場合下記2点を確認するとよい。

- BonjourがPC上で動いているか？(Macは標準でインストールされているが、Windowsは入っていない。)
- Port: 5353が開いているか？

[参考: ArduinoYun公式ページより](https://www.arduino.cc/en/Guide/ArduinoYun)

```
NB: The Yún uses Bonjour services for auto-discovery on a wireless network.
This service is not included with Windows by default.
If you do not have Bonjour already installed, you can download the service from here.
Additionally, you should make sure any anti-virus software is not blocking communication on port 5353.
```


## 無線LAN経由でGPIOを操作してみる
- Sketchの例の中に”Bridge→Bridge”があるので、このサンプルを書き込む
- 書き込み終わったら、"http://arduino.local/digital/13/1" でアクセスする。そのときのユーザー名は"root"パスは"arduino"
![image](https://qiita-image-store.s3.amazonaws.com/0/95321/577b0702-ecc8-9b58-6d82-ac61cb8ef6cc.png)
<br>
<br>

- これでL13のLEDが点灯する。逆に消す場合は、"http://arduino.local/digital/13/0"
![image](https://qiita-image-store.s3.amazonaws.com/0/95321/a18b53f3-4eb6-6835-82ef-7939a4f9953b.png)

- [その他の操作方法についてはこちら](http://www.arduino.cc/en/Tutorial/Bridge)

## Arduino Yunの無線モジュール（Linux部）にアクセス
- Arduino Yunの無線モジュールは組込みLinuxで構成されているためSSHアクセスと設定が可能。
- Teratermなどで "arduino.local" にSSH接続、ユーザー名は"root"、パスは"arduino"
<img src=https://qiita-image-store.s3.amazonaws.com/0/95321/fca8db05-e585-1905-834e-ef977a564428.png width=400>
<br>
<br>

- 成功するとこんな感じ
<img src=https://qiita-image-store.s3.amazonaws.com/0/95321/0cfd7439-61e0-cfe8-0518-3df1d35553da.png width=600>

# Yunから外のサーバーにHTTPでアクセス
## HTTP GETの場合
[Yun用にHTTPのライブラリ](https://www.arduino.cc/en/Reference/YunHttpClientConstructor)があるのでそれを使うのが楽

ファイル
→スケッチの例
→Bridge→HttpClient　の例をすこしいじればよい

このスケッチは ”http://www.arduino.cc/asciilogo.txt” というURLに対してHTTP GETを行い、返ってきた値をSerial出力しているだけ。それを5秒おきに繰り返す。
なので、この "http://..." の部分を所望のURLに書き換えるだけ。
今回はHTTP GETのスケッチなのでパラメータがあれば "http://...?\<para1>=\<value1>&\<para2>=\<value2>" のように単純にURLにつなげていけばOK。

```cpp:sample
#include <Bridge.h>
#include <HttpClient.h>

void setup() {
  // Bridge takes about two seconds to start up
  // it can be helpful to use the on-board LED
  // as an indicator for when it has initialized
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Bridge.begin();
  digitalWrite(13, HIGH);

  Serial.begin(9600);

  while (!Serial); // wait for a serial connection
}

void loop() {
  // Initialize the client library
  HttpClient client;

  // Make a HTTP request:
  client.get("http://www.arduino.cc/asciilogo.txt");

  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  Serial.flush();

  delay(5000);
}
```
## HTTP POSTの場合
[このページ](https://www.arduino.cc/en/Reference/YunHttpClientConstructor)のHttpClientクラスを見ていただくと分かるが、なぜかget()しか用意されていないので、Bridgeライブラリのprocessクラスを使う。
やっていることは、WifiモジュールのLinuxで直接curlを叩いているというだけ。
なので、叩きたいコマンドを文字列(変数s)にして、process.runShellCommand(s)するだけ。

```cpp:sample
#include <Bridge.h>
Process process; 
void setup() {
    Bridge.begin();
}
​
void loop() {
    String s = "<ここにcurlコマンド>";
    process.runShellCommand(s);
}
```

## 余談：HttpClientの中身
get()は実装されていて、post()はないはずがない！と思いHttpClientの中身をのぞいてみることにした。
Windowsの場合は以下のフォルダにBridgeライブリの中身がおいてある。
"C:\Program Files (x86)\Arduino\libraries\Bridge\src"フォルダのHttpClinet.cppが本体。
下記の通りきちんとpost()は実装されている。
なぜ隠してあるのかは不明。

```cpp:HttpClient.cpp
//一部抜粋
unsigned int HttpClient::post(const char *url, const char *data) {
  begin("curl");
  if (insecure) {
    addParameter("-k");
  }
  addParameter("--request");
  addParameter("POST");
  addParameter("--data");
  addParameter(data);
  addHeader();
  addParameter(url);
  return run();
}
```

## 余談：エラーログを収集する
process.runShellCommand()を使用していた際に情報がサーバーに上がっていないときがあったため、curlが成功しているかどうかのログを取りたくなった。
取った方法としては、curlの標準エラー出力をリダイレクトしてファイルに保存する方法。
標準出力は標準エラー出力とは別なので、"curl http://hogehoge >>error.log"では補足できない点に注意。"curl http://hogehoge 2>>error.log"とする。
これはLinuxのコマンドなので当然Wifi module(Linux)側に保存される。
あとは、上記のように手元のPCからSSH接続でWifiモジュールにアクセスすれば、エラーログ(サンプルではerror.logというファイル)が確認できる。

```cpp:errorを保存
#include <Bridge.h>
Process process; 
void setup() {
    Bridge.begin();
}
​
void loop() {
    String s = "<ここにcurlコマンド> 2>>error.log";
    process.runShellCommand(s);
}
```


#参考
[Arduino Yúnを使ってみよう (1) Yúnを設定する](http://mag.switch-science.com/2015/03/06/try-arduino-yun-1/)
[Arduino Yúnを使ってみよう (2) YúnをPCから操作する](http://mag.switch-science.com/2015/03/10/try-arduino-yun-2/)
[Arduino YUNを使ってみる（4）](http://www.eleki-jack.com/FC/2015/10/arduino-yun4.html)