LoginSignup
14
4

More than 3 years have passed since last update.

Elixir Circuits I2CでLチカ

Last updated at Posted at 2019-12-21

この記事は、「#NervesJP Advent Calendar 2019」 の21日目です。
昨日は @32hero さんの「Why Nerves|>Nervesを使う理由探し」でした。

はじめに

Elixirを使って、RaspberryPiのハードウェア制御の練習をしてみました。

外観

今回は、Elixir CircuitsI2C制御サンプルを使って、IOエキスパンダICのMCP23017を制御してみます。

※Nervesでないのは、Ubuntu環境が今、手元に無いため・・・ごめんなさい!!

動作環境

ここでのハードウェア環境は、以下を想定しています。

  • Raspberry Pi 3+
  • Raspbian Buster (2019年9月版)
  • Elixir 1.9.4
コマンドライン
~ $ uname -a
Linux RaspberryPi 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux

~ $ iex
Erlang/OTP 22 [erts-10.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 

回路

RaspberryPiとMCP23017の接続

RaspberryPiとMCP23017の接続

MCP23017とLEDの接続

MCP23017とLEDの接続

プログラムの下準備

I2Cの制御に必要なパッケージをインストールします。

コマンドライン
pi@raspberrypi:~ $ sudo apt install i2c-tools -y

I2C経由でMCP23017と通信できているか確認します。

コマンドライン
pi@raspberrypi:~ $ sudo i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

回路図の通りに接続した場合(A0, A1, A2 = LOW となっている)MCP23017はアドレス0x20に割り当てされます。

MCP23017の制御方法

コマンドの構成は<<レジスタ名, 設定値>>です。

  1. 初期化コマンドを送る

    • MCP23017のPORTAを、出力に設定<<0x00, 0x00>>
    • (入力にする場合は<<0x00, 0xff>>
  2. 出力のON/OFFの指令を送る

    • PORTAの0~7chをON<<0x12, 0xff>>
    • PORTAの0~7chをOFF<<0x12, 0x00>>

MCP23017の主要コマンド

レジスタ名の
*Aは、MCP23017のGPA0~7。
*Bは、MCP23017のGPB0~7に対応します。

レジスタ名 機能
IODIRA 0x00 入出力方向 (0: 出力 1:入力)
IODIRB 0x01
GPIOA 0x12 出力レジスタ (GPIOの値)
GPIOB 0x13

プログラム例

ElixirでI2Cを制御する

基本構文
I2C.write(ref, 0x20, <<0x12, 0xff>>)
引数 役割 例文
第2 送信先のI2Cアドレス 0x20(MCP23017のデフォルトアドレス)
第3 コマンド 0x12(GPIOAの出力レジスタ)、0xff(8ch全部出力とする)

準備

コマンドライン
~$ git clone https://github.com/elixir-circuits/circuits_i2c.git
~$ cd circuits_i2c/lib
~/circuits_i2c/lib $ touch circuits_i2c.ex

空のソースファイルcircuits_i2c.exを作っておきます。

ソースコード

出力・点滅動作

circuit.ex
defmodule Circuits do

    # "L" Chika
    def loop1(start, count_up, sleep_msec) do
        Stream.iterate( start, &( &1 + count_up ) ) |>
        Enum.map( fn count ->

            alias Circuits.I2C
            #I2Cを開く
            {:ok, ref} = I2C.open("i2c-1")

            # 初期化コマンドをI2C経由で送る
            # MCP23017のPORTAを、出力に設定
            I2C.write(ref, 0x20, <<0x00, 0x00>>)

            # PORTAの0~7chをHIGHに切替
            I2C.write(ref, 0x20, <<0x12, 0xff>>)
            :timer.sleep( sleep_msec )
            # PORTAの0~7chをLOWに切替
            I2C.write(ref, 0x20, <<0x12, 0x00>>)
            :timer.sleep( sleep_msec )

            end )
    end


    def main([]) do
        IO.puts "Hello I2C LED..."
        # 処理スタート
        loop1(0, 1, 500)
    end
end

実行

LEDが500msおきに点滅します。

コマンドライン
~/circuits_i2c $  mix run -e "Circuits.main([])" 
Hello I2C LED...

Grove規格の互換ボード

Grove規格の互換ボード

Grove規格(I2C)互換のボードを作ってみました。

※12/21時点、まだ公開できてないです、すみません!!
GitHub

参考資料

14
4
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
14
4