7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Seeed UGAdvent Calendar 2020

Day 2

Elixir Circuits I2Cでアナログ入力 (Grove Base Hat for Raspberry Pi)

Last updated at Posted at 2020-12-01

#1.はじめに

Elixirを使って、RaspberryPiのハードウェア制御の練習をしてみました。
今回は、Elixir Circuits.I2Cから、Grove Base Hat for Raspberry Piに搭載されているADコンバータを制御してみます。

image.png

#2.ハードウェア

Seeed社のGROVE規格1の機器を、RaspberryPiに接続するインターフェース・ボードです。GPIO、I2C、UART、そしてアナログタイプの入力用として12bitのADコンバータも搭載しています。

###I2C通信仕様

  • Grove Base HATのアドレス:0x04
コマンドライン
 $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- 04 -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
I2C Registers
0x10 ~ 0x17 ADC raw data
0x20 ~ 0x27 input voltage
0x29 output voltage (Grove power supply voltage)
0x30 ~ 0x37 input voltage / output voltage

I2Cコマンドの処理の流れ

# I2Cアドレス
@address 0x04

#コマンド送信
I2C.write(ref, @address, <<I2C Registers>>)
Process.sleep(1)

#結果受信、2バイト読み込み
I2C.read(ref, @address, 2)
{:ok, <<ret0, ret1>>} = I2C.read(ref, @address, 2)

#2バイト分を連結
ret0 ||| ret1 <<< 8

#3.ソフトウェア

##(1)下準備

プロジェクトを作ります。

コマンドライン
$ cd gitwork
$ mix new i2chatad
$ cd i2chatad

##(2)コード

i2chatadc.ex
defmodule I2chatad do
  @moduledoc """
  Documentation for `I2chatad`.

  https://github.com/elixir-circuits/circuits_i2c
  https://github.com/Seeed-Studio/grove.py/blob/master/grove/adc.py
  """

  alias Circuits.I2C
  require Logger
  use Bitwise

  # I2Cアドレス
  @address 0x04

  @doc """
  データ取得
  ## Examples
      iex> I2chatad.get()
  """
  def get() do
    # I2Cを開く
    {:ok, ref} = I2C.open("i2c-1")

    Logger.info("      RAW  VOLT    RATE")

    # AD0~3読み込み
    Enum.each([0, 1, 2, 3], fn ch ->
      # RAWデータ
      raw = read_raw(ref, ch)
      # mVデータ
      vol = read_voltage(ref, ch)

      # RATEの表記(xx.x %)のうち、整数部だけ残す
      rat =
        read(ref, ch)
        |> div(10)

      #測定結果を表示
      Logger.info(" ch#{ch}: #{raw}  #{vol} mV  #{rat} %")
    end)
  end

  @doc """
  12bitアナログ入力のRAWデータを読み込み
  ## Parameter
    - channel (int): 0 - 7, specify the channel to read
  ## Return:
    - (int): the adc result, in [0 - 4095]
  """
  def read_raw(ref, channel) do
    regaddr = 0x10 + channel
    read_register2(ref, regaddr)
  end

  @doc """
  電圧(mV)変換した値を返す
  ## Parameter
    - channel (int): 0 - 7, specify the channel to read
  ## Return:
    - (int): the voltage result, in mV
  """
  def read_voltage(ref, channel) do
    regaddr = 0x20 + channel
    read_register2(ref, regaddr)
  end

  @doc """
  入力電圧を、0~3.3Vのスケールでパーセント変換した値を返す
  ## Parameter
    - ref : i2c id
    - channel (int): 0 - 7, specify the channel to read
  ## Return:
    - (int): the ratio, in 0.1%
  """
  def read(ref, channel) do
    regaddr = 0x30 + channel
    read_register2(ref, regaddr)
  end

  @doc """
  I2Cレジスタの読み出し(8bit)
  ## Parameter
    - ref : i2c id
    - n (int): I2C Resister Addr
  ## Return:
  """
  def read_register(ref, n) do
    I2C.write(ref, @address, <<n>>)
    Process.sleep(1)
    {:ok, <<ret>>} = I2C.read(ref, @address, 1)
    ret
  end

  @doc """
  I2Cレジスタの読み出し(12bit)
  ## Parameter
    - ref : i2c id
    - n (int): I2C Resister Addr
  ## Return:
  """
  def read_register2(ref, n) do
    I2C.write(ref, @address, <<n>>)
    Process.sleep(1)
    I2C.read(ref, @address, 2)
    {:ok, <<ret0, ret1>>} = I2C.read(ref, @address, 2)
    #2バイト分の値をビットシフトして連結
    ret0 ||| ret1 <<< 8
  end
end

##(3)実行結果

iexのプロンプトから、I2chatad.getを実行するたびに、ch0~4までの値を取得します。

ここでは、各ADxのコネクタに、以下のセンサを繋いでいます。

Grove AD センサ
AD0 Grove Light Sensor
AD2 Grove Button
$ iex -S mix
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Compiling 1 file (.ex)
Remember to keep good posture and stay hydrated!
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)

iex(1)> I2chatad.get
12:34:45.246 [info]        RAW   VOLT     RATE
12:34:45.253 [info]   ch0: 2502  2010 mV  60 %   ### ← Light 明るい
12:34:45.260 [info]   ch1: 2374  1796 mV  52 %
12:34:45.267 [info]   ch2: 0  0 mV  0 %          ### ← Button 離した
12:34:45.274 [info]   ch3: 2504  2010 mV  61 %
:ok  

iex(2)> I2chatad.get
12:34:48.758 [info]        RAW   VOLT     RATE
12:34:48.767 [info]   ch0: 1225  1126 mV  32 %   ### ← Light 暗い
12:34:48.776 [info]   ch1: 2131  1889 mV  54 %
12:34:48.785 [info]   ch2: 4095  3283 mV  99 %   ### ← Button 押した
12:34:48.794 [info]   ch3: 2944  2396 mV  70 %
:ok: 

#4.おわりに

Elixir Circuits.I2Cから、Grove Base Hat for Raspberry PiのADコンバータを操作する例を紹介しました。もう少し使いやすくするため、ライブラリにしてみます。(作成中)

#参考資料

  1. https://wiki.seeedstudio.com/Grove_System/

7
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
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?