CQ_I2C_book


We are the team of "I2C sample book" by CQ publishing

class_libraries

I2Cサンプルブック対応クラスライブラリ

クラスライブラリとは

さまざまなクラスライブラリ

mbedでは部品(外付け部品やソフトウェア部品)を便利に使うために,部品用のクラスライブラリが提供されています.
mbed-SDK(mbedライブラリ)で提供されるDigitalOutもこのクラスライブラリのひとつで,マイコン基板のあるピンをインスタンスとして宣言し,変数のように操作できる便利さはmbedユーザの誰もが知るものでしょう.

I2Cサンプルブックでは,これと同様な使い勝手を提供するため,いくつかの部品用のクラスライブラリを用意しました.これを使うことにより,サンプルブックに入っていた部品を,その仕様書を詳しく読まなくても使ってみることができるようにしています.

ここでは,基本機能だけではありますが,便利に使えるように用意したクラスライブラリを紹介します.

使いかた

サンプルプログラムとライブラリ

用意されているクラスライブラリ

サンプルブック用に用意したクラスライブラリのリストを下に示します.
この他にも別のユーザが公開しているクラスライブラリも多数存在します.ただ部品用のクラスライブラリは,それぞれ独自の書き方で書かれているため,使い方やサポートしている機能なども,それによっていろいろです.

以下のリストは,使い方などをある程度統一したライブラリとなっています.

種類デバイス名クラスライブラリ
温度センサLM75B/components/PCT2075-LM75B-I2C-temp-sensor-with-1-deg/
温度センサPCT2075/components/PCT2075-LM75B-I2C-temp-sensor-with-1-deg/
GPIOエキスパンダ (8bit)PCAL9554B/components/PCAL9555-PCAL9554-16-8-bit-GPIO-expander/
GPIOエキスパンダ (16bit)PCAL9555A/components/PCAL9555-PCAL9554-16-8-bit-GPIO-expander/
LEDコントローラ (PWM制御 4ch)PCA9632/components/PCA9632-4ch-LED-driver-voltage-switch-ty/
LEDコントローラ (PWM制御 8ch)PCA9624/components/PCA9622-PCA962-PCA9626-8-16-24ch-LED-dri/
LEDコントローラ (PWM制御 16ch)PCA9622/components/PCA9622-PCA962-PCA9626-8-16-24ch-LED-dri/
LEDコントローラ (PWM制御 24ch)PCA9626B/components/PCA9622-PCA962-PCA9626-8-16-24ch-LED-dri/
LEDコントローラ (PWM・電流制御 16ch)PCA9955A/components/PCA9955A-PCA9956A-16-24-channel-constant/
LEDコントローラ (PWM・電流制御 24ch)PCA9956A/components/PCA9955A-PCA9956A-16-24-channel-constant/
I2CバススイッチPCA9546A/components/PCA9546A/
ステッピングモータ・コントローラPCA9629A/components/PCA9629A-Stepper-motor-controller/
リアルタイム・クロックPCF2129AT/components/PCF2127-High-accuracy-RTC-module/


サンプルプログラムを使ってみる

上の表の「クラスライブラリ」の列にはコンポーネントページへのリンクが用意されています.このリンクをクリックし,各ページに用意されているサンプルコードのImport programボタンを押せば,自分のコンパイラページに取り込まれ,すぐに使ってみることができます.

デバイスとmbedの接続は,各コンポーネントページやサンプルコード/ライブラリ公開ページの図を参考にしてください.

Information

サンプルブックに入っている全てのデバイスとそのクラスライブラリ対応リストはこちらを参照



ライブラリの応用

応用例(1):複数のデバイスを使う

ライブラリを単独でインポートして使うことも可能です.既存のプログラムに部品を追加して使う場合などに,この方法が有効です.
ライブラリは一度プログラム内にインポートしておけば,複数のインスタンスを作ることもできます.複数接続した各デバイスにそれぞれのインスタンスを作成して,それを介して操作を行います

次のコードはmbedのp28,p27に接続したPCT2075(温度センサ)を4個使う例です.それぞれのセンサから個別のデータを読むために,温度センサ・デバイスのピン(A0〜A2)の設定を変えて個別のスレーブアドレスを持たせています.

#include "mbed.h"
#include "PCT2075.h"

PCT2075 temp_sensor0( p28, p27, 0x90 ); // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
PCT2075 temp_sensor1( p28, p27, 0x92 ); // スレーブアドレス=0x92 (A2=Low,  A1=Low,  A0=High)
PCT2075 temp_sensor2( p28, p27, 0x94 ); // スレーブアドレス=0x94 (A2=Low,  A1=High, A0=Low )
PCT2075 temp_sensor3( p28, p27, 0x96 ); // スレーブアドレス=0x96 (A2=Low,  A1=High, A0=High)

int main()
{
    while(1) {
        printf( "temp sensor 0 = %7.3f\r\n", (float)temp_sensor0 );
        printf( "temp sensor 1 = %7.3f\r\n", (float)temp_sensor1 );
        printf( "temp sensor 2 = %7.3f\r\n", (float)temp_sensor2 );
        printf( "temp sensor 3 = %7.3f\r\n", (float)temp_sensor3 );
        wait( 1 );
    }
}


このプログラムは配列を使って次のように書くことも可能です.
この方法なら,各インスタンスは配列の要素としてアクセス可能になるため,よりシンプルなコードが書けます.

#include "mbed.h"
#include "PCT2075.h"

PCT2075 temp_sensor[]   = {
    PCT2075( p28, p27, 0x90 ), // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
    PCT2075( p28, p27, 0x92 ), // スレーブアドレス=0x92 (A2=Low,  A1=Low,  A0=High)
    PCT2075( p28, p27, 0x94 ), // スレーブアドレス=0x94 (A2=Low,  A1=High, A0=Low )
    PCT2075( p28, p27, 0x96 )  // スレーブアドレス=0x96 (A2=Low,  A1=High, A0=High)
};

int main()
{
    while(1) {
        for ( int i = 0; i < 4; i++ ) {
            printf( "temp sensor %d = %7.3f\r\n", i, (float)temp_sensor[ i ] );
        }
        wait( 1 );
    }
}



応用例(2):I2CのSCLクロック周波数を変更する

このページで紹介している全てのクラスライブラリは,mbed-SDKで用意されているI2Cクラスが持つデフォルトのSCLクロック周波数で動作します.
ちなみに「SCL」とは2線式のI2Cバスのクロック信号(SerialCLock)で,最も初期のI2C規格の上限であった100kHzがデフォルトの周波数として設定されます. このクロック周波数を変更する場合にはライブラリの中身を書き換えてしまうのもひとつの方法です.しかし複数の部品クラスライブラリを使っている場合に,これらを個々に描き直すのは手間です. そこで,ここで紹介しているクラスライブラリでは,それを簡単に行う方法が用意されています.

各部品クラスライブラリのインスタンスの宣言方法にはmbedのI2Cピン名を指定する方法の他に,I2Cインスタンスを渡す方法も用意されています.

たとえば次のコードはmbedのp28,p27のI2Cに2個のPCT2075,1個のPCAL9555を接続して使う例で,「ピン名」によるインスタンス宣言が行われていますが..

#include "mbed.h"
#include "PCT2075.h"
#include "PCAL9555.h"

PCT2075     temp_sensor0( p28, p27, 0x90 ); // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
PCT2075     temp_sensor1( p28, p27, 0x92 ); // スレーブアドレス=0x92 (A2=Low,  A1=Low,  A0=High)
PCAL9555    gpio( p28, p27 );               // (デフォルト)スレーブアドレス=0x40 (A2=Low,  A1=Low,  A0=Low )

int main()
{
    gpio.configure( 0x0000 ); // 全てのIOピンを出力に

    while(1) {
        if ( temp_sensor0 < temp_sensor1 ) {
            gpio.write( 0x00FF );
        } else {
            gpio.write( 0xFF00 );
        }
        wait( 1 );
    }
}


このコードは次のようにも書くことも可能です.

...
I2C         i2c( p28, p27 );
PCT2075     temp_sensor0( i2c, 0x90 ); // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
PCT2075     temp_sensor1( i2c, 0x92 ); // スレーブアドレス=0x92 (A2=Low,  A1=Low,  A0=High)
PCAL9555    gpio( i2c );               // (デフォルト)スレーブアドレス=0x40 (A2=Low,  A1=Low,  A0=Low )
...


このコードでI2Cクラスのインスタンスi2cに変更を加えれば,SCLクロック周波数の変更が簡単に行えます.

下のコードはPCT2075とPCAL9555のインスタンスの作成をピン名ではなくI2Cインスタンスを使って行っている例です.
12行目を見るとi2c.frequency( 400 * 1000 );でSCLクロック周波数が400kHzに変更されています.
このような方法でPCT2075とPCAL9555が繋がれたI2Cバスの周波数を簡単に変更することが可能です.

#include "mbed.h"
#include "PCT2075.h"
#include "PCAL9555.h"

I2C         i2c( p28, p27 );
PCT2075     temp_sensor0( i2c, 0x90 ); // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
PCT2075     temp_sensor1( i2c, 0x92 ); // スレーブアドレス=0x92 (A2=Low,  A1=Low,  A0=High)
PCAL9555    gpio( i2c );               // (デフォルト)スレーブアドレス=0x40 (A2=Low,  A1=Low,  A0=Low )

int main()
{
    i2c.frequency( 400 * 1000 ); // SCL周波数を400kHzに変更
    gpio.configure( 0x0000 );    // 全てのIOピンを出力に

    while(1) {
        if ( temp_sensor0 < temp_sensor1 ) {
            gpio.write( 0x00FF );
        } else {
            gpio.write( 0xFF00 );
        }
        wait( 1 );
    }
}


注意:まぜるな危険

各デバイスのインスタンス宣言の方法は,同一プログラム内では統一しておくほうが良いでしょう.
たとえば次のコードのような宣言を行うと..

...
I2C         i2c( p28, p27 );
PCT2075     temp_sensor0( i2c, 0x90 ); // スレーブアドレス=0x90 (A2=Low,  A1=Low,  A0=Low )
PCAL9555    gpio( p28, p27 );          // (デフォルト)スレーブアドレス=0x40 (A2=Low,  A1=Low,  A0=Low )

int main()
{
    i2c.frequency( 400 * 1000 ); // SCL周波数を400kHzに変更
    ...


PCT2075へのアクセスは400kHzで行われますが,PCAL9555へのアクセスはデフォルトの100kHzのままとなります.
これはgpioの内部に別のI2Cインスタンスが作成されるためです.
mbed-SDKでは同一機能に複数のインスタンスが作られた場合(たとえばこの例の場合,p27,p28を使うI2C機能に2つのインスタンスが作成された),それぞれのインスタンスを介した操作は,個別に持っている設定が反映されるようになっています.
もちろん,意図的にこのような使い方をするのであれば何も問題はありません

この仕組みについての詳細はこのページからリンクされている資料の31ページ付近からの解説をご覧ください.



応用例(3):GPIOエキスパンダ,LEDコントローラ用 APIについて

GPIOエキスパンダとLEDコントローラでは,デバイスを抽象化し,ピン名を定義できるようにした高水準APIが用意されています.
このAPIについてはこちらのページ:『I2Cサンプルブック対応クラスライブラリ:GPIOエキスパンダ,LEDコントローラ用 高水準API』を参照ください.



参考

各クラスライブラリのAPIについて

各部品クラスライブラリのAPIについては,クラスライブラリ公開ページの API Documentation が参考になります.
コンポーネント・ページからAPIドキュメントへは,下図のようなリンクを辿ることでアクセスできます.

/media/uploads/okano/api_document_page2.png
APIドキュメントの表示

自身でクラスライブラリを書くには?

部品クラスライブラリの作り方〜コンポーネントページヘの登録については,次のページ『ライブラリ・コンポーネントの作りかた』が参考になると思います.

またより実際的なクラスライブラリの作成方法については,次のページ『「トラ技_mbedライブラリの作成方法の勉強会」資料』からリンクされているpdf資料が役に立つかもしれません.
この資料にはコンポーネント・インスタンスを宣言する際の,ピン名/I2Cインスタンスを渡す方法などについての解説も含まれています.