diff --git a/firmware/src/config.h b/firmware/src/config.h index 79b7f92..a0d8e8c 100644 --- a/firmware/src/config.h +++ b/firmware/src/config.h @@ -25,7 +25,9 @@ const int LK_PIN = 2; const int LK_LIGHTS_PER_METER = 60; const float LK_NUM_METERS = 2; const int LK_KEY_SPACING_MM = 7; -const int LK_KEY_LEN_MM = 15; +const int LK_KEY_LEN_MM = 30; +const int LK_OFFSET_MM = 25; // Length in mm from the start of the strip to the first key +const float LK_LIGHTS_PER_MM = LK_LIGHTS_PER_METER / 1000.0; const int LK_NUM_LIGHTS = (int) round(LK_LIGHTS_PER_METER * LK_NUM_METERS); // ======================================== @@ -64,6 +66,9 @@ typedef struct note // 61 Notes from C2 to C7 const int NUM_NOTES = 61; +const int NUM_SHARP_NOTES = 25; +const int NUM_REGULAR_NOTES = NUM_NOTES - NUM_SHARP_NOTES; + const Note notes[] = { {"C2", 36}, {"C#2", 37}, {"D2", 38}, {"D#2", 39}, {"E2", 40}, {"F2", 41}, {"F#2", 42}, {"G2", 43}, {"G#2", 44}, {"A2", 45}, {"A#2", 46}, {"B2", 47}, {"C3", 48}, {"C#3", 49}, {"D3", 50}, {"D#3", 51}, {"E3", 52}, {"F3", 53}, {"F#3", 54}, {"G3", 55}, {"G#3", 56}, {"A3", 57}, {"A#3", 58}, {"B3", 59}, diff --git a/firmware/src/keyboard_lights.cpp b/firmware/src/keyboard_lights.cpp index 8cb24d8..2e195a7 100644 --- a/firmware/src/keyboard_lights.cpp +++ b/firmware/src/keyboard_lights.cpp @@ -4,44 +4,58 @@ #include #include "config.h" +#include "utils.h" #include "Adafruit_NeoPixel.h" +#include class KeyboardLights { private: Adafruit_NeoPixel led_key; + std::unordered_map key_to_light; public: - KeyboardLights() : led_key(4, LK_PIN, NEO_GRB + NEO_KHZ800) {} + KeyboardLights() : led_key(LK_NUM_LIGHTS, LK_PIN, NEO_GRB + NEO_KHZ800) + { + // Initialize key to light map + int regi = 0; + for (int i = NUM_NOTES - 1; i >= 0; i--) + { + auto note = notes[i]; + auto ki = (float) regi; + if (note.name[1] == '#') ki -= 0.5; + + // Calculate the length from the start of the keyboard to the key + ki *= LK_KEY_SPACING_MM + LK_KEY_LEN_MM; + ki += LK_KEY_LEN_MM / 2.0; // Center of the key + + // Calculate the index of the light at the same length position + ki *= LK_LIGHTS_PER_MM; + + // Convert key index to mm, then to light index + key_to_light[i] = (int) round(ki); + + // Increment the regular note index if it's not a sharp note + if (note.name[1] != '#') regi++; + } + + } void begin() { led_key.begin(); } - /** - * Convert a key index to a light index - * - * The light strip's spacing doesn't match the keyboard's spacing, so we need to convert. - * Light strip info are defined by LK_LIGHTS_PER_METER and LK_NUM_LIGHTS. - * Key spacing info are defined by LK_KEY_SPACING_MM and LK_KEY_LEN_MM. - * - * @param key Key index from 0 to 60 - * @return Light index - */ - static int keyToLight(int key) - { - return (int) (key * LK_KEY_SPACING_MM / LK_KEY_LEN_MM * LK_LIGHTS_PER_METER); - } - void hit(int key) { // 1. Calculate the starting index - int start = keyToLight(key); + int start = key_to_light[key]; Serial.printf("Key %d -> Light %d\n", key, start); // 2. Set the color of the lights - led_key.setPixelColor(start, Adafruit_NeoPixel::ColorHSV(0, 255, 255)); + led_key.setPixelColor(start, Adafruit_NeoPixel::ColorHSV(0, 255, 100)); + + led_key.show(); } }; \ No newline at end of file