Help us understand the problem. What is going on with this article?

AndroidThingsとArduino間でやり取りする ~ Android ThingsでDHT11を扱う ~

More than 1 year has passed since last update.

 
低価格の温度センサーとして売られているDHT11ですが、
Android Thingsからは直接扱えません。

今回はDHT11をAndroidThingsで扱うために、ArduinoでDHT11からデータを読み取り、AndroidThingsに送ります。

DHT11とAndroid Things

上にも書きましたが、現状(2017/12/07)、Android ThingsではDHT11は扱えません。
諸々議論はこのスレッドでされています。
簡単に言うと、Android Thingsでは、GPIOからデータを呼び出すのに230us位かかるのですが、
DHT11では、データを読み取るのに20usの速さが必要であり、現状Android Thingsでは直接データを読み取ることが実質不可能となっています。

Android ThingsとArduino

そこでDHT11等を扱うために、Arduinoでデータを読み取り、Android Thingsに送ってしまうという方法を思いつくわけです。
Arduino、AndroidThings間はUARTを利用して、双方向でデータをやり取りします。

実際にやってみる

回路

arduino-wrap.png

Arduino側のコード

Arduino側のコードです。
AndroidThingsからUARTを利用して、データが送信されるので、Serial.readで取得します。
取得するのは温度を取得するか(T)、湿度を取得するか(H)のコマンドなので、コマンドに合わせて、DHT11から読み取ります。
なおDHT11の温度や湿度は、adafruitのライブラリを利用して、取得します。
そして取得したデータをSerialに流し、Android Thingsへ送ります。

#include <DHT.h>;
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup() {                
  Serial.begin(115200);  
  dht.begin();
}

void loop() {
    int inByte = Serial.read();
    switch (inByte) {
    case 'T':
      sendTemperature();
      break;
    case 'H':
      sendHumidity();
      break;
  }
}

void sendTemperature(){
  send(dht.readTemperature());
}

void sendHumidity(){
  send(dht.readHumidity());
}

void send(float val) {
  String value = "";
  value += val;

  char charBuf[value.length()+1];
  value.toCharArray(charBuf, value.length()+1);

  Serial.write(charBuf);
}

Android Things側

全コードは以下にあります。

Arduinoへのデータ送信とデータ取得

DHT11のデータ送受信用のクラスです。
UARTDeviceの初期化を行い、データの取得を行います。

DHT11.kt
package com.github.soundtricker.androidthings.sampledht11

import android.util.Log
import com.google.android.things.pio.PeripheralManagerService
import com.google.android.things.pio.UartDevice
import java.io.IOException
import java.nio.ByteBuffer

class DHT11 constructor(uartName: String, pioService: PeripheralManagerService) {

    private val mMessageBuffer = ByteBuffer.allocate(10)
    private var mDevice: UartDevice?

    init {
        mDevice = pioService.openUartDevice(uartName)
        mDevice!!.setDataSize(8)
        mDevice!!.setBaudrate(115200)
        mDevice!!.setParity(0)
        mDevice!!.setStopBits(1)
    }

    fun getTemperature(): String {
        var response = ""
        val buffer = ByteArray(10)

        try {
            return this.fillBuffer(buffer, "T")
        } catch (e: IOException) {
            Log.e("DHT11", "failed read temperature", e)
        }

        return response
    }

    fun getHumidity(): String {
        var response = ""
        val buffer = ByteArray(10)

        try {
            response = this.fillBuffer(buffer, "H")
        } catch (e: IOException) {
            Log.e("DHT11", "failed read temperature", e)
        }

        return response
    }

    @Throws(IOException::class)
    private fun fillBuffer(buffer: ByteArray, mode: String): String {
        this.mDevice!!.write(mode.toByteArray(), mode.length)

        Thread.sleep(500L)
        this.mDevice!!.read(buffer, buffer.size)
        this.processBuffer(buffer)
        return String(this.mMessageBuffer.array(), charset("UTF-8")).replace("\u0000".toRegex(), "")
    }

    private fun processBuffer(buffer: ByteArray) {
        mMessageBuffer.clear()
        buffer.forEach { b ->
            if (b.toInt() != 0) {
                this.mMessageBuffer.put(b)
            }
        }
    }

    @Throws(Exception::class)
    fun close() {
        try {
            this.mDevice?.close()
        } finally {
            this.mDevice = null
        }
    }


}

MainActivity

MainActivityでは定期的にデータを読み取ってログに流すだけです。

MainActivity.kt
package com.github.soundtricker.androidthings.sampledht11

import android.app.Activity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import com.google.android.things.pio.PeripheralManagerService

/**
 * Skeleton of an Android Things activity.
 *
 * Android Things peripheral APIs are accessible through the class
 * PeripheralManagerService. For example, the snippet below will open a GPIO pin and
 * set it to HIGH:
 *
 * <pre>{@code
 * val service = PeripheralManagerService()
 * val mLedGpio = service.openGpio("BCM6")
 * mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
 * mLedGpio.value = true
 * }</pre>
 * <p>
 * For more complex peripherals, look for an existing user-space driver, or implement one if none
 * is available.
 *
 * @see <a href="https://github.com/androidthings/contrib-drivers#readme">https://github.com/androidthings/contrib-drivers#readme</a>
 *
 */
class MainActivity : Activity() {

    companion object {
        private val TAG = MainActivity.javaClass.simpleName
    }

    private var mDht11: DHT11? = null

    private var mHandler: Handler? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mDht11 = DHT11("UART0", PeripheralManagerService())
        mHandler = Handler()
        mHandler!!.post(mRunnable)

    }

    override fun onDestroy() {
        super.onDestroy()
        mDht11?.close()
        mDht11 = null
    }

    private fun run() {
        mHandler!!.postDelayed(mRunnable, 10L)
    }

    private val mRunnable: Runnable = Runnable {
        Log.d(TAG, "Humidity: ${mDht11!!.getHumidity()}")
        Log.d(TAG, "Temperature: ${mDht11!!.getTemperature()}")
        run()
    }
}

まとめ

AndroidThingsではどんなセンサーでも触れる訳ではなく、ちょっとハマりました。
センサー周りの処理はやはりArduinoなどに任せたほうが楽です。

参考

https://github.com/mplacona/arduwrap

なお今回はUARTを使いましたが、I2Cで送る方法もあるようです。
https://github.com/theangels/AndroidThings_Thingworx_Demo

soundTricker
Google API、GSuite、GCP、Angular(1&2)、Google Apps Scriptらへんの人 一応Google Developer Expert(Apps Script)です。 https://developers.google.com/community/experts/directory/profile/profile-keisuke_oohashi
https://plus.google.com/u/0/112329532641745322160/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away