Image

Fabbotかんなちゃんのハック方法

2016/09/12 17:34:00
先日、コワーキングスペースHaLakeにて行われました「FabBotかんなちゃんで遊ぼう!IoT勉強会」で、半日かけてFabbotかんちゃんをハックしてみましたのでその方法を簡単にまとめてみます。




もともとついていないセンサーをArduinoに取り付けた場合、Raspberry Piと繋がるPCからどのようにセンサー情報を取得できるかという方法を試しましたが、センサー以外にもカスタマイズの参考になるかと思います。


  1. Arduinoへのセンサー取り付け
  2. ArduinoからRaspberry Piへのセンサーデータ送信
  3. Raspberry Piのサーバ対応
  4. Raspberry Piと繋がるPCからのArduinoのセンサーデータ取得
という手順で進めます。

Arduinoへのセンサー取り付け

今回使用しましたのは圧力センサーで、適当に空いていたGPIO8番ピンを利用し、10kΩの抵抗をGNDと繋ぎましたが、この辺はよくある取り付けですので省略します。
この時点で正しくセンサーの値が取れるかをArduino IDEで確認しています。


void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT);
}

void loop() {
  Serial.println(analogRead(8));
}

(後で気付きましたが、analogRead関数を使っており、圧力センサーですのでアナログピンに刺すところでしたが、上記のコードのまま試し、圧力センサーに触れていない時は0で、触れた場合に高い数値が返ってきていましたので気づきませんでした。)

ArduinoからRaspberry Piへのセンサーデータ送信

FabbotかんちゃんのArduino部分にかかれていたのはもともとこちらのコードでした。


このコードに8番ピンの値を返すコマンドを追加すれば、Arduino部分のセンサー取得はできるようになります。
プログラムの後半にあるswitch文に対して、今回の場合"@"の場合を追記しています。


      case '@':
          pinMode(8, INPUT);
          Serial.println(analogRead(8));
          break;

真面目にやれば、特定のポートのピンの値を読みだす、あるいは出力にあたるdigitalWriteにも対応するようにすると汎用的ですし、別の設計方法としてはこちらのFirmataを予め書き込んでおくとRaspberry Piだけのコードで済むのかもとは思っています。

書き込んだらArduino IDEのシリアル通信で"@"を送信し、実際の値が帰ってくるかをチェックしました。(このときのボーレートは9600bpsです。)

Raspberry Piのサーバ対応

かんなちゃんはPC側からのScractchで操作できるようになっていますが、どのような仕組みを探るためRaspberry Piにログインして見ますと、ScratchServer1.0.rbというファイルが/home/piにあり、これが起動時にサーバとして動いていることが分かります。
JSONを受け付け、そのデータの中のactionというキーをコマンド名としてかんなちゃんをウィンクさせたり、首を動かしたりする仕組みになっていました。

さきほどのArduinoの方で"@"をセンサー値取得のために割り当てましたから、逆にこのサーバが"@"をArduinoに送るコマンドを追加してあげれば良いです。
具体的には、ScratchServer1.0.rbのRubyのcaseに以下を追記しました。

        when 'sensor' then
          puts sp.write('@')
          sleep(0.01)
          ret = sp.gets
          sock.write(ret)
          sleep(0.01)

ファイル編集後はこのプロセスを終了するなり、Raspberry Piを再起動させてください。

Raspberry Piと繋がるPCからのArduinoのセンサーデータ取得

サーバ部分が対応できたら、あとはPC上から直接以下のコードでデータを取得できました。取得だけではなく、特定の値より圧力センサーが強いと音声ファイルを再生するようになっています。(ただしPC上から)

# coding: utf-8
require 'socket'

socket = TCPSocket.open("192.168.1.10", 51234)
loop do
  socket.write "{\"action\":\"sensor\"}\r\n"
  socket.flush
  begin
    sensor = socket.gets.to_i
    puts sensor
    if sensor > 100
      socket.write "{\"action\":\"eye\", \"arg\":255}\r\n"
      `afplay hogehoge.m4a`
    else
      socket.write "{\"action\":\"eye\", \"arg\":0}\r\n"
    end
  socket.flush
  rescue
    nil
  end
end
socket.close

試せていませんが、かんなちゃんの動くRaspberry Pi上でもIPアドレスを変えれば動きますから、起動時に実行するようにすればかんなちゃん以外に外部のPCを必要としなくなりますね。