Eingangsfrequenz

Was mir einfällt ist:

void decoder()
{
counter --;
counter += 2*digitalRead(pin2);
}

Das ist die Interruptroutine durch eine Flanke an Phase 1 des Drehgebers aufgerufen wird. Es könnte sein daß die Anweisung "counter --;" zuviel Zeit in Anspruch nimmt und die 2. Phase bereits wieder Status geändert hat bevor Du deren Zusatand in "counter += 2*digitalRead(pin2);" ausliest.
Bei 20V läuft der Motor dann langsam genug, daß es nicht passiert.

Versuch mal die Sache umzukehren:

void decoder()
{
counter += 2*digitalRead(pin2);
counter --;
}

Grüß Uwe