Raspberry PiとBlynkで部屋の気温をスマホで確認

#概要

毎回々々概要とか書いてるけど意味ないことばっかりで、今回はPhpstorm買っちゃったぐらいしか思いつかなかったんですが・・・。

せっかくRaspberry Piがあるので、IoTらしく流行りの[Blynk](http://www.blynk.cc/)で遊びました。

#さっそく導入 -> Lチカ

ということを書こうと思いましたが、スマホのスクショ撮ったり大変なので、LチカはQiitaで公開済みのいい記事があったのでそちらを参考にしたほうがいいと思います・・・。

[Qiita: \[\*Raspberry Pi\*\] Blynkを使ってスマホからLEDチカチカ)](http://qiita.com/cigalecigales/items/e65ea7192c3e381657ed)

なので、ここではRaspberry PiとI2Cで気温をグラフとかで表示したいと思います。

#I2Cで気温を取得してBlynkで表示

と、書いておきながらまずはLabelにテキスト表示してみました。

ググるとどれもこれもマイコン使ってたりしてRaspberry Piのやり方がわからなかったので、仕方なくBlankのリファレンス見ましたよ・・・。

[Blynk Docs](http://docs.blynk.cc/)

上記のLチカを行った人はこんな感じでRaspberry PiでBlynk Serverが立ち上がっていると思います。
![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/32577/c51d9019-ec03-08ae-5e4c-0a88e6b01f82.png)

これでスマホのボタンを押すとLがチカチカしたかと思います。

次はスマホ側のウィジェットに何かデータを渡します。

##Virtual Pins

お遊びでスマホ側からデータをリクエストした日時でも表示してみます。

[Blynk Docs \#Virtual Pins](http://docs.blynk.cc/#blynk-main-operations-virtual-pins)によると、Virtual Pinというものにテキストでも食べさせると、その通りに送られるようです。

```c
Blynk.virtualWrite(pin, "abc");
Blynk.virtualWrite(pin, 123);
Blynk.virtualWrite(pin, 12.34);
Blynk.virtualWrite(pin, "hello", 123, 12.34);
```

これをどこに書くかというと、Blynkのgitのクローンを作った場所にある[main.cpp](https://github.com/blynkkk/blynk-library/blob/master/linux/main.cpp)に書きます。
要はカスタマイズするなら、makeし直してくださいとのこと。

```c:main.cpp
/**
 * @file       main.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Mar 2015
 * @brief
 */

/* <--------------------------------------------------------------------- ここから */
#include <stdio.h>
#include <string.h>
#include <time.h>
/* <--------------------------------------------------------------------- ここまで（多分いらない・・・） */

//#define BLYNK_DEBUG
#define BLYNK_PRINT stdout
#ifdef RASPBERRY
 #include <BlynkApiWiringPi.h>
#else
 #include <BlynkApiLinux.h>
#endif
#include <BlynkSocket.h>
#include <BlynkOptionsParser.h>

static BlynkTransportSocket _blynkTransport;
BlynkSocket Blynk(_blynkTransport);

#include <BlynkWidgets.h>

BLYNK_READ(V0) /* <--------------------------------------------------------------------- ここから */
{
  FILE *fp;
  char str[256] = {0};

  if ((fp = fopen("/tmp/blynktest.log", "a+")) == NULL) { /* 適当なところにログファイル作る感じ */
    printf("file open error!!\n");
    exit(EXIT_FAILURE);
  }

  /*
  while (fgets(str, 256, fp) != NULL) {
    printf("%s", str);
  }
  */

  time_t now;

  now = time(NULL);
  fprintf(fp, "%s", ctime(&now)); /* ログファイルのケツに今の日時を入れる */
  fclose(fp);

  BLYNK_LOG("%s", ctime(&now)); /* Blynk待受側にログを出力 */

  Blynk.virtualWrite(V0, ctime(&now)); /* 仮想のピンV0に今の日時の文字列を代入 */
} /* <--------------------------------------------------------------------- ここまで */

BLYNK_WRITE(V1)
{
  printf("Got a value: %s\n", param[0].asStr());
}

int main(int argc, char* argv[])
{
    const char *auth, *serv;
    uint16_t port;
    parse_options(argc, argv, auth, serv, port);

    Blynk.begin(auth, serv, port);

    while(true) {
        Blynk.run();
    }

    return 0;
}
```

これをmakeして、`./blynk --token=***`を行うと、Lチカ同様にBlynk Serverが起動して待受状態になります。

スマホの方はLabelを作って、Inputをvirtual V0に、Labelを`/pin/`にします。
![s_Screenshot_2016-11-30-00-46-31.png](https://qiita-image-store.s3.amazonaws.com/0/32577/278dfc3f-1da4-841a-416f-0635b67826f3.png)

あとはスマホ側のBlynk右上の再生ボタンを押すと、スマホ側・Raspberry PiのBlynk待受側・/tmp/blynktest.logに今の日時が書き込まれていきます。
![b.PNG](https://qiita-image-store.s3.amazonaws.com/0/32577/b6be404e-f1e0-0240-36fc-ce81fb448be0.png)

![s_Screenshot_2016-11-30-00-34-17_Ink_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/32577/9f66dd43-9d23-3b2b-0255-445196ea5d19.jpeg)

##いざI2Cへ

もう言うことないですね！
`BLYNK_READ(V0){}`ようはここの部分にI2Cのロジック書けば動きます。
（上のスマホ側の画像でもグラフで気温出してるっぽいところありますが、まさにそれがI2C使ったやつです）

```c:main.cpp
/**
 * @file       main.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Mar 2015
 * @brief
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include <linux/i2c-dev.h> // I2C用インクルード
#include <fcntl.h>
#include <sys/ioctl.h>


//#define BLYNK_DEBUG
#define BLYNK_PRINT stdout
#ifdef RASPBERRY
 #include <BlynkApiWiringPi.h>
#else
 #include <BlynkApiLinux.h>
#endif
#include <BlynkSocket.h>
#include <BlynkOptionsParser.h>

static BlynkTransportSocket _blynkTransport;
BlynkSocket Blynk(_blynkTransport);

#include <BlynkWidgets.h>

float tempval();

BLYNK_READ(V0)
{
  double num = 0.00;
  char str[128]={0};

  num = tempval();
  sprintf(str, "%.2f", tempval());
  Blynk.virtualWrite(V0, str);
}

int main(int argc, char* argv[])
{
    const char *auth, *serv;
    uint16_t port;
    parse_options(argc, argv, auth, serv, port);

    Blynk.begin(auth, serv, port);

    while(true) {
        Blynk.run();
    }

    return 0;
}

float tempval(){
    char *i2cFileName = "/dev/i2c-1";
    const unsigned char i2cAddress = 0x18;
    const __u8 t_reg = 0x05;
    int i2c_fd;

    if((i2c_fd = open(i2cFileName,O_RDWR)) < 0){
        fprintf(stderr,"Faild to open i2c port¥n");
        return 1;
    }
    if (ioctl(i2c_fd, I2C_SLAVE,i2cAddress) < 0) {
        fprintf(stderr,"Unable to get bus access to talk to slave¥n");
        return 1;
    }
    __s32 res = i2c_smbus_read_word_data(i2c_fd,t_reg);
    if(res < 0){
        fprintf(stderr,"Error i2c_smbus_read_word_data()¥n");
        return 1;
    }
    float temp;
    {
        __u16 t = res << 8 | res >> 8;//byte swap
        temp = t & 0x0FFF;      //mask
        temp /= 16;
        if(t & 0x1000){                 //sign or unsigned
            temp -= 256;
        }
        }

    time_t t;
    time(&t);
    struct tm *m;
    m = localtime(&t);

    // printf("%d/%d/%d-%d:%d:%d,%.2f\n",m->tm_year+1900,m->tm_mon+1,m->tm_mday,m->tm_hour,m->tm_                                                                                                                                                                                                                            min,m->tm_sec,temp);
    // printf("%.2f", temp);
    return temp;
}
```

ちょっと眠いです。
明日も出勤しないといけないので、とりあえずこれであげます。

というか、スマホ側のBlynkは直感操作余裕なので、説明することありません！
グラフ作ってみれば絶対わかります！

すごいね！




問題はC言語が久々すぎてうんこ・・・