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