Arduino Microを使って、センサーと「なんちゃって」デバイス連携するWebアプリをまた作ろう

# Arduino Microを使って、センサーと「なんちゃって」デバイス連携するWebアプリをまた作ろう

![アホなデモ](http://img.dfm.lrv.jp/keyserial/sample.png)

[Arduino Microを使って、センサーと「なんちゃって」デバイス連携するWebアプリを作ろう](http://qiita.com/tadfmac/items/cb1c8b6d96ccec7c7178)の続きです。

前回は、Arduino Microをセンサー情報をもとにキーコマンドを送り続けるデバイスにして、Webアプリを反応させる、というものを作ってみました。

今回も、Arduino Microをセンサー情報をもとにキーコマンドを送り続けるデバイスにして、Webアプリを反応させる、というものを作ってみました。

> いっしょじゃん！！！！

## 今回は、ヘンテコなライブラリを使って「なんちゃって」をパワーアップ！！！

まぁ、パワーアップしたところで「なんちゃって」であることに変わりはないんですが。。

- ライブラリを作ったから、たぶんちょっとだけ作りやすくなったはず！
- 数字とかもとりやすくなった！
- デバイス側からポーリングして、Webアプリ側で接続状態が確認できるように！

と、地味に良くなったと思います。ね！？

## キーシリアルコマンドレシーバ？ というものを作った。

つくったのはコレ↓

[keyserial](https://github.com/tadfmac/keyserial)

まったく、WebRTCとか言ってる時代にキーボードで通信ですよ。アホみたいw
テストするとき、普通にパソコンのキーボードでやりましたよ。えぇw

### センサーの値とか送りたいときにつかう。

で、これ使うと何ができるかというと、
1送って、0送って、3送ると「103」みたいなのが簡単に作れます。

。。。。えっと、主にそれだけなんですが。。。。なんか面倒ですよね？
そこを作るの。。。

というわけで無理矢理進めてますが、サンプルを作ってみたので、紹介させてください。

### Webアプリのコード

[サンプル](http://dfm.lrv.jp/test/sensortest2/)

もう、みなさんどうでも良くなってきた頃合いだと思いますので、興味のある方だけ上記URLかgithubでコード見て頂くとして、概要は↓な感じ。

```js
var keySerial = new keyserial({polling:true});
// デバイス側がポーリングに対応してるときだけ polling:trueを指定する。

keySerial.onValue = function(val){
	// 数値が送られてきた時の処理
};

keySerial.onKey = function(keyCode){
	// 単発のキーコマンドを受け取ったときの処理
}

keySerial.onConnect = function(){
	// デバイスがつながったときの処理
};

keySerial.onDisconnect = function(){
	// デバイスとの接続が切れたときの処理
};

keySerial.start();	// 開始!
```

簡単ですね！

### デバイス

デバイス側は、Arduino Microで作ると簡単です。Leonardoでもいいです。

![回路](http://img.dfm.lrv.jp/keyserial/schematic.png)

基本は前回からあまり変わり映えしていません。CdSで明るい！暗い！を送るところも一緒w
ただし、今回は、下記のようにしてみました。
- デバイス側からポーリング（改行を定期的に送信）する処理追加
- いきなりポーリング始めると、いろんな意味でヤバイデバイスなので、スイッチでポーリングのON/OFFできるように。
- せっかく数値が送れるようになったので、変化検知時にだけ一緒に送るように。

```cpp:cdssensor.ino
#include <Serial.h>
#define BUTTON 3
#define CDS 3
#define LED 5

boolean nowstate = false;
int button = LOW;
int cnt = 10;
boolean isPolling = false;
boolean isSendBoolWaiting = false;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
  Keyboard.begin();
}

void loop() {
  boolean state = false;
  int cdsvalue = analogRead(CDS);  
  cdsvalue >>= 5;
  if (cdsvalue < 16) {
    state = false;
  }else{
    state = true;
  }
  if(nowstate != state){
    sendBool(state);
    cnt = 10;
    sendValue(cdsvalue);
    Serial.println(cdsvalue);
  }
  nowstate = state; 
  
  //  Polling on/off
  int nowbutton = digitalRead(BUTTON);
  if((nowbutton == HIGH)&&(nowbutton != button)){
    isPolling ^= 0x01;
    if(isPolling == true){
      isSendBoolWaiting = true;
      digitalWrite(LED,HIGH);
    }else{
      isSendBoolWaiting = false;
      digitalWrite(LED,LOW);
    }
  }
  button = nowbutton;
  if(isPolling){
    cnt --;
    if(cnt == 0){
      cnt = 10;
      Keyboard.write(KEY_RETURN);
      if(isSendBoolWaiting == true){
        sendBool(state);
        sendValue(cdsvalue);
        isSendBoolWaiting = false;
      }
    }
  }

  delay(100);
}

void sendBool(boolean state){
  if(state == true){
    Keyboard.write('d');
  }else{
    Keyboard.write('l');
  }
}

void sendValue(int value){
  int cnt;
  int digits[5] = {0,0,0,0,0};
  int tmp;
  int digit;
  
  digits[0] = value / 10000;
  tmp = value % 10000;
  digits[1] = tmp / 1000;
  tmp = tmp % 1000;
  digits[2] = tmp / 100;
  tmp = tmp % 100;
  digits[3] = tmp / 10;
  tmp = tmp % 10;
  digits[4] = tmp;
  
  Keyboard.write(',');

  for(cnt=0;cnt<5;cnt++){
    digit = digits[cnt];
    if((digit!=0)||(cnt==4)){
      Keyboard.write(digit+48);
    }
  }
  Keyboard.write(KEY_RETURN);  
}
```

こんな感じです。
センサーの値も送れるようになったので、ようやくセンサーっぽくw

### まとめ

なんちゃってデバイス連携は楽しい！！
なんてったって、C言語（C++?）とjavascript、どっちも書けるんですよ！？

> もう、大混乱！w

というわけで、いろんなご指摘お待ちしてます！！