2020年10月

2020年10月18日 02:02

状態によって再生する音楽を変更するとしたら、一番簡単なのは複数のプレイリストを持って切り替えるのが良いだろうということで、今日は複数のプレイリストを生成して、それを切り替えることができるか?を確認してみます。

もともとは、

Playlist thePlaylist("TRACK_DB.CSV");

と1つのインスタンスを生成しているところを

Playlist thePlaylist0("TRACK_DB0.CSV");
Playlist thePlaylist1("TRACK_DB1.CSV");
Playlist thePlaylist2("TRACK_DB2.CSV");
Playlist* thePlaylist = &thePlaylist0;

というように3つのインスタンスを生成するようにし、

static void list()
static bool next()
static bool prev()

の中の

thePlaylist.



thePlaylist->

に変更。

void setup()

の中の

  thePlaylist.



  thePlaylist0.
  thePlaylist1.
  thePlaylist2.

の3つに、

例えば、initだったら、

  success = thePlaylist.init(playlist_dirname);



  success = thePlaylist0.init(playlist_dirname);
  success = thePlaylist1.init(playlist_dirname);
  success = thePlaylist2.init(playlist_dirname);
※エラーチェックはちゃんとやったほうがいい。苦笑。

のように、すべての初期化と設定は、3つのインスタンスに行う。
※presetの値を3つ持たせて、それぞれで設定したほうがいいだろうが今はしない。


void loop()

の中の

thePlaylist.

は、

thePlaylist->

に変更し、

switch/caseに、x/y/z でプレイリストを切り替えるコードを追加。

    case 'x': // change list
      if (s_state == Active) {
        stop();
        s_state = Ready;
      }
      thePlaylist = &thePlaylist1;
      break;
    case 'y': // change list
      if (s_state == Active) {
        stop();
        s_state = Ready;
      }
      thePlaylist = &thePlaylist2;
      break;
    case 'z': // change list
      if (s_state == Active) {
        stop();
        s_state = Ready;
      }
      thePlaylist = &thePlaylist0;
      break;


このコードをコンパイル&実行すると、x/y/z できりかえられるコードができた。

multilist





2020年10月16日 14:29

おいおい、ダイエットウォークマンどうなってんだよ~!
と言われそうだけど、ちょっと、気分を変えてサンプラーっぽいものを作ってみようかなと思い始めました。

というのも、Spresense のサンプルの中に、文字を打つとすぐに音を鳴らせるサンプルを発見したため。
https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html#_%E4%BD%8E%E9%81%85%E5%BB%B6%E5%86%8D%E7%94%9F%E3%81%99%E3%82%8B

これを使うと、シリアル入力した文字に合わせて、遅延なく音を出せそうなので、
このシリアル入力を以前買ったキーパッド

https://www.switch-science.com/catalog/5535/

に置き換えるだけで、サンプラーっぽいものができるな~と思ったんです。

で、早速、

https://github.com/sonydevworld/spresense-arduino-compatible/tree/master/Arduino15/packages/SPRESENSE/hardware/spresense/1.0.0/libraries/Audio/examples/application/rendering_objif/rendering_objif.ino

を改変。


まず、キーパッドが使えるように、以下をinclude。

#include <Wire.h>
#include "SparkFun_Qwiic_Keypad_Arduino_Library.h"
KEYPAD keypad1; //Create instance of this object

次に、setupの中の "Serial.begin(115200);"の後で、で、初期化を呼ぶ。

  if (keypad1.begin() == false) // Note, using begin() like this will use default I2C address, 0x4B. 
// You can pass begin() a different address like so: keypad1.begin(Wire, 0x4A).
  {
    Serial.println("Keypad does not appear to be connected. Please check wiring. Freezing...");
    while (1);
  }

で、文字をscanしている部分を、キーパッド入力に変える。

  keypad1.updateFIFO();  // necessary for keypad to pull button from stack to readable register
  char button = keypad1.getButton();

  while (button == -1)
  {
    Serial.println("No keypad detected");
    delay(1000);
  }

  if (button != 0)
    {
      switch (button) {
        case '1': // play
          playno = start_event(playno,0);
          break;
        case '2': // play
          playno = start_event(playno,1);
          break;
        case '3': // play
          playno = start_event(playno,2);
          break;
        case '#': // stop
          if (s_state == Active)
            {
              stop();
            }
          s_state = Stopping;
          break;
          
        default:
          break;
      }
    }

これで、簡単に、ボタンを押すと効果音が鳴るようになりました!


DSC_0474




2020年10月10日 22:57

次に音楽再生部分を組み込みます。
折角なので、自分の聞きたい曲のリストを聞けるように、player_playlist.ino を組み込みます。
https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html#_%E3%83%97%E3%83%AC%E3%82%A4%E3%83%AA%E3%82%B9%E3%83%88%E5%86%8D%E7%94%9F

ここは、地道にマージ。
同時に、Playlistと、聞きたい音楽ファイルをSDカードにそれぞれ、

AUDIO/ ディレクトリに、プレイリストで再生する音楽コンテンツファイルをコピーします。
PLAYLIST/ ディレクトリに、プレイリストファイル ( TRACK_DB.CSV ) をコピーします。

ってことで、作成してコピー。

マージ出来たら、動かしてみると、


Step_log2


こんな感じで、音楽再生しながら行動認識できた。
簡単!






いよいよ、体重が前人未到の領域(自分の中で)に踏み込んできました。
やばいです。
なので、やろうやろうと思っててサボってた、ダイエット用ウォークマンを作ってみようかなと。

HWは、お得意(苦笑)のPDA01を使います。
※小さく音楽再生できるし、加速度がついているので!
https://p-art.net/pda01-2

まずは、StepCounterのサンプルを確認すると、BoschのBMI160ベースになっているので、
KX122に物理センサを変更します。

https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html#_step_counter_%E3%81%AE%E7%89%A9%E7%90%86%E3%82%BB%E3%83%B3%E3%82%B5%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B
変更の仕方はドキュメントがあるので、わかりやすい!

簡単に、変更してStepCounterというより、走ってる、歩いてる、止まってるの行動認識ができた。

Step_log

これで、行動認識部分はすんなりOK。

次は、音楽再生を組み込もう。

2020年10月07日 23:53

GPIOの叩き方が分かったと同時に、アドレス空間を見る限り、どのコアでも同一にIOを制御できそうだということが分かったので、実際に、SubCoreでたたいてみることにします。

マルチコアのサンプルをベースにするために、

examples/asmp
を使って確認します。このサンプルは、特にチュートリアルはないようなので、
Readmeを参考に動作させてみます。

https://github.com/sonydevworld/spresense/tree/master/examples/asmp/

ここで、このサンプルの詳しい説明は、目的から外れるのでしないのですが、

./tools/config.py examples/asmp
でconfigでbuildすると、SubCoreのバイナリもRomdiskになって読み込めます。
その後、ロードして実行すると、MultiCore間で、
message queue、mutexのテストをして終了するサンプルです。

今回、これらの通信テストをせずに、スイッチ5を叩くとLEDが点灯するコードをSubCoreに書いて実行できればOKです。


まず、pinのConfigrationをMainCoreで行います。

examples/asmp/asmp_main.c ※Master側のMain Loop
に、pin制御をするためのincludeをします。

#include <arch/board/board.h>
#include <arch/chip/pins.h>

また、

int main(int argc, FAR char *argv[])

の中の 310行目

  (void) run_worker(fullpath);

の前に、inputとoutputのpinを設定します。
今回は、inputをPIN_PWM3、outputをPIN_I2S1_LRCKとしたので、

  board_gpio_config(PIN_PWM3, 0, true, false, PIN_PULLUP);
  board_gpio_config(PIN_I2S1_LRCK, 0, false, false, PIN_FLOAT);

  (void) run_worker(fullpath);

を追加します。
これで、pinのconfigができました。

※PDA01のスイッチは、開放が1、押下が0なので、pullupにしています。

※こちらを参考にしました。
https://developer.sony.com/develop/spresense/docs/sdk_tutorials_ja.html#_%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0



次にSubCore側で、inputされたら、直ちにoutputするコードを書きます。

examples/asmp/worker/hello/hello.c ※SubCore側のMain Loop
このファイルの

int main(void)
の前に、

レジスタ定義を追記します。

#define CXD56_SYS_MIRROR                          0x04000000
#define CXD56_TOPREG_BASE                       (CXD56_SYS_MIRROR + 0x00100000)
#define CXD56_TOPREG_GP_PWM3               (CXD56_TOPREG_BASE + 0x20c0)
#define CXD56_TOPREG_GP_I2S1_LRCK       (CXD56_TOPREG_BASE + 0x216c)

※諸々includeパスが通ってない場所なので、定義を書いてしまっています。

これで、Mapped IO のレジスタアドレスが定義できたので、
int main(void)

の先頭に、

  volatile uint32_t* iadr = (uint32_t*)CXD56_TOPREG_GP_PWM3;
  volatile uint32_t* oadr = (uint32_t*)CXD56_TOPREG_GP_I2S1_LRCK;

  while(1){
    if( (*iadr & 0x01) == 0){
      break;
    }
  }
  *oadr = 0x100; 
  while(1);  /* exit代わり */

SubCore側で、スイッチ5の検出をするとLEDが点灯を点灯させるコードになりました。


SubCore


実際に、これらGPIOアクセスのHWドライバ層ををworker側から
呼べるようにしようと思ったのですが、きれいに構成をし直す必要があるので諦めました。

誰かやってくれる勇者はいないかなあ…。


昨日の続きが、また、夜中になってしまった。orz

GPIOの制御は、
https://developer.sony.com/develop/spresense/docs/sdk_tutorials_ja.html#_system_gpiotool

こちらを読むとわかります。

board_gpio_config
で、pinの設定をして、

board_gpio_read
board_gpio_write
で、RWします。

MainCoreでの普通の使い方は、チュートリアルでわかります。



今回はこの中身を見て、レジスタ情報相当にたどり着くことが目的なので調べていくと、

spresense/nuttx/arch/arm/src/cxd56xx/cxd56_gpioif.c
の中の

cxd56_gpio_writeとcxd56_gpio_read

regaddr と regvalとが、レジスタアドレスと生値になります。



ここから、GPIO(SPR_PWM3/SPR_I2S1_LRCK)アクセスは、

spresense/nuttx/arch/arm/src/cxd56xx/hardware/cxd5602_topreg.h

にある、

#define CXD56_TOPREG_GP_PWM3                    (CXD56_TOPREG_BASE + 0x20c0)
#define CXD56_TOPREG_GP_I2S1_LRCK               (CXD56_TOPREG_BASE + 0x216c)

だとわかります。

読み出すときは、最下位ビットを、書き込むときは、下位から9ビット目を叩くことがわかりました。


[補足]
と、実は、レジマップを発見!

こっちのページのここに載っていました。
https://sony-semicon.co.jp/products/smart-sensing/spresense/assets/images/CXD5602_user_manual.pdf

こちらの P89 を見ても、上記の認識があってたことがわかります。


スタート遅れたので、今日もここまで。



2020年10月06日 04:45

ず~っと、サボってたのですが、久しぶりに記事書きます…。

とある事情で、MainCoreの処理を邪魔したくなかった上に、ある信号線が立ち上がったら、8us以内にある信号線を落とさなければいけなかったので、SubCoreでのGPIO制御をどうしてもしたくなりました。

そこで、サンプル使ってSubCoreでのGPIOアクセスに関して実験しました。
examples/asmp
を使います。

ボードは簡単に試すために、手持ちのPDA01を使って実験しました。
※スイッチが付いていたので…。
https://p-art.net/pda01-2

こちらの回路図を見ると、
https://p-art.net/wp/wp-content/uploads/2019/06/PDA01_kairozu.pdf

スイッチ5番が SPR_PWM3 につながっているので、これを押したら、
LED が付くコードをSubCoreに実装して動作することを確認します。

LEDは、
https://github.com/sonydevworld/spresense-hw-design-files/raw/master/CXD5602PWBMAIN1/schematics/CXD5602PWBMAIN1_schematics.pdf
を見ると、

SPR_I2S1_LRCK

につながっているので、取り急ぎ、これを叩くことにします。

ただし、Spresense内部のレジスタマップが見つからなかったので、コードを読み解くことにしました。



眠いので、今日はここまで…。
つづく。

ギャラリー
  • 土壌センサーを使ってみる!
  • KiCADを使ってみよう! その3
  • KiCADを使ってみよう! その3
  • 小型AIカメラを作ろう! その2
  • KiCADを使ってみよう! その2
  • 小型AIカメラを作ろう! その1
  • KiCADを使ってみよう! その1
  • KiCADを使ってみよう! その1
  • Spresense 向けWiSUNボードを使ってみよう
記事検索
Twitter プロフィール
楽天市場
  • ライブドアブログ