[F] Fix position calculation
This commit is contained in:
@@ -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},
|
||||
|
||||
@@ -4,44 +4,58 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
#include "Adafruit_NeoPixel.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class KeyboardLights
|
||||
{
|
||||
private:
|
||||
Adafruit_NeoPixel led_key;
|
||||
std::unordered_map<int, int> 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();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user