電子ペーパーモジュールクリックボード[CLICK-EINK]簡易ガイド

電子ペーパーモジュールクリックボード(CLICK-EINK)は、SSD1606コントローラー互換の電子ペーパーEPA-20を採用したボードです。

電子ペーパーの最大の特徴は電源を切断しても表示内容を保持できることにあります。よって使用しないときは電源を切断し、表示更新時のみ電源を与えればよいので超低消費電力のアプリケーションが作れます。また表示更新時も約40mW程度です。

採用している電子ペーパーEPA-20は、172×72ドット、2インチで高コントラスト、広視野角、白黒4スケールで使いやすさに定評があります。

制御はSSD1606に準拠した4線式SPI通信で、マイコン等のホスト機器から制御します。

mikroBUSはマイコンボード共通のクリックボード装着用コネクタの規格でPICマイコンを初めARMマイコン用ボードなど様々な開発ボードで採用されている共通規格です。mikroBUS規格に対応したクリックボードを装着すれば様々な機能をマイコンボードに付加することができます。


■ピンアサイン

ピンアサインはmikroBUSに準拠しています。

信号線はSPI通信のMOSIとクロック線、チップセレクト、その他にD/C線、Busy線を使います。ホスト機器はArduinoやPICマイコン、ARMの各種マイコン等SPIホストになる機器でれば何でも使用できます。

電源は3.3Vです。


■SPI通信例

SPI通信のサンプル例、初期化例はEPA-20のデータシート2ページ~3ページにかけて記載されています。

当方で販売しているCコンパイラ、mikroCシリーズをお使いの場合にはSPI通信のコマンド内容を意識せずにも使えるライブラリーが配布されています。Libstockからダウンロードできます。このライブラリを使えば電子ペーパーの初期化ができる他、文字や画像の表示が簡単に行えます。プログラム例は下記の通りです。

 

01 void main()
02 {
03     sysinit();
04     eink_init();
05     Delay_ms( 1000 );
06 
07     while( 1 )
08     {
09         // Display black letters on white background
10         eink_fill_screen( EINK_COLOR_WHITE );
11         eink_set_font( guiFont_Exo_2_Condensed21x32_Regular, EINK_COLOR_BLACK, FO_HORIZONTAL );
12         eink_text( "EINK", 14, 50 );
13         delay_ms( 3000 );
14         
15         // Display white letters on black background
16         eink_fill_screen( EINK_COLOR_BLACK );
17         eink_set_font( guiFont_Exo_2_Condensed21x32_Regular, EINK_COLOR_WHITE, FO_HORIZONTAL );
18         eink_text( "EINK", 14, 50 );
19         Delay_ms( 3000 );
20         
21         // Display external image
22         eink_image_bmp( _mikroe_bmp );
23         Delay_ms( 3000 );
24     }
25 }

 

mikroC以外の環境でSPIホストを作る場合には、それぞれ環境に応じてプログラミングをします。例はデータシートにありますので参考にしてください。なお、SSD1606自体は有名なコントローラーなので、ネットで “SSD1606 Library”や”SSD1606 Arduino”等で検索すると、ライブラリ例が多数表示されますので、検索してお使いになると簡単です。

 

当方で実際のSPI通信を観察したデータを下記に示します。図の波形は最初の初期化部分の最初の4バイトを表示しています。各信号線の状態を参考にしてください。

※本デバイスにMISO線はありません。(スレーブデバイス側からの出力はないため)そのため表示ではすべて00になっていますので無視してください。

なお、下図の様に画面に”1234″という数字画像の表示を行った場合のMOSI全通信データをCSV形式でこちらからダウンロードできます。初期化から画像データの転送まですべてのデータを確認して頂けます。

 


■画像データ・フォントデータの作成.

電子ペーパー本体にはフォントデータは内蔵されていません。よって、数字やローマ字、日本語等の文字はすべて文字ではなく画像データとして本体にSPIで送信する必要があります。

その他の画像データも同様です。画像データは172×72ドットの座標データとして本体に送ります。本体にはディスプレイRAMがありそこにイメージデータを格納します。RAMのサイズは各RAMあたり128×180×2ビットです。RAMのマップアドレスはSSD1606のデータシート19ページを参照してください。

表示させたい画像は、座標データとしてコンパイラで使います。ビットマップ画像から座標データを出力するツールは色々とリリースされていますが、当方では実績のあるフリーソフト、Resources Creatorをおすすめしています。

このソフトでは172×72ドットの24ビットビットマップ形式で作成されたビットマップデータを座標データとして配列データとして出力します。コンパイラでヘッダファイル等にコピー&ペーストして使うことでマイコンから画像データを表示させるのに便利です。また、Windowsのフォントデータを座標データに変換する機能もあります。

Windows標準のペイントを使って画像データを作る場合には次の手順で操作してください。

 

1.Windowsのペイントでビットマップ画像データを作成する場合にはサイズを水平方向72ピクセル、垂直方向172ピクセルとして縦長の画像ファイルを作ります。

2.ペイントで画像ファイルを作ったら、24ビットビットマップ形式で保存します。「ファイル」→「名前を付けて保存」をクリックし、「ファイルの種類」を「24ビット ビットマップ」として保存してください。

3.Resources Creatorを起動します。ウインドウ下にある「Bitmap」タブを選択します。

4.メニューバーの「File」→「Import Bitmap Image」をクリックして手順2で保存したビットマップファイルを開いてください。

5.画面下に”Width 72″ “Height 172” “Bitmap Format 24bit”と表示されていることを確認します。

6.メニューバーの「File」→「Create File .c Bitmap」をクリックして拡張子.cのファイルを生成します。

7.ファイルを開くと座標データがありますので、お使いのSPIホストを作成しているコンパイラのソースプログラムに貼り付けてお使いください。

なお、mikroCをお使いの場合には配列の型を 「const uint8_t」としてください。また、配列の要素数は24768としてください。さらにResources Creatorで作った配列データの先頭にある下記の6バイトは削除してください。

0x00,0x10,
0xAC,0x00,
0x48,0x00,
例:

const uint8_t image_bmp[24768] = { ….. }

 

 

wpmaster

Si4703採用 FMラジオチューナークリック [CLICK-FM]

Si4703採用 FMラジオチューナークリック (CLICK-FM)は、シリコンラボラトリーズ社製のワンチップFMラジオチューナーIC、Si4703を搭載したFMラジオ受信ができるクリックボード(※1)です。電源電圧は3.3Vです。

※1:クリックボードは、mikroBUS規格のインターフェースを搭載した様々な機能性ボードの総称です。

制御は同期式シリアル通信のI2Cで行います。SCL及びSDA線はいずれも4.7kオームの抵抗でプルアップされています。

76MHz~108MHzのFM波を受信して復調することができます。出力段には2つの300mWオペアンプLM4864を搭載しており十分な音声レベルの出力を得ることができます。

Si4703はボリュームコントロール機能があるので、I2C通信で音声出力のレベルを設定できます。通常は-28dBから0dBまで指定できます。なおVOLEXTレジスタを1にセットすると-58dBから-30dBの範囲で指定できるようになります。

本体には3.5mm径のステレオジャックが搭載されています。ここに1m程度のイヤホンケーブル等を接続すると、その線がアンテナ線として機能します。必ずイヤホンやスピーカーケーブルを接続してご使用ください。

 

  • ワールドワイドなFMバンド設定、76~108MHz
  • シークチューニング機能
  • 自動ゲインコントロール(ACG)内蔵
  • 優れた過負荷耐性
  • アダプティブノイズサスペンション機能
  • 自動周波数コントロール機能
  • 電子ボリューム機能
  • LM4864オペアンプ搭載 (L,R両方)
  • アンテナ兼用の3.5mmイヤホンジャック
  • I2C通信による制御(2線式か3線式かの選択可能)
  • 電源電圧は3.3V

 

使い方の詳細はSi4703のデータシートをお読み下さい。


■本体回路図

クリックして拡大できます。


■インターフェイス端子(mikroBUS規格)

 

機能詳細 ピン名 Mikrobus logo.png ピン名 機能詳細
Si4703のGPIO2へ  GPIO2 1 AN PWM 16 NC
#リセットピン  #RST 2 RST INT 15 GPIO1 Si4703のGPIO1へ 
#セレクトイネーブル #SEN 3 CS TX 14 NC
NC 4 SCK RX 13 NC
NC 5 MISO SCL 12 SCL シリアルI2C クロック
NC 6 MOSI SDA 11 SDA シリアルI2C データ
+3.3V 電源入力 3.3V 7 +3.3V +5V 10 NC
Ground GND 8 GND GND 9 GND Ground

 

※NCは未使用ピンです。#記号は負論理です。

Si4703のGPIO1/2/3をデジタルLowに設定して消費電流を低減します。このレジスタ内の他のすべてのビットは、最後に読み取られた値に維持される必要があります。

 

3  #SEN 3線式の制御にした場合に使用します。2線式の場合にはSCLの立ち上がりエッジでSENピンがLレベルに設定されると転送が開始されます。データの最後では、SENピンをハイにした後、次のSCLの立ち下がりエッジで、データがラッチされます。(下図参照)

データシートの8ページ参照

11 I2C SDA I2Cスレーブデータ線 内部で4.7kオームでプルアップ済み
・7ビットI2Cスレーブアドレス:0x20 (固定)
・100KHz又は400KHz
12 I2C SCL I2Cスレーブクロック線  内部で4.7kオームでプルアップ済み
1,15 GPIO2

GPIO1

デフォルトではハイインピーダンスになっています。レジスタの設定で入出力方向及び論理を変えられます。詳しくはデータシートの14ページを参照下さい。

 


■I2C通信とレジスタ

本モジュールに搭載のを2線式で使用する場合のI2Cの7ビットスレーブアドレスは0x10に固定されています。Readで1を加算、Writeで0を加算します。

3線式の場合のタイミングダイアグラム

 

2線式の場合のタイミングダイアグラム

下記2線式での内容を解説します。(3線式についてはデータシートを参照ください。)

2線式、3線式どちらを使うかは本体電源投入時のピンの状態により決まります。2線式I2C通信を実行するには、本体の電源投入時にSDIOピン(I2CのSDAピン、11ピン)をLレベルにします。#SENピン(3ピン)をHレベルにすると、2線式になります。フローチャートは下記の通りです。(GPIO3は本ボードではGNDの方(=Noの方)に進みます)

レジスタ番地は、「Writeの場合」にはレジスタ0x02の上位バイトから始まり続いてレジスタ0x02の下位バイトとなります。そして、自動的にインクリメントされ0x03の上位バイト→下位バイト→0x04の上位バイト→下位バイト・・・と続きます。レジスタの最後の番地まで到達すると0x00に戻ります。I2Cのストップコンディションで終了と見なされます。

「Readの場合」にはレジスタ0x0Aの上位バイトから始まり続いてレジスタ0x0Aの下位バイトとなり、同様にインクリメントされます。レジスタの最後の番地まで到達すると0x00に戻ります。I2Cのストップコンディションで終了と見なされます。

 

例えばレジスタ0x07に値を書き込みたい場合には、レジスタ0x07を直接指定する方法はないので、レジスタ0x02からスタートして、10進めて(マイコンの場合には10回I2C_Writeを実行して)(0x02hの上位→下位→0x03の上位→下位・・・)0x07の上位バイトに到達して、そこから上位、下位の順番で書き込むことになります。この辺りはプログラムに工夫が必要となります。実際のプログラム例は本ページの例を参考にしてください。

レジスタ一覧は、データシートの22ページに記載があります。

 


■設定とプログラミング例

日本で使用する場合には特に0x05レジスタでバンド設定と、スペーシング設定を日本にする必要があります。

0x05レジスタの7:6ビット BAND[1:0]がバンドの国設定です。

BAND[1:0] Band select
00 87.5–108 MHz (US / Europe, Default)
01 76-108MHz(Japan wide band)
10 76-90MHz(Japan)

 

0x05レジスタの5:4ビット SPACE[1:0]がスペーシング(チャンネル間隔)の国設定です。

SPACE[1:0] Channel spacing
00 200 kHz (US / Australia, Default)
01 100kHz(Europe,Japan)
10 50kHz

 

よっていずれもレジスタの値を 01 にする必要があります。この設定を誤るとデフォルトの設定となってしまいFMラジオの受信ができません。実際の設定値はプログラム例で確認ください。

選局するFMラジオ局の周波数は、次の式で計算します。

Freq(MHz) = 0.1 x Channel + 76

最初の0.1MHzはスペーシング値、最後の76MHzはバンドの最小値となります。例えば東京の場合80.0MHzは東京FMですが、その場合には次のようになります。

80.0(MHz) = 0.1 × CH + 76

CH = 40  となるので設定値は40となります。この辺りの実装方法もプログラム例でご確認下さい。

 


プログラムのポイント

・レジスタに書き込むデータを配列として予め用意しておく。

・レジスタに書き込まれている既存の内容は新しいデータを書き込む前に一度コピーしておく。

・レジスタに値を書き込む場合には、必ず0x02レジスタから始まるので、目的のレジスタまでインクリメントする。

・レジスタの値を読む場合には、必ず0x0Aレジスタから始まるので、目的のレジスタまでインクリメントする。

・レジスタは16ビット幅なので、上位ビット→下位ビットの順で書き込む(読み込む)。

 

char powerOn, volume, i;
int freq, ChipID;
char shadowReg[32];

char stereo,str_size,flag_RDS,flag_Clock;

const char FM_all_Reg = 0x0F;
const char FM_0a0b_Reg = 0x02;

const char Si4703_address = 0x20;

void init(){

    FM_RST = 0;    
    delay_ms(1);

    FM_SEN = 1;
    delay_ms(1);
    
    FM_SDIO = 0;
    delay_ms(1);
    FM_SCLK = 0;
    delay_ms(1);

}

void modShadowReg(char reg, unsigned int value, char set_reset){

    char reg_pos;       //Index of register byte in shadow register
                        //Reading of Si4703 registers start from 0x0A-0x0F and then starts from 0x00-0x09
                            
    reg_pos = 12 + (reg << 1);  //Calculate position of register which needs to be modified

    if(set_reset == 1){         //Sets the desired bits in register
    
        shadowReg[reg_pos] = shadowReg[reg_pos] | (Hi(value));    //Split value to higher
        reg_pos++;
        shadowReg[reg_pos] = shadowReg[reg_pos] | (Lo(value));    //and lower nibble

    }else{ //Resets the desired bits in register

        shadowReg[reg_pos] = shadowReg[reg_pos] & ( ~Hi( value ) );  //Split value to higher
        reg_pos++;
        shadowReg[reg_pos] = shadowReg[reg_pos] & ( ~ Lo( value ) ); //and lower nibble
    }
}

void FM_Write(char reg, unsigned int value, char set_reset){
    
    char wr_cnt;
    char ii;

    wr_cnt = ( reg - 1 ) << 1;               //Calculate how much bytes need to be written
    modShadowReg(reg, value, set_reset);     //Modify register bytes

    I2C1_Start();
    I2C1_wr(Si4703_address);

    for(ii=16; ii<16+wr_cnt; ii++){
        I2C1_Wr(shadowReg[ii]);
    }
    I2C1_stop;
}

void FM_Read(char cmd){       //Reading of registers starts from 0x0A register
  
  char ii;

  if (cmd == FM_all_Reg){
     I2C1_Start();
     I2C1_wr(Si4703_address + 1 );
     
     for(ii=0;ii<30;ii++){
        shadowReg[ii] = I2C1_rd(1);
     }
     shadowReg[31] = I2C1_rd(0);
     I2C1_Stop;
  }
  
  if(cmd == FM_0a0b_Reg){           //Read only STATUS and READCHAN registers
     I2C1_Start();
     I2C1_wr(Si4703_address +1 );

     for(ii=0;ii<2;ii++){ shadowReg[ii] = I2C1_rd(1); } shadowReg[3] = I2C1_rd(0); I2C1_Stop; }
    }
  
    modShadowReg(0x02, 0x0300, 0);
    FM_Write(0x02, 0x0100, 0);      //Deactivate SEEK,keep

    while( STC_bit == 1 ){
        FM_Read(FM_0a0b_Reg);
        STC_bit = (shadowReg[0] & 0b01000000) >> 6;
        delay_ms(60);
    }
    
    FM_Read(FM_0a0b_Reg);
    SF_BL_bit = (shadowReg[0] & 0b00100000) >> 5;    
}

void FMClick_Init(){
    FM_RST = 1;               //Init chip done - 2wires interface car SDIO=0 et SDEN=1
    delay_ms(1);
    I2C1_Init(100000);        //Initialize I2C module for communication with FM Click board

    FM_Read(FM_all_Reg);
    ChipID = shadowReg[14] << 8;         //Save Chip ID before powerup.
    ChipID = ChipID | shadowReg[15];

    delay_ms(1);

    modShadowReg(0x07, 0x0081, 0);
    FM_Write(0x07, 0x8100, 1);           //Activate Crystal Oscillator

    delay_ms(500);

}

char FM_Activate(){
    
    unsigned int active;
    active = ChipID;
    
    FM_Read(FM_all_Reg);
    modShadowReg(0x02, 0x4801, 0);
    FM_Write(0x02, 0x4801, 1);      //Write ENABLE bit, disable Mute , RDS mode = Verbose
    delay_ms(200);
    
    while (active == ChipID){       //Wait for module powerup
        FM_Read(FM_all_Reg);
        active = shadowReg[14] << 8; 
        active = active | shadowReg[15]; 
    } 

    modShadowReg(0x04, 0xFFFF, 0);  //Write default Volume and RSSI Seek Threshold values 
    FM_Write(0x04, 0x1800, 1);      
    modShadowReg(0x05, 0xFFFF, 0);  //Write default values
    FM_Write(0x05, 0x105F, 1);      //RSSI seek Threshold = 0x10, band = Japan, Channel spacing = 100kHZ, Volume = max 
    delay_ms(110); 
    powerOn = 1;                    //Update powerOn flag 

    return shadowReg[0]; 

} 

void FM_Tune(unsigned int freq){

    unsigned int calc; 
    char STC_bit; 

    STC_bit = 0; 
    calc = freq; 
    
    calc = ((freq *10) - 7600) / 10;
    calc = calc | 0x8000;              //Set TUNE Flag
   
    if (powerON == 1){                 //Check for power state of FM click
        FM_Read(FM_0a0b_Reg); 
        modShadowReg(0x03, 0x83FF, 0); 
        FM_Write(0x03, calc, 1);       //Write modifiled frequency value + activate tune 
        delay_ms(60); 

        while (STC_bit == 0){
            FM_Read(FM_0a0b_Reg); 
            STC_bit = (shadowReg[0] & 0b01000000) >> 6;
            delay_ms(60);
        }
        
        FM_Write(0x03, 0x8000, 0);     //Set TUNE = 0
    }else{
        ModShadowReg(0x03, calc, 1);   //If power is off, only modify the shadow register
    }
 
}

void FM_Seek(char direction){
  char STC_bit, SF_BL_bit; 

    if(direction == 1){ 
        modShadowReg(0x02, 0x0300, 0); 
        FM_Write(0x02, 0x0300, 1);            //Activate SEEK direction up and Seek ON 
    }else{ 
        modShadowReg(0x02, 0x0300, 0); 
        FM_Write(0x02, 0x0100, 1);            //Activate SEEK direction down and Seek ON 
    } 
    
    STC_bit = 0; 

    while( STC_bit == 0 ){
        FM_Read(FM_0a0b_Reg); 
        STC_bit = (shadowReg[0] & 0b01000000) >> 6;
        delay_ms(60);
    }
}

void SetVolume(char vol){

    if ( ( vol >= 0 ) && ( vol <= 16) ){
        vol = vol & 0x0F;
        modShadowReg(0x05, 0x000F, 0);
        FM_Write(0x05, vol, 1);         //Write Volume value to SYSCONFIG2 register
        delay_ms(5);
    }
}
void main() {

    init();
    FMClick_Init();
    FM_activate();

    FM_Tune(800);        //80.0MHz
    
    while(1){
        if(Button(&PORTD,0,5,0)){
            FM_Seek(1);
        }

        if(Button(&PORTD,1,5,0)){
            FM_Seek(0);
        }
        
        if(Button(&PORTD,2,5,0)){
            if(volume<15){
                volume = volume + 1; 
            } 
            SetVolume(volume); 
        } 

        if(Button(&PORTD,3,5,0)){ 
            if(volume>0){
                volume = volume - 1;
            }
            SetVolume(volume);
        }
        
    }

}

 

※参考

FM変調とは?
FM変調とは、変調する信号の振幅に応じて搬送波の周波数を変化させる方法です。よって変調波の周波数は連続的に変化します。FM変調では搬送波周波数を中心として、変調信号とは違うスペクトラムが発生するので非線形変調となります。

wpmaster

MMA8491Q 3軸デジタル加速度センサークリック [CLICK-3AX]

MMA8491Q 3軸デジタル加速度センサークリック (CLICK-3AX)は、45°チルト検出器としても機能する高機能な3軸デジタル加速度センサーMMA8491Qを使用したクリックボード(※1)です。電源電圧は3.3Vです。

※1:クリックボードは、mikroBUS規格のインターフェースを搭載した様々な機能性ボードの総称です。

X軸、Y軸、Z軸それぞれの加速度を14ビットの分解能で+8g~-8gまでの範囲で計測します。計測は超高速の700マイクロ秒です。計測データはI2CインターフェースでMCUと通信できます。SCL線、SDA線はいずれも本ボード内でプルアップされています。

45°のチルト検出器は、傾いた向きの出力を元にして3つのLEDを点灯させます。本ボードには3つのLEDが実装済みです。Z軸は常に1gの重力が加わっているため置いておくと常に点灯しています(点滅)。また45°チルト検出の出力はボード内でトランジスタによって統合されており、外部のMCUに対して割込信号として出力が可能です。

様々なアプリケーションにお使い頂けます。

 

● MMA8491Q多機能3軸±8 gデジタル加速度計
● チルト検出器よって傾いた向きの出力を基に点灯するLEDを3軸それぞれ実装済み
● +8g~-8gまでの範囲を14ビットの分解能で計測、1mg/LSBの高精度
● ~700マイクロ秒の超高速データ出力時間
● シリアルI²Cバス
● 電源 3.3V
● mikroBUS準拠で様々なマイコン開発ボードに装着しやすい
● ボードサイズ 42.9×25.4 (mm) ※但し上部円形

 

使い方についてはMMA8491Qのデータシートをお読み下さい。

 

■本体回路図

 


■インターフェイス端子(mikroBUS規格)

 

機能詳細 ピン名 Mikrobus logo.png ピン名 機能詳細
NC 1 AN PWM 16 NC
NC 2 RST INT 15 INT チルト検出割込出力
イネーブルピン EN 3 CS TX 14 NC
NC 4 SCK RX 13 NC
NC 5 MISO SCL 12 SCL シリアルI2C クロック
NC 6 MOSI SDA 11 SDA シリアルI2C データ
+3.3V 電源入力 3.3V 7 +3.3V +5V 10 NC
Ground GND 8 GND GND 9 GND Ground

※NCは未使用ピンです。

シリアルI2CのSCLピン、SDAピンはそれぞれボード内で4.7Kオームの抵抗でプルアップされています。

3  EN MMA8491AのENピンに直結しています。このピンがHレベルで加速度センサのすべてが動作します。このピンがLレベルですべての機能が停止します。よって計測する場合にはこのピンはHレベルにする必要があります。
11 I2C SDA I2Cスレーブデータ線 内部で4.7kオームでプルアップ済み
・7ビットI2Cスレーブアドレス:0x55 (固定)
・100KHz又は400KHz
12 I2C SCL I2Cスレーブクロック線  内部で4.7kオームでプルアップ済み
15 INT 3軸傾き検出時割込信号出力
各軸のいずれかが0.688g より大きい(|φ| > 45°)時、Lレベル出力
各軸のいずれかが0.688g 以下(|φ|
≤ 45°)の時、Hレベル出力
※LED出力信号と逆論理

 


■LEDの点灯とINTピンの設定

3軸にそれぞれLEDが接続されています。各LEDは0.688gより大きい(|φ| > 45°)時点灯し、0.688g 以下(|φ|≤ 45°)の時消灯します。Z軸は常に地上では重力で1gがかかっています。(垂直時)

INTピンは3つのLEDのいずれかが点灯する時Lレベルになります。

マイコン等と接続する時、傾きの状態が45°から変化したことを検出する時等に使います。使わない場合にはオープンで構いません。どの軸の割込を有効にするかはボード上の”INT SEL”とシルク印刷のある0オームのジャンパー抵抗の有無で設定できます。デフォルトではすべての軸でジャンパーされています。割込として使いたくない軸がある場合には、チップ抵抗を外すことで無効にできます。


■I2C通信とレジスタ

本モジュールに搭載のMMA8491QのI2Cの7ビットスレーブアドレスは0x55に固定されています。Readで1を加算、Writeで0を加算します。最終的な8ビットアドレスはRead時0xAB、Write時0xAAです。

本モジュールからのデータの読み込みには「シングルリードモード」と「マルチプルバイトリードモード」の2つがあります。マルチプルバイトリードモードでは、自動的にレジスターアドレスがインクリメントされるのでX、Y、Z軸それぞれのデータを連続して読み込めます。データシークエンスは次の通りです。(データシート11ページ参照)

レジスタアドレスにはステータス情報及びX、Y、Z軸それぞれのデータが入ります。レジスタマップは次の通りです。

最初に0x00番地を読み状態を確認します。0x00番地には3軸それぞれに新しい値が入っているかどうかを示すビットがあります。(データシート15~16ページ参照)傾きに変化が生じて値が更新されたかどうかを確認できます。

マルチプルバイトリードモードの場合、自動的にアドレスはインクリメントされます。よって、例えばX軸のMSBをマスター側で読み込めば自動的にアドレスがインクリメントされてX軸のLSBが読めます。3軸合計で6バイトのデータとなります。


■軸データの読み込み手順

データの読み込み等、動作には次のシークエンスが必要です。

使い方としてはENピンは初期化時はLレベルにしておき、データを読みたい時にHレベルにします。

その後I2Cマスター側から読みたい軸のレジスタアドレスにアクセスしてデータを読みます。読み取った後は再度ENピンをLレベルにします。

3軸のデータは14ビット長です。レジスタには上位(MSB)8ビット[13:6]と、下位(LSB)6ビット[5:0]が2つのレジスタに分かれて入っています。例えばX軸のデータは次のようにMSB、LSBのデータが入ります。

LSBデータの入るレジスタの下位2ビット[1:0]は使いませんので通常はI2Cマスター側マイコンのプログラムでシフトさせるようにします。

 

14ビットデータとレンジの関係は次の通りです。  


■データの解析とプログラミング例

ここでは最も基本的な使い方として、I2Cマスター側がデータを読み取った後のデータ処理方法と、プログラミング例を示します。

例としてX軸のデータとして8gのデータがAddress1と2に入っていた場合を考えます。

(1) 8gなので14ビットデータは 01 1111 1111 1111 となります。よってレジスタには下記のようにデータが入ります。

Address1: 0111 1111

Address2: 1111 11xx

(2) 最初にMSBを8ビット分(LSB分)左にシフトして、LSBデータを入れるスペースを作ります。それにはMSBの値に0x100を積算します。

0111 1111 * 0x100  =  0111 1111 0000 0000

(3) LSBを加算します。

0111 1111 0000 0000 + 1111 11xx  =  0111 1111 1111 11xx

これで16ビット長のデータとなります。

(4) 下位2ビットは切り捨てるので右に2ビットシフトする

0111 1111 1111 11xx >> 2  =  0001 1111 1111 1111

これでデータの成形ができました。

(5) この有効値14ビットのデータを実際のgに変換します。正負の判定は14ビット目が0か1かで判断します。0ならば正又は0、1ならば負の範囲であることがわかります。IF文を使う時は0x2000とのビット演算ANDで0又はそれ以外として判定可能です。実際にgに変換するプログラム例は次の通りです。

if (out_x & 0x2000) {
  
  x_axis = (0x4000 - out_x) / -1024.;  

}else{

  x_axis = out_x / 1024.;

}

 

これをもとに実際のプログラミング例を下記に示します。

※あくまでも一例ですので実際はお使いの言語、環境等に合わせてお使い下さい。

 

char STATUS;
unsigned int OUT_X, OUT_Y, OUT_Z, oldOUT_X, oldOUT_Y, oldOUT_Z;
float temp;

void MMA8491Q_Multiple_Read(char *p_STATUS, int *p_OUT_X, int *p_OUT_Y, int *p_OUT_Z){
  char reg_data[7];

  reg_data[0]=0x00;
  I2C1_Start();
  I2C1_Write(MMA8491Q_ADDR,reg_data,1,END_MODE_RESTART);
  I2C1_Read(MMA8491Q_ADDR,reg_data,7,END_MODE_STOP);

  *p_STATUS=reg_data[0];
  *p_OUT_X=((0x100*reg_data[1]+reg_data[2])>>2)&0x3FFF;
  *p_OUT_y=((0x100*reg_data[3]+reg_data[4])>>2)&0x3FFF;
  *p_OUT_Z=((0x100*reg_data[5]+reg_data[6])>>2)&0x3FFF;
}

void Display_X_Value() {                                                         
  
 if(OUT_X&0x2000){
      temp=(0x4000-OUT_X)/-1024.;
    }
    else {
      temp=OUT_X/1024.;
    }
  
    sprintf(out, "%2.3f", temp);          
  }
}

void Display_Y_Value() {                                                   
 
    if(OUT_Y&0x2000){
      temp=(0x4000-OUT_Y)/-1024.;
    }
    else {
      temp=OUT_Y/1024.;
    }

    sprintf(out, "%2.3f", temp);
  }
}

void Display_Z_Value() {     
    if(OUT_Z&0x2000){
      temp=(0x4000-OUT_Z)/-1024.;
    }
    else {
      temp=OUT_Z/1024.;
    }

    sprintf(out, "%2.3f", temp);            
  }
}

void Display_values(void) {
  Display_X_Value();
  Display_Y_Value();
  Display_Z_Value();
  Delay_ms(100);
}

void main(){
  
  while(1) {
    MMA8491Q_EN = 1;
    Delay_ms(500);

    MMA8491Q_Multiple_Read(&STATUS, &OUT_X, &OUT_Y, &OUT_Z);
    MMA8491Q_EN = 0;

    if(STATUS==0x0F) {
      Display_values();
    }
  }
}

■本製品のサポートについて

本製品はメーカーがリリースしているMMA8491Qのデータシート及び本製品の回路図を見て、その使い方をご理解頂き実際にプログラミングやマイコンから本製品を制御できる技術者向けの製品です。

本製品はMMA8491Qの機能をそのまま使った製品ですので、使い方はMMA8491Qのデータシートにてご理解頂く必要があります。本ページでは参考として使い方のプログラム例を示していますのでこれらをご参考にお使い下さい。

本製品の技術的なサポート、I2C通信による使い方、ハードウエアの設計方法等について当方マイクロテクニカではサポートを行っておりません。ご質問頂きましてもご回答致しかねます。本製品のMMA8491Qについての使い方等で技術的なご質問がある場合には、直接メーカーのサポートをご利用下さい。(但しデータシートに既に記載されている内容については回答が得られませんので、必ずデータシートをよくお読みの上、ご質問下さい。)

 

wpmaster