MiniSynth V2 este un sintetizator/sampler digital portabil, polifonic, alimentat la baterie, construit pe baza microcontroler-ului Teensy 4.0 (ARM Cortex-M7 @ 600 MHz). Dispozitivul reproduce sunete prin trei mecanisme complementare:
AudioSynthWavetable.Toate instrumentele dispun de anvelope ADSR per-instrument, acordare pe scale muzicale (Chromatic, Major, Minor, Pentatonic, Blues, Dorian etc., cu rădăcină configurabilă) și un lanț de efecte (Reverb, Delay, Chorus, Flanger, Bitcrush, Distortion). Polifonia este de 8 voci cu alocare dinamică (oldest-voice stealing).
Realizarea unui instrument muzical electronic complet, autonom (battery-powered, fără PC), care să acopere cele 7 teme de laborator ale cursului PM (GPIO, UART, Întreruperi, Timere/PWM, ADC, SPI, I2C) într-o aplicație coerentă și utilă.
Mi-am dorit un proiect care să combine electronica analogică (audio path, alimentare, jack-uri comutate) cu DSP în timp real (sinteză polifonică, efecte, eșantionare) și o interfață utilizator propriu-zisă (display + meniu navigabil). Un sintetizator polifonic portabil, cu eșantionare bifurcată (instrumente factory + sample-uri user pe SD card), îndeplinește toate cele trei criterii și demonstrează simultan toate cele 7 laboratoare PM, nu doar minimul cerut de 3 — fiecare modul al proiectului mapează firesc pe câte un laborator (GPIO/UART/INT/PWM/ADC/SPI/I2C), fără implementări forțate.
┌───────────────────────────┐
│ Teensy 4.0 │
│ (NXP iMXRT1062, M7) │
│ 3.3 V GPIO │
└─┬───┬───┬───┬───┬───┬───┬─┘
│ │ │ │ │ │ │
┌──────────────────┘ │ │ │ │ │ └──────────────────┐
│ │ │ │ │ │ │
│ GPIO bit-bang │ │ │ │ │ I2S1 (BCLK/LRCLK/DIN) │
▼ │ │ │ │ ▼ │
┌──────────┐ │ │ │ │ ┌──────────────┐ │
│ 4× SR │ │ │ │ │ │ UDA1334A │──L/R───►│ Jack 3.5mm
│ 74HC165 │◄──┐ │ │ │ │ │ I2S DAC │ │ (căști, comutat)
│ (25 keys)│ │ │ │ │ │ └──────┬───────┘ │
└──────────┘ │ │ │ │ │ │ │
│ │ │ │ │ │ 2× 47kΩ + cap │
┌──────────────┴─────┐ │ │ │ │ ▼ │
│ 2× butoane octave │ │ │ │ │ Sumare L+R ─────────►│ Jack 6.35mm
│ (Omron B3F) │ │ │ │ │ │ (chitară, comutat)
└────────────────────┘ │ │ │ │
│ │ │ │ ┌─────────────────┐
│ │ │ ├─►│ MAX98357A LEFT │──► Boxă L (4 Ω)
│ │ │ │ └────────┬────────┘
│ │ │ │ │ SD_MODE
│ │ │ └───[direct]┘ (pin 14)
│ │ │
│ │ │ ┌─────────────────┐
│ │ ├─────►│ MAX98357A RIGHT │──► Boxă R (4 Ω)
│ │ │ └────────┬────────┘
│ │ │ │ SD_MODE
│ │ └───[210 kΩ]────┘ (pin 22)
│ │
│ │ ADC (A1, A2, A3)
│ ▼
│ ┌────────────────────┐
│ │ Joystick X/Y/SW │
│ │ Potențiometru 10kΩ │
│ └────────────────────┘
│
│ I2C (SDA0, SCL0)
▼
┌─────────────────────┐
│ SSD1306 OLED 1.3" │
│ 128×64 │
└─────────────────────┘
SPI hardware (CS, MOSI, MISO, SCK):
┌──────────────────────┐
│ HW-125 microSD │ ◄── user samples (.wav)
└──────────────────────┘
Detecție jack-uri (GPIO + 100kΩ pull-up):
Pin 6 ◄── SJ1-3535NG (tip switch, "break")
Pin 23 ◄── Switchcraft 112AX (tip switch, "make", polaritate inversată)
Lanț de alimentare:
18650 Li-Ion ──► TP4056 (USB-C) ──► MT3608 boost ──► 5V ──► Teensy VIN
│ │
└► CHRG ── R ──► WP7113GD LED (verde, charging)
│
3.3V LDO Teensy ──► logica (74HC165, joystick, pot, OLED, pull-up-uri)
| Modul | Componentă principală | Rol | Interfață cu MCU |
|---|---|---|---|
| Microcontroler | Teensy 4.0 | DSP audio + control + UI | — |
| Tastatură 25 taste | 4× SN74HC165N + Omron B3F-1000 | Scanare matrice taste | GPIO bit-bang (pin 5/8/9) |
| Butoane octave | 2× Omron B3F-1000 | Shift octavă ±1 | GPIO + INT (pin 2, 3) |
| Joystick | SparkFun analog joystick | Pitch bend / modulation / meniu | ADC (A1, A2) + GPIO (pin 4) |
| Potențiometru | 10 kΩ rotativ | Volum / ajustare valori meniu | ADC (A3) |
| DAC stereo | UDA1334A | I2S → analog L/R | I2S (pin 7, 20, 21) |
| Amplificator L | MAX98357A | Class-D, 3.2 W, canal stâng | I2S (shared) + SD_MODE (pin 14) |
| Amplificator R | MAX98357A | Class-D, 3.2 W, canal drept | I2S (shared) + SD_MODE (pin 22, 210 kΩ) |
| Difuzoare | 2× Sony SS-TSF550 (4 Ω) | Ieșire stereo | analogic |
| Jack căști | SJ1-3535NG (TRS comutat) | Ieșire 3.5 mm + detecție | analog + GPIO det. (pin 6) |
| Jack chitară | Switchcraft 112AX (TS comutat) | Ieșire 6.35 mm mono + detecție | analog + GPIO det. (pin 23) |
| Display | SSD1306 OLED 1.3” 128×64 (Adafruit 938) | Meniu + HUD | I2C (pin 18, 19) |
| Storage | HW-125 microSD breakout | User samples (.wav) | SPI hardware (pin 10–13) |
| LED încărcare | WP7113GD (verde, 5 mm) | Indicator charging | TP4056 CHRG (independent de MCU) |
| Încărcător | TP4056 USB-C | CC/CV Li-Ion + protecții | — |
| Boost converter | MT3608 | 3.0–4.2 V → 5 V | — |
| Acumulator | 18650 Li-Ion + holder | Sursă de energie | — |
| Întrerupător | Rocker switch | ON/OFF general (post-MT3608) | — |
Pe firul audio (digital → analog):
Teensy generează stream-ul I2S (BCLK pin 21, LRCLK pin 20, DIN pin 7) care este distribuit simultan către trei dispozitive: UDA1334A (DAC pentru căști / chitară) și două MAX98357A (amplificatoare Class-D pentru difuzoarele stereo). Selecția canalului per amplificator se face prin pinul SD_MODE (analog multi-nivel), conform Tabelului 5 din datasheet-ul MAX98357A: ampul stâng primește SD_MODE direct dintr-un GPIO Teensy (HIGH = canal stâng), iar ampul drept primește SD_MODE printr-un rezistor serie de 210 kΩ care, împreună cu pull-down-ul intern de 100 kΩ, plasează tensiunea în intervalul B1–B2 (canal drept). Calculul rezistorului serie (din datasheet, pentru VDDIO = 3.3 V):
R_SMALL = 94.0 × VDDIO − 100 = 94.0 × 3.3 − 100 = 210.2 kΩ
→ se folosește 210 kΩ (E96) sau 220 kΩ (E24).
Pe firul de comandă (UI → DSP): Joystick-ul și potențiometrul sunt citite pe ADC. Joystick-ul efectuează în modul play pitch bend (X) și modulation (Y); apăsarea click-ului joystick-ului activează meniul. În meniu, mișcările joystick-ului sunt doar pentru navigare, iar potențiometrul este singurul mecanism de modificare a valorilor (volum master, ADSR, voice count, concert pitch, scale, root note). Această separație previne modificările accidentale în timpul navigării.
Pe firul de detecție și mute hardware:
La introducerea unui jack (căști sau chitară), GPIO-urile de detecție (pin 6 și pin 23) basculează stările (cu polarități inversate, conform datasheet-urilor SJ1-3535NG vs. Switchcraft 112AX). Firmware-ul răspunde tragând pinii 14 și 22 (SD_MODE) în LOW, ducând ambele MAX98357A în shutdown hardware (~0.6 µA quiescent / chip). Acest mecanism elimină pop-urile audibile și economisește baterie când un jack rămâne introdus.
Pe firul de alimentare: Acumulatorul 18650 alimentează modulul TP4056 (charging + protecții); ieșirea acestuia merge la MT3608 care urcă tensiunea la 5 V. Acest rail unic alimentează Teensy (prin VIN, cu trasa VIN-VUSB tăiată — obligatoriu pentru a preveni back-feed-ul USB), cele două MAX98357A, UDA1334A și HW-125. LDO-ul intern al Teensy (3.3 V) alimentează apoi logica de joasă putere: 74HC165, joystick, potențiometru, OLED și toate pull-up-urile. LED-ul de charging WP7113GD este conectat direct între VBUS și pinul CHRG al TP4056 — nu consumă pini sau ciclii MCU.
| Componentă | Cantitate | Sursă | Rol |
|---|---|---|---|
| Teensy 4.0 (NXP iMXRT1062, ARM Cortex-M7 @ 600 MHz) | 1 | PJRC / Mouser | Microcontroler principal |
| UDA1334A I2S DAC breakout (NXP) | 1 | eMAG (clonă) | DAC stereo line-level pentru căști + chitară |
| MAX98357A I2S Class-D amplifier breakout (Adafruit/clonă) | 2 | Temu | Amplificare Class-D 3.2 W per canal pentru difuzoare |
| Sony SS-TSF550 (4 Ω, bass-reflex satellite) | 2 | Local | Difuzoare stereo |
| SN74HC165N (8-bit PISO shift register) | 4 | Mouser | Scanare 25 taste + 7 intrări nefolosite |
| Bourns 4608X-101-103LF (rețea bussed 8× 10 kΩ) | 4 | Mouser | Pull-up-uri pentru 25 taste + 7 intrări libere |
| Omron B3F-1000 (tactile switch, low-profile) | 27 | Mouser | 25× taste pian + 2× butoane octave (Oct+/Oct−) |
| Adafruit 938 — OLED 1.3” 128×64 SSD1306 | 1 | Mouser / eMAG | Display meniu și HUD play-mode (jumperele J1, J2 lipite pentru I2C) |
| SparkFun analog joystick (2-axis + push-button) | 1 | Temu | Pitch bend / modulation / navigare meniu |
| Potențiometru rotativ 10 kΩ liniar | 1 | Local | Volum master / ajustare parametri meniu |
| HW-125 microSD card module (cu LDO 3.3 V + level shifter) | 1 | Temu | Storage user samples (.wav) |
| SJ1-3535NG (jack 3.5 mm TRS, switched) | 1 | Mouser | Ieșire căști + detecție plug |
| Switchcraft 112AX (jack 6.35 mm TS, switched, “Tip Closed Circuit”) | 1 | Mouser | Ieșire amplificator chitară + detecție plug |
| WP7113GD (LED verde 5 mm, GaP, V_F ≈ 2.0 V) | 1 | Mouser | Indicator charging (driven de TP4056 CHRG) |
| TP4056 USB-C charger module (cu protecții + CHRG/STDBY pads) | 1 | Temu | Încărcare CC/CV pentru Li-Ion |
| MT3608 boost converter module (2 A max) | 1 | Temu | 3.0–4.2 V → 5 V stabil |
| 18650 Li-Ion + holder cu contacte arc | 1 | Local | Sursă de energie |
| Rocker switch (ON/OFF, single-pole) | 1 | Local / Temu | Întrerupător general pe rail-ul 5 V |
| PCB custom (KiCad → fabricație online) | 1 | JLCPCB / similar | Suport mecanic + interconectare |
| Valoare | Cantitate | Rol |
|---|---|---|
| 210 kΩ (E96) sau 220 kΩ (E24) | 1 | Rezistor serie SD_MODE pentru MAX98357A-RIGHT (selecție canal drept la VDDIO = 3.3 V) |
| 100 kΩ | 4 | Pull-up-uri detecție jack (×2) + divizor monitorizare baterie (×2) |
| 47 kΩ | 2 | Rețea de sumare L+R → mono pentru ieșirea de chitară |
| 1 kΩ (sau 470 Ω pentru luminozitate sporită) | 1 | Limitare curent LED charging (WP7113GD) |
| 0.47 µF / 1 µF film | 2 | Cuplare AC pe ieșirile analogice ale UDA1334A |
| 100 nF ceramic | ~10 | Decuplare locală pe pinii VDD ai fiecărui IC |
| 10 µF electrolitic / ceramic | ~5 | Decuplare bulk pe rail-ul 5 V și 3.3 V |
Subansamble cheie deja proiectate (descrieri detaliate vor urma împreună cu schemele):
SD_MODE LEFT (direct, 0 Ω); pin 22 → 210 kΩ → SD_MODE RIGHT. Jumperele de canal de pe breakout-uri NU se podesc (altfel GPIO LOW ar scurtcircuita rail-ul de 5 V prin GPIO de 3.3 V).
| Pin | Funcție | Periferic | Observații |
|---|---|---|---|
| 0 | RX1 | UART | Debug serial input |
| 1 | TX1 | UART | Debug serial output |
| 2 | BTN_OCT_UP | GPIO + INT | Octavă +1 |
| 3 | BTN_OCT_DN | GPIO + INT | Octavă −1 |
| 4 | JOY_SW | GPIO + INT | Click joystick (activare meniu / select / toggle) |
| 5 | SR_DATA | GPIO bit-bang | Ieșirea QH a ultimului 74HC165 |
| 6 | JACK_HP_DET | GPIO input | Detecție căști (LOW = liber, HIGH = plug) |
| 7 | I2S1_DIN (OUT1A) | I2S | Date I2S → DAC + ambele amp-uri |
| 8 | SR_CLK | GPIO bit-bang | Clock 74HC165 |
| 9 | SR_LATCH | GPIO bit-bang | SH/LD 74HC165 |
| 10 | SD_CS | SPI | Chip select HW-125 |
| 11 | SD_MOSI | SPI | MOSI HW-125 |
| 12 | SD_MISO | SPI | MISO HW-125 |
| 13 | SD_SCK | SPI | SCK HW-125 (+ LED onboard Teensy) |
| 14 | AMP_LEFT_SD | GPIO output | SD_MODE MAX98357A LEFT (direct) |
| 15 / A1 | JOY_X | ADC | Pitch bend / navigare orizontală |
| 16 / A2 | JOY_Y | ADC | Modulation / navigare verticală |
| 17 / A3 | VOL_POT | ADC | Volum / ajustare parametri |
| 18 / A4 | SDA0 | I2C | OLED date |
| 19 / A5 | SCL0 | I2C | OLED clock |
| 20 | LRCLK1 | I2S | Word select → toate cele 3 dispozitive audio |
| 21 | BCLK1 | I2S | Bit clock → toate cele 3 dispozitive audio |
| 22 / A8 | AMP_RIGHT_SD | GPIO output | SD_MODE MAX98357A RIGHT (prin 210 kΩ) |
| 23 / A9 | JACK_GUITAR_DET | GPIO input | Detecție chitară (HIGH = liber, LOW = plug — polaritate inversată) |
| VIN | +5 V | Power | De la MT3608, cu trasa VIN-VUSB tăiată |
| 3.3V | +3.3 V | Power | De la LDO intern Teensy → logică de joasă putere |
| Laborator | Implementare în MiniSynth V2 |
|---|---|
| GPIO | Scanare 25 taste prin 74HC165 (bit-bang), butoane octave, click joystick, detecție jack-uri |
| UART | Debug serial (Serial1) pentru diagnostic în timpul dezvoltării |
| Întreruperi | Pin-change pe butoanele de octave, ISR audio (DMA I2S), click joystick, detecție hold pentru ieșire meniu |
| Timere / PWM | Generare I2S clocks (BCLK 1.4 MHz, LRCLK 44.1 kHz), ISR-ul Teensy Audio Library la 2.9 ms (PIT periodic), timing pentru hold-detect |
| ADC | Joystick X/Y, potențiometru, monitorizare baterie (divizor 100k/100k) |
| SPI | Card microSD (HW-125) pe SPI hardware — single full SPI demonstration cu CS/MOSI/MISO/SCK |
| I2C | Display OLED SSD1306 |
.sf2) în header-e CAudioSynthWaveform / AudioSynthNoiseWhite (math)AudioSynthWavetable (factory wavetable din PROGMEM)AudioPlaySdWav (user samples cu loop-points)instrument.txt pe SD)midi_note → scale_degree cu rădăcină configurabilăplayback_rate = 2^(semitone_offset / 12))
.kicad_sch), PCB (.kicad_pcb), gerber-uri pentru fabricație, BOM detaliat.ino + .h/.cpp), wavetable headers, manifestul SD card de demo.scad + .stl), fotografii, video demo
Namespace OCW: pm:prj2026:bianca.popa1106:mihai.brisculescu.