Die Aufteilung in Positive / Negative Fälle machte den Code ziehmlich unübersichtlich und ganz nebenbei auch langsam.
Soweit ich weiss kriegt GCC die optimierung schon soweit hin, dass man auch ruhig .... % 1024 schreiben kann. Da werden dann schon shifts draus, die auch für negative Zahlen gehen.
Beim AVR sind aber die Shifts auch nicht besonders schnell. Wenn es wirklich schnell sein soll, sollte man ganze Bytes als Nachkomma-anteil haben, und dann mit UNION arbeiten. Ich sehe noch kein Überlaufprobem wenn man jeweils 16 Bits nach der Multiplication wegläßt. Man muß sich dann nur beim Integralgleid ein wenig mit dem Wert zurückhalten, aber so groß sollte das ja ohnehin nicht werden, sonst wäre der Integral anteil einfach zu groß in der Summe.

Das macht dann schon mal den Code nur etwa 1/3 so lang und vermutlich auch 2-3 mal schneller. Eventuelle Fehler lassen sich dann auch besser finden.

Unabhängig davon sollte man die 3 Anteile erstmal mit voller Auflösung zusammenrechenen und dann erst die Rundung machen.


Der Effekt mit dem I-Glied spricht wirklich für ein Überlaufproblem. Wenn man von 32 Bits (Long) noch 24 Bits per shift unterdrückt, kann das auch nichts werden, da bleichen dann ja nur 8 Bit über, und damit wird es nie mehr als die 1,3 V. So viele Nachkommastellen für die Rundung sind nicht nötig. Also statt:
((Ki*e_sum + 838860 >> 24);
besser
((Ki*(e_sum>>8 ) + (1<<15)) >> 16);
Wenn man nur ganz kleine Werte für Ki braucht, dann auch:
((Ki*e_sum + (1<<15)) >> 16);
mit angepaßtem zahlenwert für Ki.

Beim Differenzgleid hat man eventuel ein Rauschproblem: wenn man die Zeit über die man die Steigung berechnet zu kurz hat, kreigt man leicht ein starkes Rauschen rein: Die ADC Werte ändern sich bei aufeinanderfolgenden Werten nur sehr wenig. Für die Differenz hat man dann nur ein paar weniger quantisierte Werte von vielleicht nur - 5 bis +5. Wenn der Aktor sehr schnell realgiert kann das ein Problem werden.

Es kann aber auch gut gehen und man bekommt dann ein überlagertes Dithering für die Ausgabewerte. Die Regelung kann dann trotzdem funktionieren, zum Teil sogar besser als ohne den Effekt zu erwarten wäre, aber die Parameter sind nicht mehr unbedingt das, was man von der Theorie erwartet.