工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

ADAU1401/ADAU1701 DSPmini 学習ボードで遊ぶ(1) ~ DSPボードの調達と環境整備 ~

概要

ADAU1401/ADAU1701 DSPmini 学習ボードで遊ぶための環境整備を行った。




背景と目的

以前から、ディジタルクロスオーバーネットワークで帯域分割して自作のスピーカーをマルチアンプ駆動したいと考えている。そのためには、DSPを用いて信号処理を行う必要がある。いろいろ検討した結果、市販品を使う手もあるがどうせならディジタルクロスオーバーネットワーク自体を自作してみようと思った。

今回、手始めにAnalog Devices製のDSP ADAU1401/ADAU1701が搭載された DSPmini 学習ボードを使ってみる。



詳細

1. ボードの調達

Analog Devices製のDSP ADAU1401/ADAU1701が搭載された DSPmini 学習ボードは、以下のようなものである。

https://ja.aliexpress.com/item/1005007031349285.html?spm=a2g0o.order_list.order_list_main.5.61b0585aqsqaIJ&gatewayAdapt=glo2jpn

AmazonやAliExpressで3000円程度と安価に購入できる。

Analog Devices社純正のUSBiエミュレータと呼ばれるUSB接続のデバイスを使ってボードとPCと接続し、SigmaStudioという専用ソフトウェアで簡単にディジタルフィルタの設計と設定値の送信が可能である。

ステレオのアナログ入力と4ch出力ができるようなので、ひとまず2wayのクロスオーバーネットワークを組むことができそうだ。

なお、ボードは四隅にネジ穴がないので、3Dプリンターでボードを支えるフレームを作成し、スペーサが取り付けられるようにした。


2. 環境の構想

今回は、都合によりUSBiエミュレータが入手できなかったので、専用ソフトウェアであるSigmaStudioも用いず強引に自前でI2C通信により設定を行えるように、環境を整えていく。手持ちの部材で簡単にできそうな手段として思いついたのが、

  • ESP32 DevKit-CをPCと接続し、シリアルをI2Cに変換するソフトウェアを構成してPCからシリアル経由でDSPボードを制御する

という方法。要するに、USBiエミュレータがやっているようなことをやってしまおうということ。PC側は、当然SigmaStudio相当のアプリケーションが必要になってくるが、上記の接続が確立してしまえばある意味自由に作れるので、そちらも自前で作ってしまえばよいと考えている。

ということで、今回まずはESP32 DevKit-CのソフトウェアとDSPボードとの接続を行う。


3. 接続

DSPボードと、ESP32 DevKit-Cの接続は以下とした。

  • GPIO21 <--> SCL 2.2kΩで3.3Vにプルアップ
  • GPIO22 <--> SDA 2.2kΩで3.3Vにプルアップ
  • 5V <--> 5V
  • GND <--> GND

なお、調べたところ、DSPボードのSCL、SDAは何もつながない状態で3.3Vとなっていたので3.3V系の信号ラインとなっている。そのため、プルアップ抵抗も3.3V系へ接続した。


3. シリアル-I2C ブリッジのソフトウェア

ひとまず、I2Cのレジスタ値読み取りができればよいので、Arduino IDE上でシリアルからデータを送信し、DSPから読み出した値がシリアルで返ってくるようにしてみた。

3.1 ADAU1701.h

ADAU1701のI2C通信を抽象化したクラスを作成。なお、今回は書き込み部は未実装。あとで追加予定。

#include <Wire.h>

class ADAU1701 {

public:

  ADAU1701() {
  }

  /*
    初期化
  */
  void begin(uint8_t i2c_addr, uint8_t sda_pin, uint8_t scl_pin, int i2c_freq) {
    _i2c_addr = i2c_addr;
    Wire.begin(sda_pin, scl_pin);
    Wire.setClock(i2c_freq);
  }

  /*
    書き込み
  */
  uint8_t write(uint16_t reg_addr, uint8_t data_len, uint8_t* buf) {
    // 未実装
  }

  /*
    読み取り
    Returns:
      0x00: 正常
      0xfe: データ長さエラー
      上記以外: 送受信エラー
  */
  uint8_t read(uint16_t reg_addr, uint8_t data_len, uint8_t* buf) {

    uint8_t reg_high = reg_addr / 256;
    uint8_t reg_low = reg_addr % 256;

    Wire.beginTransmission(_i2c_addr);
    Wire.write(reg_high);
    Wire.write(reg_low);

    uint8_t err = Wire.endTransmission(false);
    if (err != 0) {
      return err;
    }

    uint8_t bytesReceived = Wire.requestFrom(_i2c_addr, data_len);
    if (bytesReceived == data_len) {
      int i = 0;
      while (Wire.available()) {
        buf[i] = Wire.read();
        i++;
      }
    } else {
      return 0xfe;
    }

    return 0x00;
  }

private:

  uint8_t _i2c_addr = 0x34;

};

3.2 メインプログラム

Arduinoのメインプログラム。ADAU1701クラスを用いて作成する。 シリアルからのコマンド書式は、1バイトごとに16進文字列をスペースで区切った文字列で最後に改行コード。例: "0F 12 A4 FF 01 80" また、コマンド文字列であることを示す独自ヘッダ(AA 55)をの冒頭に2バイト分つけている。

#include "ADAU1701.h"

#define I2C_ADDR 0x34
#define SDA_PIN 21
#define SCL_PIN 22
#define I2C_FREQ 100000

#define HEADER_0 0xAA
#define HEADER_1 0x55

const uint8_t CMD_WRITE = 0x00;
const uint8_t CMD_READ = 0x01;


ADAU1701 adau1701 = ADAU1701();


// 16進文字列をbyte arrayに変換
// 例: "0F 12 A4 FF 01 80"
uint8_t parse_bytes(String hexStr, uint8_t* buf, size_t buf_len) {
  int startPos = 0;
  size_t count = 0;
  while (startPos < hexStr.length() && count < buf_len) {
    int spacePos = hexStr.indexOf(' ', startPos);
    if (spacePos == -1) {
      spacePos = hexStr.length();  // 最後の要素
    }

    String sub = hexStr.substring(startPos, spacePos);
    if (sub.length() > 0) {
      buf[count++] = (uint8_t)strtol(sub.c_str(), NULL, 16);
    }

    startPos = spacePos + 1;  // スペースの次の文字へ
  }
  return count;
}

void setup() {
  Serial.begin(115200);
  adau1701.begin(I2C_ADDR, SDA_PIN, SCL_PIN, I2C_FREQ);
}

void loop() {

  if (Serial.available()) {
    String input = Serial.readStringUntil('\n');
    uint8_t cmd_buf[16];
    uint8_t cmd_len = parse_bytes(input, cmd_buf, 16);

    if (cmd_len < 6) {
      Serial.printf("ERROR: COMMAND TOO SHORT\n");
      return;
    }

    if ((cmd_buf[0] != HEADER_0) || (cmd_buf[1] != HEADER_1)) {
      Serial.printf("ERROR: INVALID HEADER\n");
      return;
    }

    if (cmd_buf[2] == 0) {
      // 書き込み
    } else {
      // 読み込み
      uint8_t reg_high = cmd_buf[3];
      uint8_t reg_low = cmd_buf[4];
      uint8_t data_len = cmd_buf[5];
      uint8_t buf[16];
      uint16_t reg_addr = reg_high * 256 + reg_low;
      uint8_t err = adau1701.read(reg_addr, data_len, buf);
      if (err != 0x00) {
        Serial.printf("ERROR: READ,%02x\n", err);
      } else {
        for (int i = 0; i < data_len; i++) {
          Serial.printf("%02x", buf[i]);
          if (i < data_len - 1) Serial.printf(" ");
        }
        Serial.printf("\n");
      }
    }
  }
}


4. 動作確認

Arduino IDEのシリアルモニタ上で、

AA 55 01 08 1E 02

と入力したところ、

08 00

と返ってきた。このレジスタは、

https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1701.pdf

によれば、SERIAL OUTPUT CONTROL REGISTERでI2Sの出力フォーマットやクロックの設定用レジスタの値である。


まとめと今後の課題


デスク周りのリメイク

概要

デスク周りのリメイクを行った。




背景と目的

前回までで、計画した5か所のリメイクを終えたので、まとめておく。



詳細

1. 写真

すべてを収めるように写真を撮ることが難しいので、最後の天板リメイクと仕上がりCADイメージ。

2. 製作過程ダイジェスト

2.1 構想

基本構想の記事は、2025年10月に書いた。事情(というか現行のものが割と使い勝手がよくリメイクの必要がないと判断)により、ツールパネルは作らないことにした。

dekuo-03.hatenablog.jp

2.2 メインシェルフの製作

25mm杉無垢ボードで天板を作り、蜜蝋ワックスを使った。自然の風合いを生かした仕上がりにできた。 また、側板の内部には、6畳間で起こりやすい定在波周波数に合わせたヘルムホルツ共鳴器を仕込み、定在波を抑制させるオーディオアクセサリーとしての機能も持つのが特徴。おそらく、世の中にこのような棚は存在しないのではないだろうか?

dekuo-03.hatenablog.jp

2.3 デスクトップシェルフの製作

コの字デスクの端は手が届かないため、斜めに配置した天板が特徴。

dekuo-03.hatenablog.jp

2.4 右サイドデスクの製作

何といっても、天板面積と棚の収納可能幅をうまく折り合わせるために、一部を切り欠いた独特のデザインが特徴。

dekuo-03.hatenablog.jp

2.5 左サイドデスクの製作

幅1250mmと大きめかつ板取りの効率が悪いサイズで悩ましかったが、仕上がりそのものは悪くない。

dekuo-03.hatenablog.jp

2.6 メインデスク天板のリメイク

気づいたら6月後半。メインデスクに手を入れついに作業完了となった。

dekuo-03.hatenablog.jp


デスク周りのリメイク(6) ~ メインデスク天板リメイク、リメイク完了 ~

概要

メインデスクの天板リメイクを行い、リメイク計画を完了した。




背景と目的

デスク周りのリメイク第6弾。左サイドデスクに続き、メインデスクの天板リメイクに取り掛かる。今回で、リメイク計画を完了させる。



詳細

1. 設計

今回製作するのは、メインデスクの天板である。天板を作るといっても、まだまだ現在使用しているものは使える状態なので、実際には、

2.5mm厚MDFボードに、周囲のデスクと同じ柄のリメイクシートを貼り、現在の天板に載せる

という方法にする。これにより、ほとんどお金を掛けずに見た目を整えられる。現在の天板そのものに貼らない理由は、これまで使ってきてある程度傷がついており平滑性に難があるため、新たに板材を貼ったほうが良いと判断したから。

イメージとしては以下。左右のサイドデスクやデスクトップシェルフと全く同じ柄のリメイクシートにより、統一感のあるデスク面が完成する。


2. 製作

近所のホームセンターにて、必要な木材を購入し、カットサービスを利用。

早速、リメイクシートを貼る。リメイクシートの幅が400mmなので、1枚で全体を覆うことができない。そこで、1枚目の端に合わせて隙間や重なりがないように2枚目を貼るのだが、リメイクシートの端の直線性と貼り付け作業の両方で極めて高い精度が要求され、現実的には不可能である。 そのため、壁紙を張る作業でよく行われるが一部を重ね合わせて貼り、重なり部分の真ん中にカッターを入れて重なり部分を後からはがすことで、非常に正確に貼り合わせることができる。

貼った様子。上記の方法で貼ることでシートの境目がほとんど目立たず、それなりにうまくいったと思う。


3. 設置

設置前の様子。それなりの年数使ったのでかなり傷がある。色味は、今回作成したものにくらべて明るめ。

設置した様子。デスクトップシェルフも同色で、統一感のあるほぼイメージ通りの仕上がり。



まとめと今後の課題

メインデスク天板のリメイクを完了し、昨年末頃より取り組んできた5か所のリメイクを完遂した。ほぼイメージ通りの仕上がりとなり、十分満足いく結果となった。途中、ウルトラワイドディスプレイを導入することも含めて、ひとつながりのコの字型デスクが完成した。普段の在宅勤務から、DIY作業まで必要なものが周りに配置でき効率のよい空間ができたと思っている。今後、この環境を生かしてさらにDIYに励みたい。