2
1

More than 1 year has passed since last update.

Teensy4.1と激安パーツでハードウェアシンセサイザーを作る (準備)

Last updated at Posted at 2021-03-16

作るもの

こんなやつ。これでMac/WindowsにつながればUSB-MIDI音源と認識され、スタンドアロンでMIDIN INがついたハードウェアのシンセサイザーになる。ちなみにUSB-MIDIだけでなくUSB-Audioとしても認識させることができる。奥のはTeensy4で組んだ先代。
IMG_7611.jpg

用意するもの

接続

PCM5102との接続

  • VCC -> 5V
  • GND -> GND
  • LCK -> 20
  • DIN -> 7
  • BCK -> 21
  • SCK -> 23

とりあえずこの6本繋げば良い。他にも色々な配線がネット上では散見されたが、実際にハードウェアソフトウェア両面の改変無くTeensy4.1で動いたのはここに書いてあった上記の接続。

SSD1306 OLEDディスプレイの接続

  • GND -> GND
  • VCC -> 5V
  • SCK (SCL) -> 19
  • SCA (SDA) -> 18

MIDI IN

下記の回路を組む。MIDI INだけ必要でTHRUとOUTはいらない。VCCに繋がってる抵抗は220Ωで良い。

  • VCC -> 3.3V (5Vじゃないので注意!)
  • MIDI RX -> 0
  • GND -> GND

タクトスイッチ

4つ繋ぐ。片方の足をそれぞれのGND、もう片方の足を2, 3, 4, 5に繋ぐ。

ポテンションメーター

2つ繋ぐ。右の足をそれぞれ5V、左の足をそれぞれGND、真ん中の足を16、17に接続。

動作テスト

Audio (PCM5102A)

Teensyduinoを起動。

  • ツール -> ボード -> Teensyduino -> Teensy 4.1
  • ツール -> USB Type -> Serial + MIDI + Audio

と設定し、ファイル -> スケッチ例 -> Audio -> HardwareTesting -> PassThroughUSB でサンプルを開き、「マイコンボードに書き込む」ボタン(丸に→)をクリックしてボードに書き込み実行。すると、デバイスがUSB-Audio/MIDIデバイスとして認識される。サンプリング周波数は44100Hz固定のよう。Macのシステム環境設定→サウンドで出力デバイスとして指定し、何か再生して音が正常に鳴ればOK。

OLED

スケッチ -> ライブラリをインクルード -> ライブラリを管理...で「SSD1306」を検索。「Adafruit SSD1306」をインストール。さらに、「GFX」で検索して「Adafruit GFX Library」をインストール。両方とも特に理由がなければ最新バージョンを。

ファイル -> スケッチ例 -> Adafruit SSD1306 -> ssd1306_128x64_i2c (すごい下の方にある) を選択。ソースの中でI2Cのアドレスを指定している部分があるので、これをハードウェアに合わせる。こちらで使っているデバイスでは128x64のもので0x78と基板に書いてあるのに0x3Cだった (半分の値にするのが正解だったということ?)。

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32  ←ここを変える
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example
  :

実行してAdafruitのロゴに続いて各デモが流れればOK。

MIDI IN

ファイル -> スケッチ例 -> MIDI Library -> SimpleSynth でサンプルを開き、handleNoteOn() と handleNoteOff() に下記のように追記。

void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
    const bool firstNote = midiNotes.empty();
    midiNotes.add(MidiNote(inNote, inVelocity));
    handleNotesChanged(firstNote);
    Serial.printf("Note On note=%d, velocity=%d\n", inNote, inVelocity);  // これ
}

void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
{
    midiNotes.remove(inNote);
    handleNotesChanged();
    Serial.printf("Note Off note=%d, velocity=%d\n", inNote, inVelocity);  // これ
}

実行してシリアルモニタにMIDI Note On/Off時にメッセージが出ればOK。基板上のLEDも点灯する。

サンプル

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <MIDI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//  MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

//  Audio
// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=290,143
AudioOutputI2S           i2s1;           //xy=433,142
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=140,154
// GUItool: end automatically generated code

//  OLED
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  // Audio
  AudioMemory(20);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  sine1.amplitude(0.75);
  sine1.frequency(1000);

  // MIDI
  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.begin();

  // OLED
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  // Show initial display buffer contents on the screen --
  // the library in/itializes this with an Adafruit splash screen.
  //display.display();
  display.clearDisplay();
  display.setTextSize(2);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
  display.println("Start");
  display.display();
}

void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
  sine1.amplitude(0.75);
  double freq = 440.0 * pow (2.0, ((double)inNote - 69.0) / 12.0);
  sine1.frequency(freq);

  display.setTextSize(1);
  display.printf("Note On %d, %d\n", inNote, inVelocity);
  display.display();
}

void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
{
  sine1.amplitude(0.0);

  display.setTextSize(1);
  display.printf("Note Off %d, %d\n", inNote, inVelocity);
  display.display();
}

void loop() {
  // put your main code here, to run repeatedly:
  MIDI.read();
}

5D60690A-942C-491A-B9A9-0A0A28C9B49F.jpeg

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1