2017年04月25日

MakerFaireBayArea2017 プロジェクトページ紹介

今回は5月開催のイベントについて
プロジェクトページが公開されたため、
ご紹介させていただきます。


17年5月19日~21日にアメリカベイエリアで開催の
に参加します。


各プロジェクトのページが公開され、
ProjectionBallについても
こちらで公開されました。



こちらの検索画面でピックアップされているプロジェクトは
どれもスケール感が日本とか比べ物にならない感じです。



今回のイベントでは
現在、開発中の最新の
ProjectionBall IoT(仮名称)を展示予定です。

WifiモジュールESP-WROOM-02を搭載することで
スマートフォンやPCから遠隔で操作、
好きな英数字の文字列や時刻などを表示することが可能です。

また、サイズも従来の直径12cmから直径10cmとなり、
更に小型化しました。


協力会社を介して、
数か月程度で販売を開始する予定です。
現在、ファームウェアのデバッグや資料、
販売準備を進めております。




posted by Crescent at 00:00| Comment(0) | TrackBack(0) | イベント | このブログの読者になる | 更新情報をチェックする

2017年04月19日

I2S使用方法

今回はPDM出力のデジタルマイクSPH0641LU4Hを
I2S接続で読み込んでみました。



最近のデジタルマイクはMEMSマイクのため、
一般的なマイクに比べ、
高感度かつ広帯域で感度も帯域に癖がなく、
非常にフラットな感度を持ちます。


特に今回紹介するMEMSマイクは
超音波帯域のマイクとしても使用でき、
80kHzまで拾うことができます。

一般的な超音波受信器は共振型のため、
36kHzと書いてあれば36kHz前後周辺の超音波しか拾うことができません。

一方、MEMSマイクは36kHz以外でも拾うことができるため、
例えば、amazonのDashButtonの初期設定のように
普通のマイクとしても、
超音波を使って自在にスマートフォンと機器の間で通信することもできます。



超音波に対応したMEMSマイクはKnowlesから
デジタル版MEMSマイクSPH0641LU4H以外に
アナログ版MEMSマイクSPU0410LR5Hも出ています。


ただ、アナログ版はご存じのようにオペアンプ増幅回路など
周辺回路が必要です。
一方、デジタル版はそのままマイコンに接続できるため、
周辺回路が不要です。
また、アナログ部がセンサ内部のみとなるため、
ノイズにも強い回路にできます。

一般的にはデジタルマイクはPDM出力となっており、
I2S接続でオーバーサンプリングで取得します。



環境は
・STM32F401RENUCLEO
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(HAL ライブラリ、F4 ver. 1.15.0)
です。


CubeMXの設定は次の通り。

I2S-setting.png

Data and Frame FormatとSelected Audio Frequency
は試しに設定した値です。
ポイントはHalf-Duplex Masterに設定し、
ModeをMaster Recieveに設定することです。


接続は
I2S2_CKをマイクCLK
I2S2_SDをマイクDATA
に接続します。

今回はモノラルで使用するため、
I2S_WSは未使用です。


コードは下記の通り
実際には音を安定して連続に取り込む必要があるため、
DMA転送等を利用すべきですが、
動作確認のため、必要なデータ数を読み込みました。

    uint32_t I2S_RX_BUFFER[24];


  while (1)
  {
     
      int8_t res=HAL_I2S_Receive( &hi2s2,
                            (uint16_t*)&I2S_RX_BUFFER,
                            24,1000);
      HAL_Delay(200);
      //printf("Res: %d ", res);
      printf("Data: %" PRIu32", %"PRIu32", %"PRIu32" , %"PRIu32" \n",
              I2S_RX_BUFFER[0],
        I2S_RX_BUFFER[1],
        I2S_RX_BUFFER[2],
        I2S_RX_BUFFER[3]);
  }
 


今回、テストで使用したKnowles社の
デジタルマイクSPH0641LU4Hは
入力するクロックによってモードが切り替わります。

Low-Power Mode           :351 kHz ≤ fCLOCK ≤ 815 kHz
Standard Performance Mode  :1.024 MHz ≤fCLOCK ≤ 2.475 MHz
Ultrasonic Mode            :3.072 MHz ≤ fCLOCK ≤ 4.8 MHz


HALライブラリのI2Sの設定では
オーディオサンプリングの帯域設定しかありません。
実際に設定によってどのようにクロックが変化するか
確認してみました。


I2Sバスクロック96MHz設定の場合のI2Sクロック結果は下記の通り。

I2S_CLK.png

なお、クロック4.8MHz以上はデジタルマイクSPH0641LU4Hの動作保証外です。
一応、DATA出力としては6MHzまでは出ましたが...


実際にUART出力してみた例は下記の通り。

uart.png

音によって値の桁が変化するため、
正常に読み込んでいると思われます。

今度は読み込んだ値をFFT化したりして、
意図した周波数の信号がとれるか確認してみたいと思います。


なお、I2S_WSは16B幅の場合は
16bit毎にHIGH、LOWが入れ替わり、
それ以外では32bit毎にHIGH、LOWが入れ替わるようです。

96k,16B
16B_96k-WS.png

96k,32B
32B_96k-WS.png


96k,24B
24B_96k-WS.png

96k,16BEX

16BEX_96k-WS.png


1番目がCLK、2番目がDATA、3番目がWSです。


HALライブラリを利用したI2Sの場合、
HALの設定でオーディオサンプリング周波数に応じて
いい感じにクロックを出力してくれることが分かりました。
ただ、今回のセンサのようにクロックによって動作が変わる場合、
I2Sクロック周波数が直感的に分からないため、
オシロスコープ等で確認する必要がありそうです。


タグ:STM32 HAL
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2017年04月13日

FreeRTOS TICK RATE 調査

今回はSTM32 CubeMXで自動生成できる
FreeRTOSについて紹介させて頂きます。

CubeMXでFreeRTOSにチェックを入れるだけで
簡単にFreeRTOSを導入することが可能です。

ロボット制御やモータ制御を専門としていると
リアルタイム性や高速制御周期が制御性能や制御安定性に
効いてくるため気になるポイントです。


今回は将来的に加速度制御系にFreeRTOSを導入する場合を考え、
標準のFreeRTOSのconfigTICK_RATE_HZをデフォルト1000から
10000~60000まで変更してリアルタイム性やスレッドが動作するかテストしてみました。

FreeRTOSはconfigTICK_RATE_HZをデフォルト1000となっていますが、
この場合、最小スレッド切替が1msとなってしまいます。
加速度制御系や電流制御系を構築する場合、
20us~200us程度の最小スレッド切替が欲しいところです。



環境は
・STM32F303K8
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(HAL ライブラリ、F3 ver. 1.7.0)
です。


CubeMXの設定は下記の通りです。
MPU周波数は内臓RCで最大周波数の64MHzに設定しました。
ポイントはデフォルトでは無効のosDelayUntil関数を有効化する点です。

rtos-setting1.png

rtos-setting2.png



作成するスレッドは3つ。

void StartDefaultTask(void const * argument)
{
  uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
      osDelayUntil (&PreviousWakeTime, 1);
  }
}

void StartTask02(void const * argument)
{
   uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);
    osDelayUntil (&PreviousWakeTime, 1);
  }
 }

void StartTask03(void const * argument)
{
   uint32_t PreviousWakeTime = osKernelSysTick();
  for(;;)
  {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
      osDelayUntil (&PreviousWakeTime, 1);
  }
}

スレッドはそれぞれGPIOのトグルを実行し、
トグル実行時間含めて1tick分まで待機します。


スレッドの生成は3段階の優先度で設定しました。
スレッド1つor 2つの場合は2つ目、3つ目のスレッドをコメントアウトして
スレッドを減らして実行しました。

 /* definition and creation of myTask01 */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityRealtime, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of myTask02 */
  osThreadDef(myTask02, StartTask02, osPriorityHigh, 0, 128);
  myTask02Handle = osThreadCreate(osThread(myTask02), NULL);

  /* definition and creation of myTask03 */
  osThreadDef(myTask03, StartTask03, osPriorityAboveNormal, 0, 128);
  myTask03Handle = osThreadCreate(osThread(myTask03), NULL);




最小スレッド切替の定義は
FreeRTOSConfig.h内の
#define configTICK_RATE_HZ                       ((TickType_t)1000*10)
を変更して実験しました。



◆結果
結果一覧は下記の通り

configTICK_RATE  周期       スレッド1つ   スレッド2つ   スレッド3つ
10000           100us       ○           ○        ○
20000           50us        ○           ○        ○
30000           33us        ○           ○        ×
40000           25us        ○           △       ×
50000           20us        △           ×        ×
60000           17us        ×           ×        ×

○:スレッド通りの動作、△:ジッターが多く、時々スレッド通り動作していない
×:スレッド通り動作していない、他のスレッドが全く動作していない


◆スレッド1つ
スレッド1つの場合、configTICK_RATE_HZ 50000 が限界ラインのようです。
configTICK_RATE_HZ 60000 にすると
下記のように周期が一定でなく、非常にジッターが多い感じです。


1ch60t.png



◆スレッド2つ
スレッド2つの場合、configTICK_RATE_HZ 30000 が限界ラインのようです。
configTICK_RATE_HZ 40000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2の周期が一定でなく、非常にジッターが多い感じです。


2ch40t.png

更に周期を高く設定して、
configTICK_RATE_HZ 50000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2が全く動作していません。


2ch50t.png


◆スレッド3つ
スレッド3つの場合、configTICK_RATE_HZ 20000 が限界ラインのようです。
configTICK_RATE_HZ 30000 にすると
下記のようにスレッド1、スレッド2は周期一定ですが、
スレッド3は全く動作していません。

3ch30t.png


更に周期を高く設定して、
configTICK_RATE_HZ 40000 にすると
下記のようにスレッド1は周期一定ですが、
スレッド2の周期が安定せず、
スレッド3は全く動作していません。
3ch40t.png



◆スレッド切替時間
スレッド数2や3の場合は11us程度のようです。
厳密には同時にスレッドスタートできないため、
スレッド切替時間というよりも
スタート時の処理時間の差といった方が正しいかもしれません。

taskswitch.png



◆まとめ

スレッド1つ:25us周期、configTICK_RATE_HZ 40000が限界ライン
スレッド2つ:33us周期、configTICK_RATE_HZ 30000が限界ライン
スレッド3つ:50us周期、configTICK_RATE_HZ 20000が限界ライン
という感じです。
スレッド切替時間は11us程度。

ただ、今回のスレッド内のタスクはLEDトグルの最小限の処理のため、
実際に数値計算の処理やAD変換等の処理が入ると
もう少し限界ラインが変わってくると思います。


理想的な加速度制御系を構築するためには
電流制御周期20us程度が理想で
加速制御周期100us程度となると
スレッド2つでFreeRTOS+F3だとちょっと厳しいかなと思いました。

ということで理想的な加速度制御系を実現するには
MPU周波数が高いF4、F7、H7 を使ってみるか
今まで通り、RTOSなしでタイマ処理で分けるのが良さそうです...

続きを読む
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2017年04月07日

OLED試食

Amazonで販売されているOLED(有機EL液晶)を試食してみました。




sIMG_4342.png

画面サイズは人差し指程度ですが、
思った以上にはっきりと表示され、
遠くからの視認性も良さそうです。



sIMG_4341.png

上の部分が一部黄色に表示され、
それ以外が青色表示なようです。
そのため、表示位置によっては黄色と青色の中途半端な表示になってしまいます。


R3を開放、R1、R8の抵抗を追加します。


配線はD0をSCL、D1をSDAに接続します。
RESをHigh、CSをGNDに接続することです。
解放では動作しませんでした...



RESは場合によっては電源投入後にLOWからHIGHにする必要があるようですが、
今回は常にHIGHでも動作しました。

全体が一色の方が使い勝手が良さそうだと思いました。



0.91インチI2C有機ELディスプレイ128x32の方が大きさが小さく、
RESやCS等の配線、チップ抵抗変更も不要なため、
基板上に邪魔にならずに簡単に実装でき、
情報表示用途には最適だと思いました。



posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする

2017年04月01日

STM32CubeF3 v1.7.0

今回はCubeMXのライブラリをアップデートした際に
遭遇した不具合?について共有したいと思います。


先日リリースされたSTM32CubeMX4.2.0
とSTM32CubeF3 1.7.0を適用しました。


その後、STM32CubeF3 1.6.0で生成した
CubeMXのプロジェクトファイル(*.ioc)を開いて、
再度、別のコードを生成すると
・HALドライバはSTM32CubeF3 1.6.0
・自動生成コードはSTM32CubeF3 1.7.0という
現象が発生しました。

そのため、STM32CubeF3 v1.7.0から増えたパラメータ

htimX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

がHALドライバにないため、
コンパイルが通らないという現象が発生しました。



cubemxf3.png

設定はSTM32CubeF3 1.6.0から読み込む設定です。


STM32CubeF3 1.6.0で生成したCubeMXの
プロジェクトファイル(*.ioc)を流用せずに
0から新規プロジェクトで生成すると上手くバージョンが一致したコードが生成されました。

古いバージョンで生成したプロジェクトファイル(*.ioc)は
テンプレートの読み込み先を最新にするか、
0から新規プロジェクトで生成するのが良さそうです。

特に新しい機能が追加された場合、
旧ドライバにない機能をコメントアウトで対応できますが、
新機能が不定となる可能性もあり、
別の不具合を起こす可能性もあるので、統一した方がよいと思いました。


バージョンアップするとこいう不具合が起きたりするので、
アップデートを見送るか、適用するか悩ましいものです。


ちなみに新しく増えたパラメータAutoReloadPreloadは
TIMx_ARR registerのバッファ有無切替が可能なようですが、
どのような効果があるのか、
資料を見つけられず良く分かりませんでした。
また、追って調査してみたいと思います。


**追記**
おすすめできる方法ではありませが、
あとから再度、旧ライブラリで生成する場合は
*.iocファイルをテキストエディタで開いて、
V1.X.X.Xの部分を書き換えるのが手っ取り早い方法と分かりました。

posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子工作 | このブログの読者になる | 更新情報をチェックする