LoginSignup
2
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-07

 
低価格の温度センサーとして売られている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などに任せたほうが楽です。

参考

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

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2