// // config.h // // Piano LED Visualizer on Circle - all tunable parameters. // // Every value in this file is a product decision that Phase 0 of // PIANO-LED-CIRCLE-PLAN.md exists to answer. Bench-test on Raspberry Pi OS // first, then transcribe the answers here and build once. // #ifndef _config_h #define _config_h // -------------------------------------------------------------------------- // Keybed and strip geometry (plan section 6) // -------------------------------------------------------------------------- // An 88-key keybed spans MIDI notes 21 (A0) through 108 (C8). #define MIDI_NOTE_MIN 21 #define MIDI_NOTE_MAX 108 #define KEY_COUNT (MIDI_NOTE_MAX - MIDI_NOTE_MIN + 1) // 88 // LEDs per key. At 144 LEDs/m, 2 per key spans 1.222m, which lines up with a // standard 88-key keybed almost exactly. #ifndef LEDS_PER_KEY #define LEDS_PER_KEY 2 #endif #define LED_COUNT (KEY_COUNT * LEDS_PER_KEY) // 176 // Strip orientation. Pixel 0 of a WS2812B strip is at the end the data line // enters. Decide this AFTER the strip is physically mounted, then flip this // one flag. // // 0 = pixel 0 is at the bass end -> led = (note - 21) * 2 // 1 = pixel 0 is at the treble end -> led = (108 - note) * 2 #ifndef STRIP_REVERSED #define STRIP_REVERSED 0 #endif // -------------------------------------------------------------------------- // Power safety (plan section 7) - NOT optional // -------------------------------------------------------------------------- // // 176 LEDs at full white draw ~60mA each = 10.56A theoretical maximum, against // a 6A supply. Real playing never approaches that (a ten-finger chord lights 20 // LEDs, ~1.2A), but a firmware bug that whites out the strip would brown out // the rail. These two clamps make that unreachable rather than unlikely. // Global brightness ceiling, applied to every channel of every pixel. // 0-255. At 96 a full-strip white would draw roughly 4A, still inside 6A. #ifndef GLOBAL_BRIGHTNESS #define GLOBAL_BRIGHTNESS 96 #endif // Hard cap on simultaneously lit keys. Beyond this, further held notes are // tracked but not lit, so current draw stays bounded no matter what arrives // on the wire. 20 keys is a ten-finger chord; 30 leaves room for pedal-held // passages without ever approaching the supply limit. #ifndef MAX_LIT_KEYS #define MAX_LIT_KEYS 30 #endif // -------------------------------------------------------------------------- // Colour (Phase 0 decides these against the actual diffuser) // -------------------------------------------------------------------------- // // Colours look substantially different through a diffuser than on bare strip. // Do not finalise these from a photo. // Colour for a played key, before brightness scaling. #ifndef NOTE_COLOR_R #define NOTE_COLOR_R 0 #endif #ifndef NOTE_COLOR_G #define NOTE_COLOR_G 140 #endif #ifndef NOTE_COLOR_B #define NOTE_COLOR_B 255 #endif // Distinct colour for a "next note to play" hint driven by learning software // on the PC (plan Phase 3). Reached over MIDI channel HINT_MIDI_CHANNEL. #ifndef HINT_COLOR_R #define HINT_COLOR_R 255 #endif #ifndef HINT_COLOR_G #define HINT_COLOR_G 80 #endif #ifndef HINT_COLOR_B #define HINT_COLOR_B 0 #endif // -------------------------------------------------------------------------- // Velocity response // -------------------------------------------------------------------------- // 1 = velocity scales pixel brightness, 0 = every key lights at full // GLOBAL_BRIGHTNESS regardless of how hard it was struck. #ifndef VELOCITY_SENSITIVE #define VELOCITY_SENSITIVE 1 #endif // Floor for velocity scaling, as a percentage. A pianissimo note should still // be clearly visible, so velocity maps onto [VELOCITY_FLOOR_PCT, 100] rather // than onto [0, 100]. #ifndef VELOCITY_FLOOR_PCT #define VELOCITY_FLOOR_PCT 35 #endif // -------------------------------------------------------------------------- // MIDI routing // -------------------------------------------------------------------------- // Channel carrying notes actually played on the piano. 0-15 on the wire // (channel 1 in a DAW), or MIDI_CHANNEL_ANY to accept every channel. #define MIDI_CHANNEL_ANY 0xFF #ifndef NOTE_MIDI_CHANNEL #define NOTE_MIDI_CHANNEL MIDI_CHANNEL_ANY #endif // Channel reserved for Phase 3 "light the next key" hints from the PC. Kept // separate from played notes so the two never overwrite each other. Set to // MIDI_CHANNEL_NONE to ignore hints entirely. #define MIDI_CHANNEL_NONE 0xFE #ifndef HINT_MIDI_CHANNEL #define HINT_MIDI_CHANNEL 15 // channel 16 in a DAW #endif // -------------------------------------------------------------------------- // Hardware wiring (VERIFIED against circle/addon/WS28XX, do not guess) // -------------------------------------------------------------------------- // // CWS28XXStripe clocks the WS2812B waveform out over SPI at a fixed 6.4MHz, // encoding each LED bit as one SPI byte. On SPI master device 0 that puts the // data line on: // // MOSI = GPIO10 (BCM) = physical pin 19 // // Feed that through a 74AHCT125 to get a 5V logic level at the strip, and tie // the Pi's ground to the LED supply ground. See plan section 7. #ifndef SPI_MASTER_DEVICE #define SPI_MASTER_DEVICE 0 #endif #endif