I2Cデバイスの活用

5.1. I2Cとは

I2Cは「Inter Integrated Circuit」の略で、機器内、機器間のどちらの通信にも用いられる通信方式です[7]。 機器内のセンサー等のインターフェースとして最も普及しています。 また、類似の規格として、DDC(Display Data Channel)やSMBusがあり、I2Cと一部互換性があります。

I2Cには以下のモード[8]があります。 本書では、普及している「スタンダードモード」と「ファストモード」の説明を行います。

表5.1 I2Cモード一覧

モード クロック Armadillo-640対応 スタンダードモードとの互換性

スタンダードモード

~100kHz

ファストモード

~400kHz

ファストモードプラス

~1MHz

×

ハイスピードモード

~3.4MHz

×

一部互換

ウルトラファストモード

~5MHz

×

互換性なし


一般的な接続方法を下図に示します。 なお、Armadillo-640はマスターとして別のデバイスと通信できます。

images/bus_structures/i2c.svg

図5.1 I2Cの接続方法


images/bus_structures/i2c_3slaves.svg

図5.2 複数のスレーブを接続する場合


I2Cの主な特徴を以下に示します。

  • デバイスはマスターとスレーブが存在
  • 1つのバス上にマスターとスレーブを複数接続可能[9]
  • 信号線はSDA(データ)とSCL(クロック)の2本のみ
  • 信号線はオープンドレイン(プルアップが必要)
  • データはクロックに合わせて変化
  • スレーブは7ビットもしくは10ビットのアドレスを持つ[10]
  • 通信は常にマスターが開始し、アドレスでスレーブを選択
  • クロックは最高400kHz(ファストモード)、最高100kHz(スタンダードモード)

I2Cの詳しい仕様は、NXP Semiconductorsから公開されている資料をご覧ください。

I2Cのデータフォーマットは以下のようになっています。

images/data_formats/i2c_seq_single_byte.svg

図5.3 I2Cの通信フォーマット


S

スタートコンディション

P

ストップコンディション

A

ACK(ACK=0)

N

NACK(ACK=1)

通信はスタートコンディションで開始し、ストップコンディションで終わります。 斜線部分がスレーブの応答です。 1バイトごとに受信側がACKを返すようになっています。なお、マスターが最後のデータを受信したときはNACKを返します。

最初のバイトはアドレスバイトといいます。 2バイト目以降はデータバイトとなり、内容やフォーマットはスレーブのデバイスごとに異なります。

デバイスによっては、以下のように複数バイトの読み出しを連続で行うことも可能です。

images/data_formats/i2c_seq_multi_byte.svg

図5.4 複数バイトの連続送受信


アドレスバイトは、スレーブ指定のための7ビットのアドレスとマスターが読み出すか書き込むかをスレーブに伝えるためのR/Wで構成されています。

images/data_formats/i2c_address_byte.svg

図5.5 アドレスバイト


なお、リスタートやクロックストレッチについては複雑なため、ここでは触れていません。

I2Cの波形は以下のようになっています。

images/waveforms/i2c.png

図5.6 I2Cの波形


5.2. A/Dコンバーター(PCF8591)を使用する

ここでは、I2CバスにA/Dコンバーターを接続する方法を紹介します。

使用するデバイスは以下のとおりです。

  • PCF8591(NXP Semiconductors製)

今回使用するPCF8591は、以下の特長を持ちます。

  • 単電源動作(2.5~6V)
  • I2C接続(スタンダードモード)
  • アドレス 0x48~0x4F(同一バスに8つ接続可能)
  • 分解能 8ビット
  • 逐次比較型
  • 4入力
  • D/A出力あり(8ビット 1出力)

5.2.1. 接続方法

Armadillo-640との接続を示します。 Armadillo-640のCON14から出ているI2C4にPCF8591を接続します。 アドレスを指定するA0~A2は全てGNDに接続しておきます[11]。 AIN0~AIN3がアナログ入力ピンです。 AIN0にかかる電圧を、10kΩの可変抵抗で変えられるようにしています。 AIN1~AIN3はそれぞれ固定電圧としています。 リファレンス電圧VREFに電源電圧と同じ3.3Vを入力しているため、 0V~3.3Vの範囲のアナログ入力を8ビット(256段階)のデジタル値に変換します。

I^2^C接続A/Dコンバーター回路図

図5.7 I2C接続A/Dコンバーター回路図


5.2.2. 対応カーネルイメージの作成

PCF8591のドライバを有効にしたLinuxカーネルと、DTBを作成します。

標準状態のカーネルのソースコードを元に変更する手順は次の通りです。

  1. Device Treeの編集
  2. カーネルコンフィギュレーションでのデバイスドライバの有効化
  3. カーネルとDTBをビルドしArmadilloに書き込み

はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-i2c4.dtsiです(「サンプルソースコード」のページからダウンロードできます)。

&iomuxc {
        pinctrl_i2c4: i2c4grp {
                fsl,pins= <
                        MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x40010808
                        MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x40010808
                >;
        };
};

&i2c4 {
        status = "okay";
        clock-frequency = <50000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c4>;

        pcf8591@48 {                            // 1
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "nxp,pcf8591";
                reg = <0x48>;                   // 2
                input_mode = <0>;
        };
};

図5.8 armadillo-640-i2c4.dtsi


1

デバイス名@スレーブアドレス(16進表記)

2

スレーブアドレス(16進表記)

さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。

#include "armadillo-640-lcd70ext-l00.dtsi"
#endif
#include "armadillo-640-i2c4.dtsi"        //追加行

/ {
        model = "Atmark Techno Armadillo-640";

図5.9 armadillo-640.dts


続いて、「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。

[ATDE ~/linux-4.14-at[version]]$ make ARCH=arm menuconfig

図5.10 menuconfigの実行


Device Drivers  --->
  [*] Hardware Monitoring support  --->   ← 有効にする
    [*]   Philips PCF8591 ADC/DAC         ← 有効にする

図5.11 menuconfig


変更を加え、カーネルコンフィギュレーションを確定してください。

以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。

5.2.3. 使用例

実際に、PCF8591から値の取得をおこなう手順を説明します。 変換された値の末尾に’0'が追加された文字列が返ります。

[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in0_input
0120                                                       ←VR1を回すと値が変化
[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in0_input
1230                                                       ←VR1を回すと値が変化
[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in0_input
2340                                                       ←VR1を回すと値が変化
[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in1_input
1280
[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in2_input
2550
[armadillo ~]# cat /sys/bus/i2c/devices/3-0048/in3_input
0

図5.12 コマンド実行例


5.2.4. プロトコル

PCF8591のデータには3種類あります。

表5.2 PCF8591のデータバイト

データ名 データ方向

コントロールバイト

W

D/A出力値

W

A/D入力値

R


コントロールバイトの書き込みは以下のように行います。

images/data_formats/pcf8591/write_seq.svg

図5.13 PCF8591 通信フォーマット(書き込み)


D/A出力値を書き込む場合は、コントロールバイトに続けて書き込みます。

images/data_formats/pcf8591/write_dac_seq.svg

図5.14 PCF8591 通信フォーマット(D/A出力値書き込み)


A/D入力値の読み出しは以下のように行います。

images/data_formats/pcf8591/read_seq.svg

図5.15 PCF8591 通信フォーマット(読み出し)


PCF8591のアドレスバイトのフォーマットを示します。 7ビットアドレスの上位4ビットは固定で1001です。下位3ビットは対応するピン(A2~A0)で設定可能です。 今回の例では全てGNDに接続したので、A2~A0は全て0になります。

images/data_formats/pcf8591/address_byte.svg

図5.16 PCF8591 アドレスバイト


コントロールバイトのフォーマットを示します。 AOEを1にするとD/A出力が有効になります。 AISEL1~0はA/D入力のモードを指定します。両方0でシングルエンド入力となります。 AINCは1にするとオートインクリメントが有効になります。 CH1~0はA/D入力のチャンネル0~3を2進数で指定します。

images/data_formats/pcf8591/control_byte.svg

図5.17 PCF8591 コントロールバイト


A/D入力値、D/A出力値のフォーマットを示します。 どちらも1バイトに8ビットのデータがそのまま入っています。

images/data_formats/pcf8591/data_byte.svg

図5.18 PCF8591 データバイト


[注記]サンプリング・A/D変換が行われるタイミング

PCF8591では、ACKの後にサンプリングが行われ、データバイトの読み出し中にA/D変換がおこなわれます。 そのため、通信の最初のデータバイトで転送される値は、前回の通信中に変換された値となります。 また、電源投入後の最初のデータバイトで転送される値は0x80となります。 今回使用するドライバでは、対策として電源投入後やコントロールバイト変更後は2回読み出しています。

5.3. I/Oエクスパンダー(PCF8574)を使用する

ここでは、I2CバスにI/Oエクスパンダーを接続する方法を紹介します。

使用するデバイスは以下のとおりです。

  • PCF8574(NXP Semiconductors製)

今回使用するPCF8574は、以下の特長を持ちます。

  • 単電源動作(2.5~6V)
  • I2C接続(スタンダードモード)
  • アドレス 0x20~0x27(同一バスに8つ接続可能)
  • GPIO数 8
  • 入出力方向の設定不要
  • 入力変化割り込み機能あり

5.3.1. 接続方法

Armadillo-640との接続を示します。 Armadillo-640のCON14から出ているI2C4にPCF8574を接続します。 アドレスを指定するA0~A2は全てGNDに接続しておきます[12]。 例として、スイッチやLEDを接続しています。 スイッチはオンでLow入力になるようにし、LEDはLow出力で点灯するようにします。

I^2^C接続I/Oエクスパンダー回路図

図5.19 I2C接続I/Oエクスパンダー回路図


5.3.2. 対応カーネルイメージの作成

PCF8574のドライバを有効にしたLinuxカーネルと、DTBを作成します。

標準状態のカーネルのソースコードを元に変更する手順は次の通りです。

  1. Device Treeの編集
  2. カーネルコンフィギュレーションでのデバイスドライバの有効化
  3. カーネルとDTBをビルドしArmadilloに書き込み

はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-i2c4.dtsiです(「サンプルソースコード」のページからダウンロードできます)。

&iomuxc {
        pinctrl_i2c4: i2c4grp {
                fsl,pins= <
                        MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x40010808
                        MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x40010808
                >;
        };
};

&i2c4 {
        status = "okay";
        clock-frequency = <50000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c4>;

        pcf8574@20 {                            // 1
                #address-cells = <2>;
                #size-cells = <0>;
                compatible = "nxp,pcf8574";
                reg = <0x20>;                   // 2
                gpio-controller;
                #gpio-cells = <2>;
        };
};

図5.20 armadillo-640-i2c4.dtsi


1

デバイス名@スレーブアドレス(16進表記)

2

スレーブアドレス(16進表記)

さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。

#include "armadillo-640-lcd70ext-l00.dtsi"
#endif
#include "armadillo-640-i2c4.dtsi"        //追加行

/ {
        model = "Atmark Techno Armadillo-640";

図5.21 armadillo-640.dts


続いて「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。

[ATDE ~/linux-4.14-at[version]]$ make ARCH=arm menuconfig

図5.22 menuconfigの実行


Device Drivers  --->
  -*- GPIO Support  --->
    I2C GPIO expanders  --->
          [*] PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders   ← 有効にする

図5.23 menuconfig


変更を加え、カーネルコンフィギュレーションを確定してください。

以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。

5.3.3. 使用例

まず、GPIOクラスディレクトリを作成します。

[armadillo ~]# ls /sys/class/gpio/
export     gpiochip128  gpiochip504  gpiochip96
gpiochip0  gpiochip32   gpiochip64   unexport
[armadillo ~]# echo 504 > /sys/class/gpio/export
[armadillo ~]# echo 505 > /sys/class/gpio/export
[armadillo ~]# echo 506 > /sys/class/gpio/export
[armadillo ~]# echo 507 > /sys/class/gpio/export
[armadillo ~]# echo 508 > /sys/class/gpio/export
[armadillo ~]# echo 509 > /sys/class/gpio/export
[armadillo ~]# echo 510 > /sys/class/gpio/export
[armadillo ~]# echo 511 > /sys/class/gpio/export
[armadillo ~]# ls /sys/class/gpio/
export   gpio506  gpio509  gpiochip0    gpiochip504  unexport    ←gpio504~gpio511が作成された
gpio504  gpio507  gpio510  gpiochip128  gpiochip64
gpio505  gpio508  gpio511  gpiochip32   gpiochip96
[armadillo ~]# cat /sys/class/gpio/gpio504/direction
in                                                               ←初期状態では入力

図5.24 GPIOクラスディレクトリ作成コマンド実行例


次に、実際にPCF8574のGPIOにアクセスし、LEDを点灯させてみます。

[armadillo ~]# cat /sys/class/gpio/gpio504/direction
in                                                               ←初期状態では入力
[armadillo ~]# echo high > /sys/class/gpio/gpio504/direction     ←highに設定してもLED1は消灯のまま
[armadillo ~]# echo low > /sys/class/gpio/gpio504/direction      ←lowに設定するとLED1が点灯
[armadillo ~]# echo 1 > /sys/class/gpio/gpio504/value            ←1に設定するとLED1が消灯
[armadillo ~]# echo 0 > /sys/class/gpio/gpio504/value            ←0に設定するとLED1が点灯

図5.25 出力コマンド実行例


最後に、スイッチの状態を取得してみます。

[armadillo ~]# cat /sys/class/gpio/gpio505/value                 ←スイッチがONの時に実行
0
[armadillo ~]# cat /sys/class/gpio/gpio505/value                 ←スイッチがOFFの時に実行
1

図5.26 入力コマンド実行例


5.3.4. プロトコル

PCF8574のデータには2種類あります。

表5.3 PCF8574のデータバイト

データ名 データ方向

GPIO出力値

W

GPIO入力値

R


GPIO出力値の書き込みは以下のように行います。

images/data_formats/pcf8574/write_seq.svg

図5.27 PCF8574 通信フォーマット(書き込み)


GPIO入力値の読み出しは以下のように行います。

images/data_formats/pcf8574/read_seq.svg

図5.28 PCF8574 通信フォーマット(読み出し)


PCF8574のアドレスバイトのフォーマットを示します。 7ビットアドレスの上位4ビットは固定で0100です。下位3ビットは対応するピン(A2~A0)で設定可能です。 今回の例では全てGNDに接続したので、A2~A0は全て0になります。

images/data_formats/pcf8574/address_byte.svg

図5.29 PCF8574 アドレスバイト


GPIO出力値、GPIO入力値のフォーマットを示します。 各ビットはピンP7~P0にそのまま対応します。 GPIO出力値で0を書き込むと、Low出力になり、1を書き込むと、High出力になります。 High出力は弱いプルアップとなっており、入力も兼ねています。 そのため、図5.19「I2C接続I/Oエクスパンダー回路図」のようにスイッチはオンでLow入力になるようにし、 LEDはLow出力で点灯するようにします。

images/data_formats/pcf8574/data_byte.svg

図5.30 PCF8574 データバイト


5.4. 温度湿度センサー(HDC1080)を使用する

ここでは、I2Cバスに温度湿度センサーを接続する方法を紹介します。

使用するデバイスは以下のとおりです。

  • HDC1080(Texas Instruments製)

今回使用するHDC1080は、以下の特長を持ちます。

  • 単電源動作(2.7~5.5V)
  • I2C接続(ファストモード)
  • アドレス 0x40
  • 測定範囲 温度: -40~125℃ 湿度: 0~100%RH
  • 精度 温度: 0.2℃ 湿度: 2%RH
  • 分解能 温度: 最大14ビット 湿度: 最大14ビット

5.4.1. 接続方法

Armadillo-640との接続を示します。 Armadillo-640のCON14から出ているI2C4にHDC1080を接続します。

I^2^C接続温度湿度センサー回路図

図5.31 I2C接続温度湿度センサー回路図


5.4.2. 対応カーネルイメージの作成

HDC1080のドライバを有効にしたLinuxカーネルと、DTBを作成します。

標準状態のカーネルのソースコードを元に変更する手順は次の通りです。

  1. Device Treeの編集
  2. カーネルコンフィギュレーションでのデバイスドライバの有効化
  3. カーネルとDTBをビルドしArmadilloに書き込み

はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-i2c4.dtsiです(「サンプルソースコード」のページからダウンロードできます)。

&iomuxc {
        pinctrl_i2c4: i2c4grp {
                fsl,pins= <
                        MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x40010808
                        MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x40010808
                >;
        };
};

&i2c4 {
        status = "okay";
        clock-frequency = <50000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c4>;

        hdc1080@40 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "ti,hdc1080";
                reg = <0x40>;
        };
};

図5.32 armadillo-640-i2c4.dtsi


さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。

#include "armadillo-640-lcd70ext-l00.dtsi"
#endif
#include "armadillo-640-i2c4.dtsi"        //追加行

/ {
        model = "Atmark Techno Armadillo-640";

図5.33 armadillo-640.dts


続いて「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。

[ATDE ~/linux-4.14-at[version]]$ make ARCH=arm menuconfig

図5.34 menuconfigの実行


Device Drivers  --->
  [*] Industrial I/O support  --->                              ← 有効にする
    Humidity sensors  --->
      [*] TI HDC100x relative humidity and temperature sensor   ← 有効にする

図5.35 menuconfig


変更を加え、カーネルコンフィギュレーションを確定してください。

以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。

5.4.3. 使用例

実際に、HDC1080から値の取得をおこなう手順を説明します。

[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_humidityrelative_scale
0.001525878
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_humidityrelative_raw
25296                                                       ←湿度:38.6%
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_humidityrelative_raw
48136                                                       ←湿度:73.4%
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_temp_offset
-15887.515151
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_temp_scale
2.517700195
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_temp_raw
25296                                                       ←温度:23.687℃
[armadillo ~]# cat /sys/bus/iio/devices/iio\:device0/in_temp_raw
28448                                                       ←温度:31.623℃

図5.36 コマンド実行例


湿度(%)は以下の式で求められます。

in_humidityrelative_raw × in_humidityrelative_scale
= 25296 × 0.001525878
= 38.598609888

図5.37 湿度の計算


温度(1/1000℃)は以下の式で求められます。

(in_temp_raw + in_temp_offset) × in_temp_scale
= (25296 + (-15887.515151) ) × 2.517700195
= 23687.744138981845555

図5.38 温度の計算


5.4.4. プロトコル

HDC1080のアドレスバイトのフォーマットを示します。 7ビットアドレスは固定で1000000です。

images/data_formats/hdc1080/address_byte.svg

図5.39 HDC1080 アドレスバイト


HDC1080には16ビットのレジスタが8個あります。 ポインターの書き込みによってレジスタを指定してアクセスします。

表5.4 HDC1080のレジスタ

ポインター レジスタ名 データ方向

0x00

Temperature(温度)

R

0x01

Humidity(湿度)

R

0x02

Configuration

R/W

0xFB~FD

Serial ID(40ビット)

R

0xFE

Manufacturer ID

R

0xFF

Device ID

R


温度の読み出しは以下のように行います。 ポインター(0x00)の書き込みで温度の取得が開始されるため、6.5ms以上待ってから読み出しを行います。 データは14ビットなので、下位2ビットが0埋めになっています。湿度も同様に、ポインター(0x01)の書き込み後に読み出します。

images/data_formats/hdc1080/read_temp.svg

図5.40 HDC1080 通信フォーマット(読み出し)


コンフィグレーションの書き込みは以下のように行います。

images/data_formats/hdc1080/write_config.svg

図5.41 HDC1080 通信フォーマット(書き込み)


コンフィグレーションレジスタのフォーマットを示します。 デバッグを行う上であまり重要ではないため、各ビットの説明は省きます。

images/data_formats/hdc1080/config_reg.svg

図5.42 HDC1080 コンフィグレーションレジスタ


5.5. VOCsセンサー(CCS811)を使用する

ここでは、I2CバスにVOCsセンサーを接続する方法を紹介します。

使用するデバイスは以下のとおりです。

  • CCS811(ams AG製)

今回使用するCCS811は、以下の特長を持ちます。

  • 単電源動作(1.8~3.3V)
  • I2C接続(ファストモード)
  • アドレス 0x5A~0x5B(同一バスに2つ接続可能)
  • VOCs(揮発性有機化合物)、CO2の濃度を測定
  • VOCs: 0~1156ppb[13]
  • CO2: 400~7992ppm[13]
  • 屋内用

5.5.1. 接続方法

Armadillo-640との接続を示します。 Armadillo-640のCON14から出ているI2C4にCCS811を接続します。 アドレスを指定するADDRはGNDに接続しておきます[14]

I^2^C接続VOCsセンサー回路図

図5.43 I2C接続VOCsセンサー回路図


5.5.2. 対応カーネルイメージの作成

CCS811のドライバを有効にしたLinuxカーネルと、DTBを作成します。

標準状態のカーネルのソースコードを元に変更する手順は次の通りです。

  1. Device Treeの編集
  2. カーネルコンフィギュレーションでのデバイスドライバの有効化
  3. カーネルとDTBをビルドしArmadilloに書き込み

はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-i2c4.dtsiです(「サンプルソースコード」のページからダウンロードできます)。

&iomuxc {
        pinctrl_i2c4: i2c4grp {
                fsl,pins= <
                        MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x40010808
                        MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x40010808
                >;
        };
};

&i2c4 {
        status = "okay";
        clock-frequency = <50000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c4>;

        ccs811@5A {                             // 1
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "ccs811";
                reg = <0x5A>;                   // 2
        };
};

図5.44 armadillo-640-i2c4.dtsi


1

デバイス名@スレーブアドレス(16進表記)

2

スレーブアドレス(16進表記)

さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。

#include "armadillo-640-lcd70ext-l00.dtsi"
#endif
#include "armadillo-640-i2c4.dtsi"        //追加行

/ {
        model = "Atmark Techno Armadillo-640";

図5.45 armadillo-640.dts


続いて「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。

[ATDE ~/linux-4.14-at[version]]$ make ARCH=arm menuconfig

図5.46 menuconfigの実行


Device Drivers  --->
  [*] Industrial I/O support  --->       ← 有効にする
    Humidity sensors  --->
      [*] AMS CCS811 VOC sensor          ← 有効にする

図5.47 menuconfig


変更を加え、カーネルコンフィギュレーションを確定してください。

以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。

5.5.3. 使用例

実際に、CCS811から値の取得をおこなう手順を説明します。 VOCs濃度(ppb)、CO2濃度(ppm)が出力されます。

[armadillo ~]# cat /sys/class/i2c-dev/i2c-3/device/3-005a/iio\:device0/in_concentration_voc_raw
53
[armadillo ~]# cat /sys/class/i2c-dev/i2c-3/device/3-005a/iio\:device0/in_concentration_voc_raw
1156                                                            ←息を吹きかけるとVOCs濃度が上がる
[armadillo ~]# cat /sys/class/i2c-dev/i2c-3/device/3-005a/iio\:device0/in_concentration_co2_raw
751
[armadillo ~]# cat /sys/class/i2c-dev/i2c-3/device/3-005a/iio\:device0/in_concentration_co2_raw
7992                                                            ←息を吹きかけるとCO2濃度が上がる

図5.48 コマンド実行例


5.5.4. プロトコル

CCS811のアドレスバイトのフォーマットを示します。 アドレスの上位6ビットは固定で101101です。

images/data_formats/ccs811/address_byte.svg

図5.49 CCS811 アドレスバイト


CCS811にはレジスタが14個あります。 ポインターの書き込みによってレジスタを指定してアクセスします。 レジスタのバイト数はそれぞれ異なります。 ここでは重要なレジスタのみ紹介します。

表5.5 CCS811のレジスタ

ポインター レジスタ名 バイト数 データ方向

0x00

STATUS

1

R

0x02

ALG_RESULT_DATA

8

R


STATUSレジスタの読み出しは以下のように行います。

images/data_formats/ccs811/read_status.svg

図5.50 CCS811 通信フォーマット(STATUS読み出し)


CO2やVOCsの濃度の読み出しは以下のように行います。

images/data_formats/ccs811/read_results.svg

図5.51 CCS811 通信フォーマット(ALG_RESULT_DATA読み出し)


STATUSレジスタのフォーマットを示します。

images/data_formats/ccs811/status_reg.svg

図5.52 CCS811 STATUSレジスタ


読み出されていないデータがあるとき、DATA_READYが1になります。 今回使用したドライバでは、DATA_READYが1になるまで待ち、新しいデータが用意された後に濃度を読み出します。



[7] I2CやIICと表記される場合もあります。アイ・スクエア(ド)・シーやアイ・ツー・シーと読みます。

[8] I2Cの「モード」は、デバイスが対応している通信速度を表します。

[9] マスターは1つのみにする場合が多いです。

[10] アドレスはデバイスの型番により異なります。アドレスを設定ピンによって変更し、複数の同じデバイスで別のアドレスを持つことができるデバイスもあります。

[11] 複数のスレーブをバスに接続する場合は、A0~A2の設定を変えてアドレスが重複しないようにしてください。

[12] 複数のスレーブをバスに接続する場合は、A0~A2の設定を変えてアドレスが重複しないようにしてください。

[13] 動作確認時に表示された値

[14] 複数のスレーブをバスに接続する場合は、ADDRの設定を変えてアドレスが重複しないようにしてください。