Rapid IoTを色々動かしてみた

未分類
NXPのRapid IoT prototyping kitには様々なセンサー類が搭載されており、
それらのセンサー情報を取得するアプリケーションが事前にプログラムされています。
また総合開発環境MCUXpressoと別売りのHexiwear Docking Stationを使用することで
搭載されたセンサーを使った独自IoTを開発することも可能です。
今回はこの方法でサンプルプロジェクトを基に色々と動かしてみました。

1.LED制御

装置LEDは色・輝度を指定して実行する事で制御できます。

typedef enum {
    RGB_LED_BRIGHT_HIGH   = 3       /*!< LED High Brightness */
} rgb_led_brightness_t;
typedef enum {
    RGB_LED_COLOR_BLUE   = 2,       /*!< LED Color: Blue*/
} rgb_led_color_t;
RGB_Led_Set_State(RGB_LED_BRIGHT_HIGH, RGB_LED_COLOR_BLUE);
以下は色と輝度を切り替えた装置LEDの図です。
  

2.文字列画面出力と画面制御

装置に搭載されているカラーディスプレイの様々な項目に関して設定できます。
輝度のレベルを選択することでバックライトの輝度を設定します。

typedef enum _backlight_level {
    BLIGHT_LEVEL_OFF    = 0, /*!< Backlight Off */
} backlight_level_t;
Backlight_SetLevel(BLIGHT_LEVEL_OFF);
既存の定義されたRGB値を指定することで画面色や文字色を設定します。
#define GUI_BLUE          0x00FF0000
#define GUI_WHITE         0x00FFFFFF
GUI_SetBkColor(GUI_WHITE);
GUI_SetColor(GUI_BLUE);

文字列の出力と画面の全消去です。

GUI_DispString(" Hello World!\n\n");
GUI_Clear();
以下の図はHello Worldの出力結果です。
    

3.外部アナログ入力をAD変換して画面出力

Rapid IoT本体をDocking Stationと接続することで本体背面にある入出力端子を
外部接続として拡張できます。そこで外部接続端子の1つを使用してアナログ入力を
AD変換してデジタル値として取得し本体画面にログとして表示します。

アナログ値の入力に使う端子等の固定値を定義します。

#define DEMO_BASE BOARD_INITPINS_MB1_AN_PERIPHERAL
#define DEMO_CHANNEL BOARD_INITPINS_MB1_AN_CHANNEL
#define DEMO_GROUP 0

ADコンバータの現在設定を取得し使用する端子に合わせて初期化します。

    adc16_channel_config_t adc16ChannelConfigStruct = {
     .channelNumber = DEMO_CHANNEL,
     .enableInterruptOnConversionCompleted = false,
     .enableDifferentialConversion = false
    };
    adc16_config_t adc16ConfigStruct;
    ADC16_GetDefaultConfig(&adc16ConfigStruct);
    /* Initialize ADC16 converter */
    ADC16_Init(DEMO_BASE, &adc16ConfigStruct);
    ADC16_EnableHardwareTrigger(DEMO_BASE, false);
    ADC16_SetHardwareAverage(DEMO_BASE, kADC16_HardwareAverageCount32;
    ADC16_SetChannelMuxMode(DEMO_BASE, kADC16_ChannelMuxA;
    ADC16_DoAutoCalibration(DEMO_BASE);

設定した後ADコンバータから値を取得します。

    ADC16_SetChannelConfig(DEMO_BASE, DEMO_GROUP, &adc16ChannelConfigStruct);
    /* Polling to see if ADC conversion has been done.*/
    while (0U == (kADC16_ChannelConversionDoneFlag &
      ADC16_GetChannelStatusFlags(DEMO_BASE, DEMO_GROUP)))
    {
    }
    uint32_t Adc1Value = ADC16_GetChannelConversionValue(DEMO_BASE, DEMO_GROUP);
以下は取得した値を画面に出力した実行結果です。
   

4.加速度センサーによる割り込みと加速度の画面出力

加速度センサーが閾値以上の加速度を検知した際に割り込みをかける機能を利用して
各加速度を取得し画面出力します。

まず加速度センサーからの割り込みを有効化するために定義します。

#define EN_TRANS_INTERRUPT

これにより加速度センサーから割り込みをする機能を有効化する関数が実行されます。

FXOS8700_WriteReg(fxos8700_handle, FXOS8700_CTRL_REG4, tmp[0] | FXOS8700_INT_EN_TRANS_MASK)

割り込みの発生条件に使用する加速度の閾値(例では2G)を設定します。

FXOS8700_WriteReg(fxos8700_handle, FXOS8700_TRANSIENT_THS_REG, 0x20)

次に本体側の加速度センサーの割り込み受付を有効化します。

PORT_IRQ_EnablePortDIrq();
加速度センサー割り込み時の実行先にセンサー値を取得し画面出力する関数を追加します。
if (pin_nb & (1 << BOARD_INITPINS_ACCEL_INT2_GPIO_PIN)) {
    /* TODO: Trigger event */
    GPIO_ClearPinsInterruptFlags(BOARD_INITPINS_ACCEL_INT2_GPIO, 1U << BOARD_INITPINS_ACCEL_INT2_GPIO_PIN);
}

加速度センサデータを取得するには初めに初期化します。

Init_MotionDetect();

以下の関数を実行する事で3軸分の浮動小数点データをまとめて取得する事ができます。

float AccelerometerValue[3] = {0};
uint8_t AccelerometerSize   = 12;
get_acceleration((uint8_t *)AccelerometerValue, &AccelerometerSize);
以下は取得した加速度センサーの3軸の値と合成加速度を画面出力した実行結果です。
   

5.BLE通信のAdvertisingを使用し疑似ビーコンとして通信

BLE通信におけるAdvertising用のパラメータを設定変更します。
例としてIntervalの値を両方とも10秒とし、Advertisingの送信間隔を変更します。
※サンプルには10秒用の定義はないため計算して定義します。

GAPSetAdvertisingParametersRequest_t gAdvParams = {
    /* minInterval */         gGapAdvertisingInterval_10s_c, \
    /* maxInterval */         gGapAdvertisingInterval_10s_c, \
    /* advertisingType */     GAPSetAdvertisingParametersRequest_AdvertisingType_gConnectableUndirected_c, \
    /* addressType */         GAPSetAdvertisingParametersRequest_OwnAddressType_gPublic_c, \
    /* directedAddressType */ GAPSetAdvertisingParametersRequest_PeerAddressType_gPublic_c, \
    /* directedAddress */     {0, 0, 0, 0, 0, 0}, \
    /* channelMap */          GAPSetAdvertisingParametersRequest_ChannelMap_gChannel37_c | GAPSetAdvertisingParametersRequest_ChannelMap_gChannel38_c | GAPSetAdvertisingParametersRequest_ChannelMap_gChannel39_c, \
    /* filterPolicy */        GAPSetAdvertisingParametersRequest_FilterPolicy_gProcessAll_c \
};

変更したらパラメータ設定を反映します。

GAPSetAdvertisingParametersRequest(&gAdvParams, BLE_FSCI_IF);
次にBLE通信のAdvertisingパケットの内容を変更します。
Advertisingパケット用データ格納先(最大31byte)にAD TypeとAD Dataを設定します。
複数の設定項目がある場合は項目毎に同じ様に繰り返します。
※以下はローカル名の設定する例です。
sprintf(device_name, "RPK%02X%02X\0", bleAddress[1], bleAddress[0]);
ShellGap_AppendAdvData(&gAppAdvertisingData,
      GAPSetAdvertisingDataRequest_AdvertisingData_AdStructures_Type_gAdShortenedLocalName_c,
      device_name);

設定したAdvertisingのパケットデータを更新します。

ShellGap_ChangeAdvertisingData(2, NULL);

全ての設定が完了したらBLE通信を開始/停止します。

GAPStartAdvertisingRequest(BLE_FSCI_IF);
GAPStopAdvertisingRequest(BLE_FSCI_IF);
以下はRaspberry Piでコマンドhcltools,hcldumpを実行し取得したデバイス名と
パケットフォーマットの図です。

6.低消費電力モードへの変更と駆動時間

Rapid IoTの搭載CPU Kinetisは複数の低消費電力モードを持っていて
そのうちの1つであるWaitモードを実行し駆動時間を確認します。

Waitモードは通常起動(Runモード)から以下の処理を行うと遷移します。

SMC_PreEnterWaitModes();
SMC_SetPowerModeWait(SMC);
SMC_PostExitWaitModes();
しかし時間経過と電池残量の変動を通常起動時と比較すると同様に推移していくので、
デバッグ確認すると処理実行後も止まることなく動き続けており省電力モードとして
動作していないことが判明しました。
色々調査した所、Waitモードを起動する別の方法がありそちらを試してみます。
SCB_SCR_SLEEPONEXIT_Mskビットの有効化を追加します。
status_t SMC_SetPowerModeWait(SMC_Type *base) {
    /* configure Normal Wait mode */
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
   /* ここに追加 */ SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
    __DSB();
    __WFI();
    __ISB();
    return kStatus_Success;
}
モード移行処理の実行後もデバッグモードでメイン処理が進まないことを確認しました。
時間経過と電池残量を同じ方法で再確認し、駆動時間が延びていることが確認できました。
 
以下が独自アプリケーションによるモード毎の駆動時間のまとめです。
動作モード 駆動時間
Runモード 約3時間
Waitモード 約3時間30分

 

コメント

タイトルとURLをコピーしました