Grosso modo il y a 3 solutions :
1) PWM basse fréquence, disons 100Hz
Avantage : bon ralentis
Inconvénient : le moteur chauffe plus qu'avec une tension continue et un courant moyen équivalent, surtout si tu alimentes en 20V un moteur 12V. À vue de nez, à faible vitesse de rotation, le moteur dissipera 3 ou 4 fois plus d'énergie que si, pour la même vitesse de rotation, il était alimenté avec une tension continue. Le bruit, la mécanique vibre à la fréquence de la PWM.
2) PWM « haute fréquence », au delà de l'audible, plus de 20kHz
Avantages : pas de bruit, ne chauffe pas car le courant est quasi continu comme si le moteur était alimenté avec une tension continue.
Inconvénients : Le L298 est à l'agonie, il faut un pont en H CMOS qui montent à des fréquences plus élevées (voir les modules Pololu, mais il me semble que j'en avais déjà parlé). Comme avec une tension continue, le ralenti est pas top, on ne peut pas atteindre de très faibles vitesses de rotation.
3) PWM « haute fréquence », au delà de l'audible, plus de 20kHz et asservissement de vitesse (ce qui est appelé compensation de charge dans les décodeurs de locos)
Avantages : les même que en 2) + ralentis impeccables, côté utilisateur la commande n'est pas la PWM à appliquer mais la vitesse de rotation moteur désirée (et indirectement la vitesse de la loco)
Inconvénients : le pont en H qui va bien (voir 2)), matériel pour mesurer la vitesse, logiciel un peu plus compliqué : il mesure la vitesse de rotation du moteur et adapte la PWM de manière à garder cette vitesse voisine d'une consigne. Dans ton cas, la mesure de vitesse peut se faire via un codeur sur l'arbre du moteur (généralement un tout petit aimant qui passe devant un capteur à effet Hall). Ce codeur génère des impulsions qui sont comptées par l'Arduino via une entrée d'interruption. On trouve des moteurs déjà équipés de codeurs, généralement pour la robotique.
Perso, je me lancerais dans ce type de réalisation où je fais la loco de A à Z, je ferais 3 sans la moindre hésitation.