diff --git a/src/modules/needy_finetuner/needy_finetuner.ino b/src/modules/needy_finetuner/needy_finetuner.ino index e71dc17..c31245a 100644 --- a/src/modules/needy_finetuner/needy_finetuner.ino +++ b/src/modules/needy_finetuner/needy_finetuner.ino @@ -4,28 +4,35 @@ #include #define PIN_GAUGE 3 +#define PIN_LED 2 #define PIN_SLIDER A7 #define ADJUSTMENT_PERIOD_MS 15000 -#define SLEEP_PERIOD_MS 5000 +#define SLEEP_PERIOD_MS random(20000, 30000) + +#define SLIDER_EDGE_AVOIDANCE 50 #define ARRAY_LENGTH(array) ((sizeof array)/(sizeof (array[0]))) uint32_t deadline = 0; int16_t target = 0; +int16_t previousSliderValue = 0; int16_t previousTarget = 0; uint8_t moved = 0; void setup() { Serial.begin(115200); + Serial.println("Needy finetuner by Midgard"); - obus_module::setup(OBUS_TYPE_NEEDY, OBUS_NEEDY_ID_DEVELOPMENT); + /*obus_module::setup(OBUS_TYPE_NEEDY, OBUS_NEEDY_ID_DEVELOPMENT);*/ pinMode(PIN_GAUGE, OUTPUT); + pinMode(PIN_LED, OUTPUT); pinMode(PIN_SLIDER, INPUT); - target = getSliderValue(); + previousSliderValue = getSliderValue(); + target = previousSliderValue; previousTarget = target; } @@ -35,6 +42,7 @@ uint16_t getSliderValue() { for (int i = 1; i < ARRAY_LENGTH(stops); i++) { if (value <= stops[i]) return (value - stops[i - 1]) * 170 / (stops[i] - stops[i-1]) + (i-1)*170 - 1; } + return 0; } void gauge(unsigned char value) { @@ -48,61 +56,78 @@ bool is_in_tune(int16_t target, int16_t sliderValue) { return abs(target - sliderValue) <= 20; } -/* -int amountOfLedsToLight(timeLeft, target, sliderValue) { + +int ledPattern(int32_t timeLeft, int16_t target, int16_t sliderValue) { if (is_in_tune(target, sliderValue)) { return 0; } - if (timeLeft <= ADJUSTMENT_PERIOD_MS * 2 / 4) return 3; - if (timeLeft <= ADJUSTMENT_PERIOD_MS * 3 / 4) return 2; - if (timeLeft <= ADJUSTMENT_PERIOD_MS * 4 / 4) return 1; + if (timeLeft <= ADJUSTMENT_PERIOD_MS / 4 * 1) return 3; + if (timeLeft <= ADJUSTMENT_PERIOD_MS / 4 * 2) return 3; + if (timeLeft <= ADJUSTMENT_PERIOD_MS / 4 * 3) return 2; + if (timeLeft <= ADJUSTMENT_PERIOD_MS / 4 * 4) return 1; + return 0; } -*/ +int ledCycle = 0; + void loop() { - bool is_message_valid = obus_module::loopNeedy(&message, callback_game_start, callback_game_stop); + /*bool is_message_valid = obus_module::loopNeedy(&message, callback_game_start, callback_game_stop);*/ - int16_t sliderValue = getSliderValue(); + int16_t sliderValue = (getSliderValue() + previousSliderValue) / 2; + previousSliderValue = getSliderValue(); int16_t gaugeValue = previousTarget - sliderValue; int32_t timeLeft = deadline - millis(); if (timeLeft <= ADJUSTMENT_PERIOD_MS) { // Require a movement being detected for at least 2 successive loops, to combat jitter - if (moved >= 2) { + if (moved >= 3) { gaugeValue = target - sliderValue; } else { - if (abs(sliderValue - previousTarget) > 2) moved++; + if (abs(sliderValue - previousTarget) > 4) moved++; else moved = 0; - gaugeValue = (ADJUSTMENT_PERIOD_MS - timeLeft) * 127 / ADJUSTMENT_PERIOD_MS; - if (target > previousTarget) { + gaugeValue = (ADJUSTMENT_PERIOD_MS - timeLeft) * 107 / ADJUSTMENT_PERIOD_MS + 20; + if (target < previousTarget) { gaugeValue *= -1; } } } - /*amountLeds = amountOfLedsToLight(timeLeft, target, sliderValue);*/ + ledCycle++; + bool ledOn = false; + if (ledCycle > 0b1111) ledCycle = 0; + switch (ledPattern(timeLeft, target, sliderValue)) { + case 1: if ((ledCycle >> 3) & 1) ledOn = true; break; + case 2: if ((ledCycle >> 2) & 1) ledOn = true; break; + case 3: if ((ledCycle >> 1) & 1) ledOn = true; break; + case 4: if ( ledCycle & 1) ledOn = true; break; + default: break; + } + if (ledOn) digitalWrite(PIN_LED, 1); + else digitalWrite(PIN_LED, 0); if (timeLeft < 0) { - deadline = millis() + ADJUSTMENT_PERIOD_MS + SLEEP_PERIOD_MS; - previousTarget = sliderValue; - do { - target = random(1023 - 2*30) + 30; - } while(abs(target - previousTarget) < 50); - moved = 0; + Serial.println("---"); if (!is_in_tune(target, sliderValue)) { obus_module::strike(); - target = sliderValue; + Serial.println("Deadline missed, strike!"); } + + deadline = millis() + ADJUSTMENT_PERIOD_MS + SLEEP_PERIOD_MS; + previousTarget = sliderValue; + do { + target = random(1023 - 2*SLIDER_EDGE_AVOIDANCE) + SLIDER_EDGE_AVOIDANCE; + } while(abs(target - previousTarget) < 50); + moved = 0; } if (gaugeValue > 127) gaugeValue = 127; else if (gaugeValue < -127) gaugeValue = -127; gauge(gaugeValue + 127); - delay(50); + delay(40); } void callback_game_start(uint8_t puzzle_modules) {