2014年7月20日日曜日

Socket.IOとNode.js、Node-serialport、それにArduinoを加えてスマホから家電のスイッチを制御する(1)

こんにちわ。このシリーズではNode.jsとExpress、Socket.IO、Node-serialportを使ってブラウザからArduinoからのシリアル通信を受け取ったり、ブラウザからArduinoへ制御コマンドをシリアル通信で送信してArduinoをコントールしたりします。最後にはRaspberry Piに移植して書いたプログラムをデーモン化することで、常にプログラムを動かし続け、ブラウザからAC電源のONOFFを制御するシステムを構築します。
 この記事では、nodebrewを利用したNode.jsのインストールについて記述します。

こんなのを作ることができます。

Node.jsのインストール
 Homebrewというパッケージ管理ソフトを使用してNodebrewをインストールします。なおapt-getやMacportsでもいいはずなので、そこは読み替えてください。Nodebrewはnodeのバージョン管理ソフトです。これをつかってNodeをインストールします。
 Homebrewでのインストールコマンドは、
(sudo) brew update
(sudo) brew install nodebrew
となっています。
パスの設定が必要になるので、.bashrcや.zshrcに
export "PATH=$HOME/.nodebrew/current/bin:$PATH"
と書き足しておきます。どこでも大丈夫だと思います。先頭でも、末尾でも。
インストールが無事終了していれば、
nodebrew help
と端末に入力するとnodebrewの使い方が表示されます。
nodebrew 0.7.4

Usage:
    nodebrew help                         Show this message
    nodebrew install             Download and install a  (compile from source)
    nodebrew install-binary      Download and install a  (binary file)
    nodebrew uninstall           Uninstall a version
    nodebrew use                 Use 
    nodebrew list                         List installed versions
    nodebrew ls                           Alias for `list`
    nodebrew ls-remote                    List remote versions
    nodebrew ls-all                       List remote and installed versions
    nodebrew alias          Set alias to version
    nodebrew unalias                 Remove alias
    nodebrew clean  | all        Remove source file
    nodebrew selfupdate                   Update nodebrew
    nodebrew migrate-package     Install global NPM packages contained in  to current version
    nodebrew exec  --   Execute  specified 

Example:
    nodebrew install v0.10.22     Install a specific version number
    nodebrew use v0.10.22         Use a specific version number
では、nodebrewをつかってnodeをインストールします。helpを参照するとインストールに使うコマンドは
nodebrew install 
or
nodebrew install-binary 
となっていることがわかります。僕は楽をしたかったのでinstall-binaryを選択しました。また、versionはなんとなくv0.10.26を選択。なので、インストールコマンドは
nodebrew install-binary v0.10.26
となります。次にどのバージョンを使用するかnodebrewに伝えます。
nodebrew use v0.10.26
そして、確認のために
nodebrew list
とすると使用しているNoad.jsのバージョンが表示されます。
nodebrew list
v0.10.26

current: v0.10.26
念のために、nodeコマンドを使用してnodeが使用できるようになったか確認します。
kiitani> node -v
v0.10.26
良さそうです。

これでNode.jsのインストールが完了です。
次の記事ではSocket.IOをインストールして公式チュートリアルであるchatアプリを作製することでSocket.IOの使い方を勉強します。


2014年7月6日日曜日

Raspberry Piを買って初期設定をする



すっごい久しぶりに書きます。
大学院生になってしまいました。

今日は近くの秋葉原でRaspberry Piを買ってきたので、セットアップを行いました。
忘備録を兼ねて簡単にまとめておきます。

  1. 購入すべきものと購入場所
  2. OSのインストール
  3. 初期設定
 ローカルホストとしてのPCはOSX 10.9.2 marvericksで端末にはiTerm2を使っています。VNCクライアントはFinderの機能を使います。Windowsの方はTeraTerm等でSSHを行うことができます。

1.購入すべきものと購入場所
 まずはRaspberry Piです。これがなくては始まりませんね?TypeBを買いましょう。秋葉原で現地調達するとなると、僕が確認したのはマルツと千石電商本館2Fです。マルツでは4700円+税、千石では4720円だったような気がします。今回は千石で買いました。それにしても千石電商本館2Fは色々センサやらモータも売っていてすごい楽しい。ちなみにRSオンラインから購入すれば3900円+送料です。今すぐ欲しい!休日にRaspiで遊びたいんだ!って人以外はネットで買ったほうが安いです。

 次に周辺機器です。
  • Raspberry Piの電源としてUSB(microB)充電器5V1Aのもの。
  • ストレージとしてClass10/8GB以上のSDカード。


  • ディスプレイ出力するためのHDMIケーブル。
  • 無線LANドングル もしくは LANケーブル。


  • あとは、持っていなければUSBキーボード。
これらは全てヨドバシカメラで購入。今からするとネットで買えばもっと予算が抑えられた気がします。注意点としては、Raspberry PiはSDカードとの相性があるので、http://elinux.org/RPi_SD_cardsを見て確認するといいかもしれません。

▲高専時代に買ったのと違って箱を開けたらボードでケースっぽいのはなかった。


2.OSのインストール
 Rapsberry PIのOSはさまざまなものがあり、NOOBSというシステムをつかってOS複数入れて切り替えて使うこともできますが今回は標準的なRASPBIANをインストールします。OSはhttp://www.raspberrypi.org/downloads/からダウンロードすることができます。僕はターミナルのddコマンドをつかってSDカードにOSのイメージを書き込みました。

 具体的な方法はhttp://www.myu.ac.jp/~xkozima/lab/raspTutorial1.htmlでとても詳しく記述されています。巨人の肩の上に乗っちゃいましょう。最近では、専用のソフトを使用するOSのインストール方法もあるようです。http://elinux.org/RPi_Easy_SD_Card_Setupで詳しく確認できます。また、それも不安だという人は、OS入りのSDカードを購入することもできます。割高ですが。

3.初期設定
 さまざまなサイトで初期設定について書かれているので、今回は自分がやったことをリストアップします。一度目に起動した時に出てくるあの青い設定画面はsudo raspi-configで再び出すことができます。

  • Expand File System
これを実行しないと、パーティションが小さいままでSDカードの容量がもったいないです。

  • Change User Password
セキュリティのためにデフォルトから変えましょう。ちなみにデフォルトはraspberryとなっています。

  • Internationalization Options
言語設定、地域に合わせた時刻設定、キーボードの種類の変更を行います。この時、言語設定でja_JP.UTF8を選択しておきましょう。この時、チェックを入れるためにはスペースキーを押します。またja_JP.UTF8を優先させることで、デスクトップを表示したとき日本語表示されます。時刻はAsiaからTokyoを選びます。

  • rootのパスワードの変更
デフォルトではrootにパスワードがかかっていません。コマンドは、

sudo passwd root

です。

  • 無線LANの設定
無線LANの設定はhttp://openrtm.org/openrtm/ja/content/raspberrypi_initial_settingを参考にすると良いです。


  • iptablesの設定
ファイアウォールを設定します。http://wordpress.zenmai.org/2013/09/29/raspberry-pi-9-2/の方の設定を参考に設定しています。このくらいを行っておけば最低限セキュリティを考えているといえるのでは無いでしょうか。Raspberry Piを踏み台にして、家のパソコンがいたずらされたらい屋ですからね…。



 えー。最後はオススメのサイトを紹介しまくるという投げやりな感じになってしまいましたが、次回はRaspberry Piに直接キーボードやモニターを刺さずに遠隔操作できるSSHやVCNについて書きたいと考えています。とりあえずググればできるよってことで!

2014年1月28日火曜日

ArduinoをWindowsにつないでGmailの未読メールの数を表示する (2)

前回記事
の続き.前回の記事ではlibcurlを使って,未読メール一覧を取得してchar型配列に格納するところまでやった.今回の記事では,文字列処理を行って未読メール数を取得するところまでをみていく.

以下にソースを示す.

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

#include <curl/curl.h>
#include <string.h>

typedef struct
{
    char* memory;
    size_t size;
} Memory;

size_t write_memory_callback(void* ptr, size_t size, size_t nmemb, void* data)
{
    if (size * nmemb == 0){
        return 0;
 }
    size_t realsize = size * nmemb;
    Memory* mem = (Memory*)data;
    
    mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory) {
        memcpy(&(mem->memory[mem->size]), ptr, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
    }

    return realsize;
}

int main(void)
{
    CURL *curl;
    CURLcode res;
    char* start;
    char* end;
    //未読数が囲まれているタグを定義
    char start_str[] = "<fullcount>";
    char end_str[] = "</fullcount>";
    //タグ部分の切り出し
    char unread[100];
    Memory* mem = (Memory* )malloc(sizeof(Memory*));
    int startposition,endposition;
 int unreadNum = 0;
    
 while(1){
  mem->size = 0;
  mem->memory = NULL;
  curl = curl_easy_init();
 
  if(curl)
  {
       curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
       //ユーザ名・パスワード設定
       curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password");
       curl_easy_setopt(curl, CURLOPT_URL,"https://mail.google.com/mail/feed/atom");
       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback);
       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)mem);

       res = curl_easy_perform(curl);

       //エラーチェック 
       if(res != CURLE_OK){
          fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }
       //クリーンアップ
       curl_easy_cleanup(curl);
  }

  start = strstr(mem->memory,start_str); 
  end = strstr(mem->memory,end_str);
  startposition = (int)(start-mem->memory);
  endposition = (int)(end-mem->memory);
  strncpy_s(unread, mem->memory+startposition,endposition-startposition);
  
  //数字の抜き出し
  int arrayIndex = 0;
  char unreadNumStr[10]={0};
  for(int i=0; i<strlen(unread); i++){
   if(isalnum((int)unread[i]) != 0){
    if(isalpha((int)unread[i]) == 0){
     unreadNumStr[arrayIndex] = unread[i];
     arrayIndex++;
    }
   }
  }

  unreadNum = atoi(unreadNumStr);
  printf("%d\n",unreadNum);
 }
    return 0;
}

簡単に説明すると,

1. strstr関数を使って,<fullcount>,</fullcount>を探し,そこから切り出しを始める.
 例えば,処理前の文字列が<fullcount>1</fullcount>asdfaklsufkashdf.....
だとすると,
startは<fullcount>1</fullcount>asdfaklsufkashdf.....
となり,
endは</fullcount>asdfaklsufkashdf.....
となる.この操作によって,欲しい文字列<fullcount>1</fullcount>の始まりと終わりのポインタがわかる.

2. 何文字目から何文字目までを切り出すのかを明確にする

3. strncpy_s関数を使って文字列を切り出す.
コピーのはじめと終わりの位置を指定してコピーすることで新しい文字列に目的の文字列を切り出します.

4. isalnum , isalpha関数を使って数字部分のみを取り出す.

5. atoi関数を使って文字列を数値に変換する.

という流れになっている.