M5Stack社のATOM Echoを買いました

概要

スイッチサイエンスから購入したATOM Echoが来たのでちょっと、触ってみたいと思います。

ATOM Echoとは?

ATOMシリーズ3つ目のコアです。既存のATOMにマイクとスピーカーを内蔵しています。そのため既存ピンが使えなくなっているので注意が必要です。

外見

スイッチサイエンスさんで購入しましたので、シールがぺたぺたはられています。パッケージが小さいので、お顔が見えないんですよね。これ店頭売りで他の店舗で売る場合どうするんだろう?

ちなみにシールは横にはられています。右側にタブがありますもんね。

あけるとこんな感じです。付属品はありません。

並べるとこんな感じです。

ぽんボケですが底は互換性のある形になります。ただしATOM Echoは底にあるピンを全部マイクとスピーカーで使っているので、他の用途で使うことはできません。

厚みの比較です。ATOM Echoは高さが増えた分台形になっていますね。金型から抜きやすくするため?

初期ファームウエア

Bluetoothスピーカーになるファームウエアが購入時には入っています。上書きしてしまった場合には転送しなおす必要があります。

上記にファームウエアがありますので、自分で転送し直すと元に戻せます。

esptool.py --port COM3 -b 1500000 write_flash 0x00000 Atom_echo_a2dp_led_0x00.bin

私はこんなコマンドで元に戻せました。COM3のところは環境によって変えてください。転送に失敗する場合には750000に転送速度落としたほうが安定すると思います。

上記にWindowsとMacでかんたんに転送できるツールがありますが、Windowsのセキュリティーにひっかかったので、自分で転送したほうがいいかな?

実行すると「M5_SPEAKER_T1」という名前で起動するので、スマホなどからBluetoothで接続するとスピーカーになります。ちゃんとボリュームの連動をしますし、それなりの音もでます。小さいのであまり無理はしちゃだめだとは思いますが思いのほか良かったです。

Factory_Test

基本的な動作確認用なのですが、、、起動時になる音がちょっとあれなので、どうなんでしょう?

どうあれなのかは説明できないぐらい、あれです、、、

Repeater

ボタンを押すと録音して、離すと再生してくれるサンプルです。一番基礎的なサンプルはこれだと思います。。。

が、いろいろ怪しいスケッチです。

/*Press button to record,released button to playback*/
#include <driver/i2s.h>
#include <M5Atom.h>
#define CONFIG_I2S_BCK_PIN 19
#define CONFIG_I2S_LRCK_PIN 33
#define CONFIG_I2S_DATA_PIN 22
#define CONFIG_I2S_DATA_IN_PIN 23
#define SPEAKER_I2S_NUMBER I2S_NUM_0
#define MODE_MIC 0
#define MODE_SPK 1
#define DATA_SIZE 1024
uint8_t microphonedata0[1024 * 80];
int data_offset = 0;
void InitI2SSpeakerOrMic(int mode)
{
    esp_err_t err = ESP_OK;
    i2s_driver_uninstall(SPEAKER_I2S_NUMBER);
    i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER),
        .sample_rate = 16000,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // is fixed at 12bit, stereo, MSB
        .channel_format = I2S_CHANNEL_FMT_ALL_RIGHT,
        .communication_format = I2S_COMM_FORMAT_I2S,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 6,
        .dma_buf_len = 60,
    };
    if (mode == MODE_MIC)
    {
        i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM);
    }
    else
    {
        i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
        i2s_config.use_apll = false;
        i2s_config.tx_desc_auto_clear = true;
    }
    err += i2s_driver_install(SPEAKER_I2S_NUMBER, &i2s_config, 0, NULL);
    i2s_pin_config_t tx_pin_config;
    tx_pin_config.bck_io_num = CONFIG_I2S_BCK_PIN;
    tx_pin_config.ws_io_num = CONFIG_I2S_LRCK_PIN;
    tx_pin_config.data_out_num = CONFIG_I2S_DATA_PIN;
    tx_pin_config.data_in_num = CONFIG_I2S_DATA_IN_PIN;
    //Serial.println("Init i2s_set_pin");
    err += i2s_set_pin(SPEAKER_I2S_NUMBER, &tx_pin_config);
    //Serial.println("Init i2s_set_clk");
    err += i2s_set_clk(SPEAKER_I2S_NUMBER, 16000, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
}
void setup() {
    M5.begin(true, false, true);
    M5.dis.drawpix(0, CRGB(128, 128, 0));
    delay(2000);
}
void loop() {
    if (M5.Btn.isPressed())
    {
        data_offset = 0;
        InitI2SSpeakerOrMic(MODE_MIC);
        M5.dis.drawpix(0, CRGB(128, 128, 0));
        size_t byte_read;
        
        while (1)
        {
            i2s_read(SPEAKER_I2S_NUMBER, (char *)(microphonedata0 + data_offset), DATA_SIZE, &byte_read, (100 / portTICK_RATE_MS));
            data_offset += 1024;
            M5.update();
            if (M5.Btn.isReleased())
                break;
            //delay(60);
        }
        size_t bytes_written;
        InitI2SSpeakerOrMic(MODE_SPK);
        i2s_write(SPEAKER_I2S_NUMBER, microphonedata0, data_offset, &bytes_written, portMAX_DELAY);
    }
    M5.update();
}

えーっと、確保しているメモリサイズ以上書き込みが可能です(笑)

割と長めにボタンを押しているとバッファオーバーランで再起動がかかります、、、

EchoSTT

マイクで録音したデータをサーバー上で解析するサンプルです。クイックスタートをちゃんと読まないと動かせなかったです(反省)

まずM5Burnerをダウンロードして、その後にATOMのEchoSTTを書き込みます。その後に「Get Token」ボタンを押すとその端末のトークンキーが取得できます。

Arduino IDEでソースファイルを開き、SSIDとKEY、M5Burnerで取得したトークンキーを編集すると利用可能になります。

あとは初期値はDEV_PID_MANDARINになっていますので、中国語ができないひとはDEV_PID_ENGLISHに変更してください。

#define  DEV_PID_MANDARIN   "1537"      //普通话(纯中文识别)
#define  DEV_PID_M_AND_E    "1536"      //普通话(支持简单的英文识别)
#define  DEV_PID_ENGLISH    "1737"      //英语
#define  DEV_PID_CANTONESE  "1637"      //粤语

まったくもって、他のがどう違うのかがわかりません、、、

StreamHttpClient_ECHO

HTTPでmp3をダウンロードして再生するサンプルです。下記のライブラリを手動で入れる必要があります。

※追記 本家のライブラリに手を加えているのでM5のを使わないとだめみたいです、、、

SSIDとKEYを変更してWi-Fiアクセスポイントに接続することで実行できます。URLを他のmp3に変更することで再生する曲も変更可能です。

ちょっとノイズが乗るかなー?

まとめ

ネットに接続して、マイクとスピーカーをかんたんに利用するのには最適なボードだと思います。ただし、まだESP32のマイクとかスピーカーの使い方は改善の余地があると思いますので、調整することでもう少し音質は良くなる気がします。

コメント

  1. 長野祐一郎 より:

    M5関連情報、いつも参考にさせていただいております!
    お教えいただきたいのですが、ATOMEchoやCore2で、
    「マイクで録音した内容を100msほど遅延させてスピーカーで鳴らし続ける」
    といった処理は可能でしょうか?この100msを適宜調整し、実験に用いる予定です。
    お時間あるときにご回答いただけますと幸いです。

    • たなかまさゆき より:

      EchoもCore2もマイクから取得したデータをそのままスピーカーに出力すればデータ形式的には大丈夫ですが、ハードウエア的にマイクとスピーカーは同時に利用することはできません。
      同じデータバスに接続されているのでどっちかしか使えない状況です。

      また同時に使えたとしても、ハウリングが発生してしまうと思いますのでそのへんを考慮する必要がありそうです。
      たとえば2台のEchoで無線で通信するようなことは可能ですが、なかなか安定動作は難しいと思います。

      • 匿名 より:

        なるほどそういう制約があるのですね。
        2台で通信すると、ネットワークの状態次第で遅延時間が変動し、気持ち悪いことになりそうですね。ご教授いただき、ありがとうございます。

        • 匿名 より:

          いつも貴重な情報を上げていただきありがとうございます。

          StreamHttpClient_ECHO(m5のほう)を試しているのですが下記エラーが発生しています。
          ESP8266Audioのライブラリは使わずにM5のsrcに入っているライブラリを使うの認識であっていますでしょうか。
          もし何かご存知でしたらご教授いただけないでしょうか。

          ■エラー
          decoding error ‘lost synchronization’ at byte offset

  2. たなかまさゆき より:

    https://github.com/m5stack/M5-ProductExampleCodes/archive/master.zip

    こちらをダウンロードして展開して「StreamHttpClient_ECHO」のフォルダを

    C:\Users\%username%\Documents\Arduino\libraries

    にコピーしました

    https://github.com/Gianbacchio/ESP8266_Spiram/archive/master.zip

    上記も同じ用にlibrariesフォルダにコピーしました

    StreamHttpClient_ECHO\StreamHttpClient_ECHO\StreamHttpClient_ECHO.ino

    その後上記をビルドしたところ、正常にビルドできました

    ==================================

    STATUS(mp3) ‘257’ = ‘Decoding error ‘lost synchronization’ at byte offset 12283′
    STATUS(mp3) ‘257’ = ‘Decoding error ‘lost synchronization’ at byte offset 12284′
    STATUS(mp3) ‘257’ = ‘Decoding error ‘lost synchronization’ at byte offset 12285′
    STATUS(mp3) ‘257’ = ‘Decoding error ‘lost synchronization’ at byte offset 12286′
    Running for 22738 ms…
    Running for 23748 ms…
    Running for 24758 ms…
    Running for 25768 ms…

    とはいえ、エラーがでました
    おそらくサーバー側が遅くてダウンロードに時間がかかているかもしれません
    上記は23秒ぐらい経過してから音楽がなりました

  3. 匿名 より:

    早速のご連絡ありがとうございます。私の方でも音楽を再生することが出来ました。ありがとうございました。

    再生時のエラーもサーバー側の問題ということで安心しました。