Mathematische Funktionen auf dem PIC ohne Library optimieren

Mathematische Funktionen auf dem PIC ohne Library optimieren ist ein Thema, das in der Praxis schneller relevant wird, als viele erwarten. Sobald ein PIC-Mikrocontroller mehr tun soll als „Pins schalten“, tauchen Berechnungen auf: Sensorwerte skalieren, gleitende Mittelwerte bilden, Kalibrierkurven auswerten, Winkel oder Drehzahl bestimmen, PWM-Regelungen stabilisieren oder Messwerte für ein Display aufbereiten. Wer dann einfach math.h einbindet und mit sin(), sqrt() oder pow() arbeitet, erlebt auf kleinen PIC16/PIC18 häufig eine böse Überraschung: Der Code wird groß, die Laufzeit steigt spürbar, und das Timing wird weniger deterministisch. Genau hier setzt Optimierung an: Viele mathematische Funktionen lassen sich auf 8-Bit-PICs deutlich schneller und kompakter umsetzen, wenn Sie bewusst auf Library-Funktionen verzichten und stattdessen Festkomma-Arithmetik, Lookup-Tabellen, geeignete Approximationen und „Strength Reduction“ verwenden. Dieser Artikel zeigt Ihnen praxistaugliche Strategien, mit denen Sie Mathematik auf PICs effizient machen, ohne die Wartbarkeit zu opfern – inklusive konkreter Fehlerbudgets, geeigneter Zahlenformate und typischer Muster für Trigonometrie, Wurzeln und Divisionen.

Warum die Standard-Library auf kleinen PICs oft problematisch ist

Auf vielen PIC16- und PIC18-Controllern gibt es keine Hardware-FPU. Gleitkommaoperationen und komplexe Funktionen wie Sinus, Logarithmus oder Potenzen müssen dann als Software-Routinen ausgeführt werden. Das ist grundsätzlich korrekt, aber häufig teuer: viel Flash für die benötigten Routinen, mehr RAM für temporäre Werte und vor allem viele Taktzyklen. Das macht sich besonders bemerkbar, wenn Berechnungen in einem festen Zeitraster laufen sollen (z. B. alle 1 ms in einer Regelung) oder wenn die CPU die meiste Zeit schlafen soll (Low-Power).

  • Codegröße: Schon ein einzelner Aufruf kann große Teile der mathematischen Runtime nachziehen.
  • Laufzeit: Float-Operationen sind auf 8-Bit-MCUs typischerweise deutlich langsamer als Integer.
  • Timing: Echtzeitverhalten leidet, wenn „teure“ Funktionen in kritischen Pfaden liegen.
  • Debugging: Library-Aufrufe erschweren manchmal die Nachvollziehbarkeit und Optimierung.

Wenn Sie mit Microchip-Tools arbeiten, sind MPLAB X IDE und die MPLAB XC Compiler die üblichen Grundlagen, aber die Performance-Entscheidung liegt bei Ihnen: Welche Mathematik muss wirklich „hochpräzise“ sein, und wo reicht eine kontrollierte Näherung?

Grundsatzentscheidung: Genauigkeit definieren, bevor Sie optimieren

Optimierung ohne Ziel führt zu Chaos. Definieren Sie daher zuerst das erforderliche Fehlerbudget: Wie viele Nachkommastellen sind physikalisch überhaupt sinnvoll? Viele Sensoren liefern keine „echten“ 0,001 °C, selbst wenn Ihre Rechnung das könnte. Oft sind 0,1 °C oder 1 mV realistisch, während die restliche Genauigkeit nur Rechenzeit kostet.

  • Messrauschen: Wenn der Sensor ±2 LSB rauscht, lohnt keine Rechenpräzision unterhalb dieses Niveaus.
  • Kalibrierung: Eine perfekte Funktion ohne passende Kalibrierung bringt wenig.
  • Regelung: Zu hohe Rechenauflösung kann sogar instabil wirken, wenn sie nur Rauschen verstärkt.

Ein pragmatisches Ziel ist oft: „maximaler Fehler kleiner als 0,5 LSB im finalen Ausgabewert“ oder „maximaler Fehler kleiner als 1 % vom Messbereich“. Erst danach wählen Sie das Verfahren.

Festkomma statt Float: Der größte Hebel für PIC16/PIC18

Die wichtigste Optimierung ist meist der Wechsel von Floating Point zu Fixed Point. Sie speichern reale Werte als Integer mit fester Skalierung (z. B. Temperatur in Zehntelgrad, Spannung in Millivolt oder ein Q-Format mit Bruchbits). Die CPU rechnet dann mit Integern, was deutlich schneller und kompakter ist. Grundlagen zur Festkommaarithmetik finden Sie beispielsweise unter Festkommaarithmetik.

Q-Format kurz und praxistauglich

Mit F Bruchbits gilt:

x_fixed = x_real × 2F

Multiplikation zweier Q-Werte (mit Rückskalierung):

p= a×b 2F

Wichtig: Auf 8-Bit-PICs benötigen Sie dafür praktisch immer ein größeres Zwischenformat (z. B. 32 Bit), um Überläufe zu vermeiden.

Strength Reduction: Teure Operationen in billige umwandeln

Viele „mathematische“ Probleme sind in Wahrheit nur ungünstig formuliert. Strength Reduction bedeutet: Sie ersetzen teure Operationen (Division, Multiplikation, Potenzen) durch schnellere Varianten (Shift, Additionen, Tabellen, Vorfaktoren).

  • Division durch Potenzen von 2: / 8 wird zu >> 3.
  • Multiplikation mit Konstanten: * 10 kann zu (x<<3) + (x<<1) werden.
  • Konstante Faktoren auslagern: Skalierungsfaktoren vorab berechnen und als Integer-Konstante speichern.
  • Reihenfolge optimieren: Erst skalieren, dann runden, dann begrenzen – statt mehrfach umzurechnen.

Diese Maßnahmen sind besonders effektiv, wenn die Berechnung in Schleifen oder Interrupt-Pfaden läuft.

Lookup-Tabellen: Schnell, deterministisch, gut kontrollierbar

Wenn Sie eine Funktion immer wieder auswerten (z. B. Sinus, Gamma-Korrektur, NTC-Kennlinie), sind Lookup-Tabellen oft der beste Kompromiss. Sie speichern vorab berechnete Werte im Flash (Programmspeicher) und holen sie zur Laufzeit ab.

  • Vorteil: Sehr schnell, konstante Laufzeit.
  • Vorteil: Fehler ist kontrollierbar über Tabellengröße und Interpolation.
  • Nachteil: Benötigt Flash; bei sehr großen Tabellen muss man clever komprimieren.

Interpolation als Qualitäts-Booster

Mit linearer Interpolation können Sie die Tabellengröße deutlich reduzieren. Für eine Funktion f zwischen zwei Stützstellen:

y=y_0 + xx_0 x_1x_0 × y_1y_0

In Fixed Point wird das zu einer Kombination aus Subtraktion, Multiplikation und Shift. Für viele Sensor- und UI-Anwendungen ist das mehr als ausreichend.

Polynom-Approximationen: Wenig Speicher, gute Genauigkeit

Wenn Flash knapp ist oder Sie eine Funktion für einen begrenzten Bereich brauchen, sind Polynomapproximationen häufig ideal. Sie approximieren f(x) durch ein Polynom niedrigen Grades. Typischerweise nutzen Sie dafür:

  • Taylor-Reihen: einfach, aber nicht immer optimal im Fehlerverlauf.
  • Minimax/Chebyshev-Approximation: gleichmäßiger Fehler über den Bereich, oft bessere Effizienz. Als Einstieg eignet sich Minimax Approximation oder Chebyshev-Polynome.

Ein praktisches Muster ist Horner-Schema, weil es Multiplikationen minimiert:

P(x)= (((a_3x+a_2)x+a_1)x+a_0)

Damit wird aus „viele Potenzen“ eine Kette aus Multiplikation und Addition, ideal für PICs.

CORDIC: Trigonometrie und mehr ohne Multiplikation

Für Sinus, Cosinus, Arctan und verwandte Funktionen kann CORDIC sehr attraktiv sein. CORDIC arbeitet iterativ mit Shifts und Additionen statt mit klassischen Multiplikationen. Das passt gut zu MCUs ohne schnelle Multiplikationseinheiten. Eine verständliche Übersicht finden Sie unter CORDIC.

  • Vorteil: Keine echten Multiplikationen nötig (nur Shifts/Additionen).
  • Vorteil: Gute Genauigkeit mit wenigen Iterationen, gut kontrollierbar.
  • Nachteil: Iterativ; pro Iteration kostet es Zeit, aber sehr deterministisch.

CORDIC lohnt sich besonders, wenn Sie Winkelberechnungen häufiger brauchen und eine LUT zu groß wäre oder eine Polynomapproximation in Ihrem Wertebereich kompliziert wird.

Wurzel, Inverses und Division: Schnelle iterative Verfahren

Auf PICs ist Division teuer, und sqrt() aus der Library ebenfalls. Häufig reichen iterative Verfahren, die schnell konvergieren und in Integern laufen.

Ganzzahl-Square-Root (Integer sqrt)

Wenn Sie nur die ganzzahlige Wurzel benötigen (z. B. für Beträge oder Normen), können Sie ein Integer-Verfahren nutzen, das ohne Float auskommt. Für viele Anwendungen ist eine ganzzahlige Wurzel plus sinnvolle Skalierung ausreichend.

Newton-Raphson für 1/x oder sqrt

Newton-Raphson ist für Festkomma attraktiv, wenn Sie eine gute Startnäherung haben. Für das Inverse gilt grundsätzlich:

y_n+1 = y_n × (2x×y_n)

Mit 1–3 Iterationen erhalten Sie oft schon sehr brauchbare Genauigkeit, wenn die Skalierung sauber gewählt ist. Das kann sich lohnen, wenn Sie viele Divisionen durch denselben Wert ersetzen möchten (z. B. Normierung, Umrechnungen).

Trigonometrie pragmatisch: Sin/Cos ohne libm

Sinus und Cosinus werden auf kleinen PICs häufig gebraucht (z. B. Motorregelung, IMU, Phasenberechnung). Ohne Library haben Sie mehrere solide Optionen:

  • Quarter-Wave-LUT: Speichern Sie nur 0–90° und spiegeln Sie den Rest über Symmetrie. Spart Flash.
  • LUT + lineare Interpolation: Gute Qualität bei moderater Tabelle.
  • Polynom im kleinen Bereich: Sehr effizient, wenn Winkelbereich begrenzt ist (z. B. ±15°).
  • CORDIC: Wenn Sie auch atan2 oder Winkel zurück brauchen.

Ein häufig unterschätzter Trick ist Symmetrie: Sinus und Cosinus lassen sich über Quadranten abbilden, sodass Sie nur einen kleinen Bereich approximieren müssen.

Exponent, Log und Pow: Oft ist das Problem anders lösbar

Funktionen wie log(), exp() oder pow() wirken „unverzichtbar“, sind auf kleinen PICs aber oft der Punkt, an dem die Library explodiert. Prüfen Sie, ob die Anforderung wirklich mathematisch ist oder ob eine alternative Darstellung reicht:

  • dB, Pegel, Helligkeit: Häufig genügt eine Lookup-Tabelle oder eine stückweise lineare Kennlinie.
  • Potenz mit ganzzahligem Exponenten: Nutzen Sie Exponentiation by Squaring statt allgemeinem pow().
  • Wurzel/Quadrat: Oft reichen feste Spezialfälle: x*x, isqrt, statt allgemeiner Potenzen.

Stückweise lineare Approximation: Der „Industrie-Kompromiss“

Für Kennlinien (NTC, Drucksensor, Batteriemessung) ist eine stückweise lineare Approximation extrem praxisnah. Sie definieren Segmente mit Steigung und Offset, z. B. als Tabelle aus (x0, y0, m). Zur Laufzeit suchen Sie das passende Segment (oft per Bereichsprüfung oder Binärsuche) und berechnen:

y=y_0+m×(xx_0)

Mit Festkomma-Steigungen wird das sehr schnell. Der Vorteil: Sie können die Segmente so wählen, dass der Fehler überall unter Ihrem Ziel bleibt.

Skalierung, Rundung und Sättigung: Damit Optimierung nicht zu Bugs führt

Optimierte Mathematik scheitert selten an der Idee, sondern an Details: Überläufe, Vorzeichenfehler, unklare Einheiten, falsch gesetzte Shifts. Legen Sie deshalb klare Regeln fest.

  • Einheiten dokumentieren: z. B. „mV“, „0,1°C“, „Q8.8“.
  • Zwischenergebnisse größer wählen: Multiplikationen in 32 Bit, auch wenn Ergebnis 16 Bit ist.
  • Rundung statt Trunkation: Vor dem Shift ein halbes LSB addieren, um systematische Fehler zu reduzieren.
  • Sättigung (Clamping): Bei Ausreißern lieber begrenzen als überlaufen lassen.

Optimierung im Workflow: Messen, nicht raten

Ohne Messung optimieren Sie im Blindflug. Bewährte Vorgehensweisen sind:

  • Zyklusmessung per GPIO: Pin vor/nach der Funktion toggeln und mit Logic Analyzer messen.
  • Vergleichsrechnungen: Referenz (z. B. auf PC mit Double) gegen die PIC-Näherung testen.
  • Testvektoren: Randfälle (min/max), typische Werte und Ausreißer systematisch prüfen.
  • Codegröße beobachten: Nach jeder Änderung Flash-Verbrauch kontrollieren.

Ein klarer Gewinn entsteht meist durch wenige, gezielte Maßnahmen: Festkomma, LUT, Horner-Polynom und das Entfernen unnötiger Divisionen.

Praktische Auswahlhilfe: Welche Technik passt zu welcher Funktion?

  • Lineare Umrechnung, Kalibrierung: Festkomma + einfache Multiplikation/Division, ggf. Vorfaktoren.
  • NTC/komplizierte Kennlinien: Stückweise linear oder LUT + Interpolation.
  • Sin/Cos im vollen Bereich: Quarter-Wave-LUT oder CORDIC.
  • atan2/Winkel: CORDIC oder LUT/Approximation im relevanten Bereich.
  • sqrt: Integer-sqrt oder Newton-Raphson, abhängig von Genauigkeit.
  • log/exp/pow: Möglichst vermeiden; sonst LUT oder minimax im begrenzten Bereich.

Outbound-Links für Vertiefung und Referenzen

IoT-PCB-Design, Mikrocontroller-Programmierung & Firmware-Entwicklung

PCB Design • Arduino • Embedded Systems • Firmware

Ich biete professionelle Entwicklung von IoT-Hardware, einschließlich PCB-Design, Arduino- und Mikrocontroller-Programmierung sowie Firmware-Entwicklung. Die Lösungen werden zuverlässig, effizient und anwendungsorientiert umgesetzt – von der Konzeptphase bis zum funktionsfähigen Prototyp.

Diese Dienstleistung richtet sich an Unternehmen, Start-ups, Entwickler und Produktteams, die maßgeschneiderte Embedded- und IoT-Lösungen benötigen. Finden Sie mich auf Fiverr.

Leistungsumfang:

  • IoT-PCB-Design & Schaltplanerstellung

  • Leiterplattenlayout (mehrlagig, produktionstauglich)

  • Arduino- & Mikrocontroller-Programmierung (z. B. ESP32, STM32, ATmega)

  • Firmware-Entwicklung für Embedded Systems

  • Sensor- & Aktor-Integration

  • Kommunikation: Wi-Fi, Bluetooth, MQTT, I²C, SPI, UART

  • Optimierung für Leistung, Stabilität & Energieeffizienz

Lieferumfang:

  • Schaltpläne & PCB-Layouts

  • Gerber- & Produktionsdaten

  • Quellcode & Firmware

  • Dokumentation & Support zur Integration

Arbeitsweise:Strukturiert • Zuverlässig • Hardware-nah • Produktorientiert

CTA:
Planen Sie ein IoT- oder Embedded-System-Projekt?
Kontaktieren Sie mich gerne für eine technische Abstimmung oder ein unverbindliches Angebot. Finden Sie mich auf Fiverr.

 

Related Articles