// https://wokwi.com/projects/413295477815552001
// for https://forum.arduino.cc/t/how-to-cancel-out-a-log-curve/1317310

int input = 128;
int log_output = 0;
int exp_output = 0;
const byte MotorPin = 11;

// %,RPM Lookup Table
int LUT[][2] = {
  {0, 0},
  {9, 1},
  {10, 60},
  {20, 100},
  {40, 130},
  {60, 140},
  {80, 145},
  {100, 150},
};

int lookUpRPM(int rpm) {
  int Y0 = LUT[0][1];
  int X0 = LUT[0][0];
  for (auto &row : LUT) {
    if (row[1] == rpm) return row[0];
    if (row[1] >= rpm) return map(rpm, Y0, row[1], X0, row[0]);
    Y0 = row[1];
    X0 = row[0];
  }
  return X0;
}

void setup() {
  Serial.begin(115200);
  pinMode(MotorPin, OUTPUT);
}

void loop() {
  static int lastRPM = 0;
  int input = map(analogRead(A0), 0, 1023, 0, 200);
  if (input != lastRPM) {
    lastRPM = input;

    log_output = log(input);
    exp_output = exp(0.5 * input);
    int dutyPct = lookUpRPM(input);
    int dutyPWM = dutyPct * 255 / 100;

    Serial.println();
    Serial.print("Input is: "); Serial.println(input);
    Serial.print("log output is: "); Serial.println(log_output);
    Serial.print("exp output is: "); Serial.println(exp_output);
    Serial.print("LUT duty is: "); Serial.println(dutyPct);
    Serial.print("LUT PWM is: "); Serial.println(dutyPWM);
    analogWrite(MotorPin, dutyPWM);
  }
}