Wio LTEで遊んでみる（その２：温湿度センサー）

[Grove IoT スターターキット for SORACOM](https://soracom.jp/press/2017102501/)で遊んでみるの続き。

- [初回：環境構築＋Lチカ](https://qiita.com/ryo_naka/items/45fcb686f264f537a493)

##〇温湿度
センサー
http://wiki.seeedstudio.com/Grove-TemperatureAndHumidity_Sensor/

スケッチはまずは
groveのgrove-temperature-and-humidity-sensorを指定。
スケッチの中に
`#define SENSOR_PIN    (WIOLTE_D38)`
とあるので、D38につないでみる。

表示できた。

<img width="321" alt="temperature_01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/512fe157-cf9d-6973-ae8a-c4921df3c14e.png">


###〇処理について
表示だけできても応用しにくいのでスケッチの中身も確認してみる。

使っている関数とか
[リファレンス](http://www.musashinodenpa.com/arduino/ref/index.php)

####〇初期化

    void DHT11Init(int pin)
    {
      digitalWrite(pin, HIGH);
      pinMode(pin, OUTPUT);
    }

・[digitalWrite](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2051)
`HIGHまたはLOWを、指定したピンに出力します。`

HIGHでON、LOWでOFFと思っておけばいいのかな？

・[pinMode](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2014)
`ピンの動作を入力か出力に設定します。`

Pinに紐づいているモジュールからのIN/OUTを変更できると思っておけばOK？
OUTPUTに設定すると、データを取得できる　と？


####〇開始

    void DHT11Start(int pin)
    {
      // Host the start of signal
      digitalWrite(pin, LOW);
      delay(18);
      
      // Pulled up to wait for
      pinMode(pin, INPUT);
      while (!digitalRead(pin)) ;
      
      // Response signal
      while (digitalRead(pin)) ;
      
      // Pulled ready to output
      while (!digitalRead(pin)) ;
    }

・[digitalRead](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2075)
`指定したピンの値を読み取ります。その結果はHIGHまたはLOWとなります。`

Pinに紐づいているモジュールからの値？を受け取れる。
でもHIGHまたはLOWってことはON/OFFってこと？？
今回のように温度や湿度を取得したい場合はこれだと詳細なデータの取得はできないってことかな。

####〇終了
    void DHT11Finish(int pin)
    {
      // Releases the bus
      while (!digitalRead(pin)) ;
      digitalWrite(pin, HIGH);
      pinMode(pin, OUTPUT);
    }
    
初期化にしている設定と同じ状態にしているってことかな。


####〇データ取得
    bool TemperatureAndHumidityRead(float* temperature, float* humidity)
    {
      byte data[5];
      
      DHT11Start(TemperatureAndHumidityPin);
      for (int i = 0; i < 5; i++) data[i] = DHT11ReadByte(TemperatureAndHumidityPin);
      DHT11Finish(TemperatureAndHumidityPin);
    
      略
    }
    byte DHT11ReadByte(int pin)
    {
      byte data = 0;
      
      for (int i = 0; i < 8; i++) {
	    while (digitalRead(pin)) ;
	    
	    while (!digitalRead(pin)) ;
	    unsigned long start = micros();
	    
	    while (digitalRead(pin)) ;
	    unsigned long finish = micros();
	    
	    if ((unsigned long)(finish - start) > 50) data |= 1 << (7 - i);
	      }
      
      return data;
    }
    
・[micros](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2555)
`Arduinoボードがプログラムの実行を開始した時から現在までの時間をマイクロ秒単位で返します。約70分間でオーバーフローし、ゼロに戻ります。`

(finish - start)で処理にかかった時間を取得しているってことか。
でもここの処理で何をしたいのかがよくわからん。
雰囲気的にはビット単位で取得しているってことなんだろうけど。


改めてセンサーのページを確認してみる

>When MCU sends a trigger signal, sensor will change from low power consumption mode to active mode. After the trigger signal sensor will send a response signal back to MCU, then 40 bit collected data is sent out and a new signal collecting is trigged.(Note that the 40 bit collected data which is sent from sensor to MCU is already collected before the trigger signal comes.) One trigger signal receives one time 40 bit response data from sensor. Single-bus data is used for communication between MCU and sensor. The communication process is shown below:

Google先生に頼る。
>MCUがトリガ信号を送信すると、センサは低消費電力モードからアクティブモードに切り替わります。トリガ信号センサが応答信号をMCUに送り返すと、40ビットの収集データが送信され、新しい信号収集がトリガされます（センサからMCUに送信される40ビットの収集データは、トリガー信号が来ます。）1つのトリガー信号はセンサーから1回の40ビット応答データを受け取ります。シングルバスデータは、MCUとセンサ間の通信に使用されます。通信プロセスを以下に示します。

わかるようなわからんような。

>It costs 5ms for single time communication.The high-order bit of data sends out first. Signal Data is 40 bit, comprised of 16 bit humidity data, 16 bit temperature data and 8 bit checksum.The data format is:
    
    8bits integer part of humidity+8bits decimal part of humidity
    +8bits integer part of temperature+8bits decimal part of temperature
    +8bits checksum.
    
5msってのはここから出てきている数字か。
40bitだから、8ビットずつデータを取得して1バイトずつ格納しているのか。

でも、なんでwhile、なんでdata |= 1 << (7 - i)なのかはようわからんな。。
データの取得時に細かくログだしてみりゃわかるんだろうけど。。

まあ、とりあえずこれでこのモジュールのデータが取れると思っておけばいいんだろうけど。

####〇チェック
    bool DHT11Check(const byte* data, int dataSize)
    {
      if (dataSize != 5) return false;
    
      byte sum = 0;
      for (int i = 0; i < dataSize - 1; i++) {
    	sum += data[i];
      }
    
      return data[dataSize - 1] == sum;
    }

雰囲気からするとchecksumの値をチェックしているということかな。


####〇取得後
      *humidity = (float)data[0] + (float)data[1] / 10.0f;
      *temperature = (float)data[2] + (float)data[3] / 10.0f;

これで温度と湿度を返却できるということか。


####〇接続/送信/切断
ついでにSORACOMのHarvestへの送信部分についても

      connectId = Wio.SocketOpen("harvest.soracom.io", 8514, WIOLTE_UDP);
    
      if (!Wio.SocketSend(connectId, data)) {
	    SerialUSB.println("### ERROR! ###");
	    goto err_close;
      }
    
      length = Wio.SocketReceive(connectId, data, sizeof (data), RECEIVE_TIMEOUT);
      if (length < 0) {
	    SerialUSB.println("### ERROR! ###");
	    goto err_close;
      }
      if (length == 0) {
	    SerialUSB.println("### RECEIVE TIMEOUT! ###");
	    goto err_close;
      }
    

これは見ればなんとなくわかる。


とりあえずは今回はここまで