User Tools

Site Tools


nano_ardule_midi_controller:step-by-step_coding_roadmap

This is an old revision of the document!


Nano Ardule MIDI Controller: 단계별 코딩 로드맵

목표: 하드웨어를 모두 연결한 뒤, 기능을 작은 단위로 쪼개어 안정적으로 구현·검증한다. 각 단계는 독립 스케치로 끝내고, 통합은 맨 마지막에 진행한다. 이 문서는 2025년 8월 21일에 작성된 개정판이다.

최종 수정일: — Haeyoung Jeong 2025/08/26 08:19

꽃과 PCB


전제(Assumptions)

  • 보드: Arduino Nano(ATmega328P)
  • 표시장치: 1602 I2C LCD
  • 입력: 로터리 인코더 1개(버튼 포함), 푸시버튼 6개
  • 출력: MIDI OUT, LED(Part A/B/Drums, Activity)
  • 저장: EEPROM(설정), microSD(Type 0 MIDI, User Program/Combi)
  • 채널 규칙(권장): A=CH1, B=CH2, Drums=CH10 (Global에서 변경 가능)

전체 원칙

  • 한 단계 = 하나의 기능만 탑재한 최소 스케치 → 성공 시 `/tests/step_##_name.ino`로 고정 저장
  • LCD는 “미니 디버그 콘솔”처럼 사용(상태·에러 간단 표기)
  • 문제 발생 시 직전 단계 스케치와 비교하여 원인 분리
  • 통신/입출력은 비동기·상태머신 우선(블로킹 지양)

추천 디렉토리 구조

/NanoArdule
  /src
    config.h
    ui.h / ui.cpp                // LCD UI, 화면 템플릿, 상태머신
    midi_io.h / midi_io.cpp      // TX/RX, Running Status, 유틸
    routing.h / routing.cpp      // Layer/Split, 채널 리매핑
    storage.h / storage.cpp      // EEPROM (User Program/Combi/Global)
    player.h / player.cpp        // SD & Type-0 MIDI 재생
    main.ino
  /tests
    step_00_base.ino
    step_01_lcd_power.ino
    step_02_inputs.ino
    step_03_midi_tx.ino
    step_04_midi_rx_pass.ino
    step_05_routing_layer_split.ino
    step_06_ui_modes.ino
    step_07_eeprom.ino
    step_08_sd_player.ino

단계 0. 베이스 골격-passed

목표: 공통 헤더·유틸과 전역 상태 정의, 부팅 배너

해야 할 일

  • `config.h`에 핀/채널/타임아웃 등 상수 모음
  • 전역 상태(`struct AppState`) : 모드(SINGLE/EDIT/PLAY/SETUP), 활성 파트(A/B/A+B/DRUMS), 각 파트의 PRG/BANK/VOL/PAN/RVB/CHR
  • 부팅 배너: `Nano Ardule vX.Y` 1초 → `READY`

통과 기준

  • 리셋/전원 인가 시 LCD에 배너 후 `READY` 표시

산출물: step_00_base.zip test/, src/ 구조는 아직 만들지 않고 단순하게 시작한다.

주의사항

  • 업로드 시에는 D0(RX) 및 D1(TX) 핀에 연결된 사용자 제작 회로의 연결을 해제한다.

단계 1. 전원·LCD·LED 스모크 테스트_passed

목표: 전원 품질과 LCD, LED 배선 이상 유무 확인

해야 할 일

  • LCD 초기화(`0x27, 16×2`) → “Hello, Ardule” 1.5초 → “READY”
  • Activity/Part LED 한 번씩 시퀀스 점등
  • (선택) `Serial.begin(115200)`로 부팅 로그 1~2줄

통과 기준

  • 깜빡임 최소, 글자 깨짐 없음, LED 과다광도/발열 없음

산출물: step_01_lcd_power.zip 필요한 상수를 전부 코드 안에서 #define 문으로 정의했으므로 여기에서는 config.h 파일을 포함하지 않음


단계 2. 로터리 인코더 & 버튼 입력_passed

목표: 인코더 증감과 버튼 단·장 클릭을 정확히 읽어들임

해야 할 일

  • 인코더 카운터 표시: `ENC: 123`
  • 버튼(각각) 단클릭/장클릭(>700ms) 구분 → LCD 표시
  • 소프트 디바운스 또는 라이브러리, 풀업/접지 확인
  • 특히 PART SELECT 버튼에 연결된 A6에는 외부 풀업저항(10K)을 연결하였음
  • RX 및 TX에서 외부 회로로 나가는 중간에 점퍼를 넣어 프로그램 업로드 시 이를 끊을 수 있게 하였음-TX와 그라운드 레일 사이에 절연 불량이라서 패드 사이를 잘 긁어서 문제를 해결함
  • 로터리 인코더의 CLK/DT 단자와 GND 사이에 103 세라믹 커패시터를 삽입하여 불안정한 동작을 개선하였음(별도의 풀업 저항을 넣으라는 권유도 있었으나 이것까지는 하지 않음)

통과 기준

  • 빠른 회전에도 카운트 누락·역방향 오검출 없음
  • 모든 버튼 단·장 클릭이 일관되게 표시

산출물:


단계 3. MIDI TX 기본_passed

목표: 실제 GM 음원으로 Note/Program/Channel 전송 검증

해야 할 일

  • 버튼 단클릭: Note 60 On ↔ Off
  • 인코더: Program Change 증감(001…128) — BANK은 후속 단계
  • LCD 상단: `CH:01 PRG:001`, 하단: `NOTE: C4 ON/OFF`

통과 기준

  • 소리 발생·정지가 정확, PRG 변경 즉시 반영

산출물:


단계 4. MIDI RX & 패스스루_passed

목표: 외부 키보드 입력 파싱 및 기본 패스스루

해야 할 일

  • LCD 하단: `IN Ch1 N60 V90`, PB/Mod 등도 간단 로그
  • IN → OUT 그대로 전달(지연 최소)
  • Running Status 처리 점검

통과 기준

  • 고속 연주·페달에도 누락 없음, 체감 지연 미미

산출물:

  • step_04_progchange_encoder.zip인코더로 Program Change 번호를 선택하고 전송하는 기본 버전
  • step_04b_progchange_with_loop_v2.zip인코더 Program Change에 더해서 버튼을 길게 놀러 노트 루프 ON/OFF 토글 기능을 추가한 확장 버전
  • step_05_midi_in_thru_lcd_monitor_v12.zip MIDI IN으로 들어온 신호를 그대로 MIDI THRU로 내보냄. LCD 갱신 주기가 너무 빠르면 THRU에 지연이 발생하므로, 인코더 버튼을 누르면 LCD 표시를 아예 끄도록 한다. 이 버전은 PC에서 보내는 MIDI 파일 재생 신호를 받아서 그대로 보내는 용도이다. 화면 표시는 0.2초 간격으로 갱신한다. 너무 자주 갱신하면 MIDI 신호를 내보내는데 지연이 발생할 수 있다.

중간단계 정리

Step 04 완료 체크리스트 (Step 05 시작 조건)

하드웨어/전원

  • ✅ Arduino Nano(ATmega328P), 1602 I2C LCD(0x27), 인코더(D2/D3, SW=D4), Activity LED=D9 배선 정상
  • ✅ 인코더 라인에 10 nF(=103) RC(또는 등가) 적용, 필요 시 4.7 kΩ 풀업 추가 고려
  • ✅ 업로드 시 TX 외부 회로 분리 → 업로드 후 재연결 (RX/TX 간섭 없음)

펌웨어 기본

  • ✅ MIDI TX 보드레이트 31,250 bps (Serial.begin(31250))
  • ✅ Activity LED(D9) 전송 시 짧게 점등
  • ✅ LCD 출력은 고정폭(16자 패딩) 또는 라인 전체 지우고 재출력으로 잔상 없음

입력 안정화

  • ✅ 인코더: 인터럽트 RISING + µs 가드(STEP_GUARD_US≈800 µs)로 역방향/튀는 값 없음
  • ✅ 인코더 버튼: 디바운스(≥25 ms), 단/장(>700 ms) 구분 정상
  • ✅ A6(사용 시) 풀업 10 kΩ 또는 등가 값으로 안정 (히스테리시스 적용 가능)

Step 04 기능 달성

  • ✅ Program Change(0–127): 인코더 회전으로 번호 변경 →
    • 자동 커밋: 0.2 s 무동작 시 PC 전송
    • 즉시 전송: 버튼 짧게 눌러 PC 전송
  • ☐ (선택) Note Loop 토글: 버튼 길게 눌러 C–E–G–C5 순환 Note On/Off (FSM, 비차단)
  • ✅ LCD 1행: PRG: xxx 고정폭 표시 / 2행: 상태 메시지(1초 후 “Ready/Loop” 복귀)

트러블슈팅 기록 (요약)

  • ✅ “Ready52/꼬리 문자” → 라인 전체 클리어·패딩 출력으로 해결
  • ✅ 업로드 정지 → 보드 뒷면 TX–GND 미세 단락 제거로 해결
  • ✅ 인코더 튐 → RC + µs 가드 + 고정폭 표시로 착시/노이즈 해소

ChatGPT 대화 목록이 너무 길어져서 다음 단계부터는 새 창으로 넘어가려고 한다. 아래를 새 채팅 첫 메시지로 붙여넣으면 바로 다음 단계로 넘어간다고 한다.

프로젝트: Nano Ardule MIDI Controller

현황(요약):
- Step 04까지 완료. Program Change를 인코더로 조절/전송 OK.
- LCD는 16자 패딩으로 잔상 제거, Activity LED 동작.
- 인코더 RISING + STEP_GUARD_US≈800µs, 버튼 디바운스/장단클릭 정상.
- (선택) Note Loop 토글도 동작함/안함: [여기에 O/X 적기]

요청:
- Step 05: Routing (Layer/Split)과 채널 리매핑 설계 및 테스트 스케치 제시.
- 우선 목표: PART A/B 단일/동시(A+B)와 DRUMS(CH10) 모드 전환, 키 스플릿 포인트 지정, 트랜스포즈 엔트리 진입 UI 골격.

단계 5. 라우팅: Layer & Split

목표: 입력 노트를 A/B 다중채널로 복제 또는 음역대로 분기. 당초 단계 목표는 아주 간단하게 설정하였으나, SAM9703 도터보드에 장착된 GMS963200-B(4 MB ROM)의 모든 소리에 접근하기 위한 사운드 브라우저 기능이 들어가면서 다소 복잡해졌다. 사운드 브라우저에 진입하려면 인코더 버튼을 길게 눌러야 한다.

이 단계에서는 Nano Ardule MIDI Controller의 핵심 기능을 구현하는 것이므로 매우 주의깊게 진행하여 실패가 없도록 해야 한다. 8월 마지막 주말에 꽤 공을 들여서 코딩을 구현하였다. 애초에 구상하였던 작동 방식도 조금씩 합리적으로 변하고 있다.

  • (인코더 회전 step 변경) 프로그램이나 뱅크 변경은 현 방식대로 하되 나머지 수치 변경은 step = 3으로 변경(6으로 해 보았으나 한번에 너무 큰 값이 바뀜)
  • Reverb/Chorus의 각 채널별 초기 센드 설정: step_05_routing_layer_split_v1.6b_cycle_pc_rvb_cho_plusminus.ino

해야 할 일

  • Layer: 같은 노트를 A와 B 채널로 동시 송신
  • Split: 스플릿 포인트 기준 A(하), B(상)로 분기
  • LCD 예시: `LAYER ON` / `SPLIT A:C3↓ | B:C#3↑`

통과 기준

  • 스플릿 경계에서 노트 누락·중복 없음
  • Layer 시 두 악기 겹침이 안정적

산출물:


단계 6. UI 모드·화면 템플릿·안전 탈출

목표: 버튼으로 모드 전환, 인코더로 파라미터 순환 편집

해야 할 일

  • 모드: `SINGLE(기본)/EDIT/PLAY/SETUP(Global)`
  • 인코더 버튼: 편집 대상 순환(Program → Bank LSB → Vol → Pan → Reverb → Chorus → Cutoff(CC74) → Reso(CC71))
  • LCD 16×2 템플릿(예)
    • L1: `Mode:SGL A PRG:001`
    • L2: `VOL:64 RVB:32 CHR:32`
  • 어디서든 `STOP/EXIT`로 한 단계씩 안전 복귀

통과 기준

  • 모드 간 전환 시 화면 깜빡임 최소, 조작 혼동 없음

산출물: `/tests/step_06_ui_modes.ino`


단계 7. EEPROM: User Program & Combi 저장/로드

목표: User Program(단일 파트)과 Combi(A+B) 슬롯 저장

데이터 레이아웃(예시)

필드 크기 설명
MAGIC 4B `“ARDU”`
VER 1B 구조 변경 대비
SLOTN CH/PRG/BANK/VOL/PAN/RVB/CHR/필요 CC
CRC16 2B 무결성

해야 할 일

  • `saveUser(slot) / loadUser(slot)` / `saveCombi(slot) / loadCombi(slot)`
  • 빈 슬롯/CRC 불일치 시 `LOAD FAILED` 표시
  • 저장 시 현재 볼륨 등 연주 필수치도 함께 기록

통과 기준

  • 전원 재투입 후 동일 상태 복원
  • 50회 반복 저장에도 에러 없음

산출물: `/tests/step_07_eeprom.ino`


단계 8. microSD & Type-0 MIDI 플레이어

목표: SD에서 곡 스캔, 선택 재생/일시정지/정지

해야 할 일

  • 파일 규칙 권장: `file00.mid` … `file99.mid` (최대 100)
  • LCD 상태: `▶`/`⏸`/`■`, 곡 번호, 경과/총시간(선택)
  • 공연 보호: 재생 중 위험 조작은 이중 확인(PLAY+STOP 등)

통과 기준

  • 짧은/긴/템포 변화 큰 파일 모두 정상
  • SD 없음/불량 시 명확 경고 & 안전 복귀

산출물: `/tests/step_08_sd_player.ino`


단계 9. Global Settings(SETUP)

목표: 기본 악기/채널/대기시간/연속재생 등 EEPROM에 저장

권장 항목(예)

  1. Part A/B 기본 Program
  2. Part A/B 기본 Channel, 대체 CH(연주 중 리매핑용)
  3. 인코더 적용 지연(예: 0.2s)
  4. MIDI 파일 정지 시 리와인드 여부
  5. 연속 재생 On/Off, 곡 간 대기시간(초)
  6. (선택) 설정 덤프 to SD

통과 기준

  • 전원 재투입 후 전역 설정이 기대대로 반영

산출물: `/src/storage.(h|cpp)` 업데이트 + UI 반영


단계 10. 통합·최적화·예외 처리

목표: 모든 기능 동시 구동에서 안정성 확보

체크리스트

  • 지연/버퍼: IN → (Layer/Split) → OUT 지연 최소
  • 노이즈·전원: 인코더/SD 동작 시 LCD 떨림·리셋 여부
  • 메모리: SRAM 여유(문자열 `F()`), 스택/힙 충돌 없음
  • 에러 처리: SD 제거, 빈 슬롯, MIDI IN 없음… → 사용자 친화 메시지
  • 안전 토글: Panic, GM/GS/XG Reset SysEx(선택)
  • 회귀 테스트: `/tests` 전 단계 스케치 재검증

산출물: `/src/main.ino` 완성 빌드


최종 QA 체크리스트

  • 부팅 배너/READY 정상
  • 인코더 증감/버튼 단·장 클릭 인식
  • MIDI TX: Note/Program/Channel 정확
  • MIDI RX: 수신·패스스루 누락 없음
  • Layer/Split 라우팅 정확(경계 노트 포함)
  • UI 모드 전환 & 안전 탈출(Stop/Exit) 일관
  • EEPROM Save/Load + CRC 무결성
  • SD 스캔/재생/일시정지/정지 안정
  • 통합 후 지연/노이즈/에러 처리 OK

트러블슈팅 힌트

  • LCD 깜빡임: `lcd.clear()` 남발 금지 → 커서 이동으로 덮어쓰기, I2C 클럭(100k/400k) 조정
  • 인코더 튐: 풀업/접지 재확인, 인터럽트 vs 폴링 비교, 디바운스 임계 재조정
  • MIDI 누락: 송수신 버퍼 크기, Running Status·Pitch Bend 등 가변길이 처리 확인
  • SD 불안정: CS 핀/배선 짧게, 전원 디커플링(100nF+수십μF), 라이브러리 버전 고정
  • EEPROM 내구: 매직/버전/CRC 사용, 덮어쓰기 최소화(더블버퍼·저널링 전략)

작업 순서 요약

1) 베이스 골격 → 2) LCD·LED 스모크 → 3) 입력 → 4) MIDI TX → 5) MIDI RX/패스 → 6) 라우팅 → 7) UI 모드 → 8) EEPROM → 9) SD/플레이어 → 10) Global → 11) 통합/QA
nano_ardule_midi_controller/step-by-step_coding_roadmap.1756681778.txt.gz · Last modified: by hyjeong