LoginSignup
3
0

More than 5 years have passed since last update.

Android ThingsとA/D変換(MCP3008)

Last updated at Posted at 2017-12-05

今日はAndroid Things on Raspberry PIでA/D変換をします。
Raspberry Piにはアナログ入力がないので、アナログ入力が必要な場合はA/Dコンバーターが必要です。
手元にあるA/DコンバーターがMCP3008しか無いので、MCP3008を使ってやります。

ハードウェア

以下の構成です。
可変抵抗から読み取った値を使ってサーボを動かします。

potentionmeter.png

可変抵抗から読み取ったアナログ値をMCP3008を使ってA/D変換します。

コード

MCP3008の公式Peripheral Driver Libraryは現在ありません。
個人で作った方がいるようです。
https://github.com/PaulTR/AndroidThingsMCP3008ADC

ただ、maven repositoryには登録してない臭いので、コピペして使います。
サーボについては、Peripheral Driver LibraryにあるPwmServoを利用します。

今回のコードは以下においてあります。
https://github.com/soundTricker/analog-digital-convert

メインどころ

複雑なところはあんまりないですね
センサーからデータを読み取ることろは、Handlerを使って、キューに積んで処理しています。

またmap関数は読み取り値→角度の変換処理を主に行ってます。

MainActivity.kt

package com.github.soundtricker.androidthings.analogdigitalconvert

import android.app.Activity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import com.google.android.things.contrib.driver.pwmservo.Servo
import java.io.IOException


class MainActivity : Activity() {


    companion object {
        private val TAG = MainActivity::class.java.simpleName

        private val PIN_CS = "BCM25"
        private val PIN_CLOCK = "BCM17"
        private val PIN_MOS_IN = "BCM24"
        private val PIN_MOS_OUT = "BCM23"
        private val PIN_SERVO = "PWM1"

        private val CHANNEL_POTENTIONMETER = 0x0
        private val MIN_VOL = 0
        private val MAX_VOL = 410
        private val MIN_ANGLE = 0
        private val MAX_ANGLE = 180

    }

    private lateinit var mcp3008: MCP3008
    private lateinit var mcpHandler: Handler

    private lateinit var servo: Servo

    private val readChannelMoveServo = Runnable {
        readAndMoveServo(CHANNEL_POTENTIONMETER)
    }

    private fun readAndMoveServo(readChannel: Int) {
        val vol = this.mcp3008.readAdc(readChannel)
        Log.i(TAG, "ADC $readChannel: $vol")

        val angle = map(vol, MIN_VOL, MAX_VOL, MIN_ANGLE, MAX_ANGLE)
        val prevAngle = this.servo.angle

        if (Math.abs(prevAngle - angle) <= 3) {
            return
        }
        Log.i(TAG, "ANGLE $readChannel: $angle")
        this.servo.angle = angle
        runReadChannel()
    }


    private fun runReadChannel() {
        this.mcpHandler.postDelayed(this.readChannelMoveServo, 10L)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            this.servo = Servo(PIN_SERVO)
            this.servo.setPulseDurationRange(0.6, 2.35)
        } catch (e: IOException) {
            Log.e(TAG, "servo can't initialized", e)
            return
        }
        this.mcp3008 = MCP3008(PIN_CS, PIN_CLOCK, PIN_MOS_IN, PIN_MOS_OUT)
        try {
            this.mcp3008.register()

        } catch (e: IOException) {
            Log.e(TAG, "mcp can't initialized", e)
            return
        }
        mcpHandler = Handler()
        mcpHandler.post(this.readChannelMoveServo)


    }

    override fun onDestroy() {
        super.onDestroy()
        this.mcp3008.unregister()
        this.servo.close()
    }

    private fun map(x: Int, inMin: Int, inMax: Int, outMin: Int, outMax: Int): Double {
        return ((x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin).toDouble()
    }


}

まとめ

やはりAndroid Thingsだと公式にはライブラリが出てないので、めんどくさいのですが、
よく使われているものはちょこちょこライブラリを作ってくれている人もいるので、探してみるといいと思います。

参考

3
0
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
3
0