Welt der Fertigung
Sie sind hier: Startseite » Suchen » Lernen » Arduino

Arduino als Taschenrechner

Mathematik auf einem Kleincomputer

Der Arduino ist bestens für Automationsprojekte geeignet. Hier ist es immer mal wieder nötig, mathematische Formeln abzuarbeiten. Doch muss sich der Entwickler stets vor Augen halten, wo diesbezüglich die Grenzen dieses Kleincomputers liegen.

Kleincomputer werden für verschiedenste Dinge verwendet. Darunter sind viele Anwendungen, bei denen es darum geht, mathematische Aufgaben zu lösen, um beispielsweise abhängig vom Ergebnis unterschiedliche Aktionen auszulösen. Die vorhandenen mathematischen Funktionen des Arduino sind überschaubar, doch für viele Zwecke völlig ausreichend, ganz abgesehen davon, dass sich bei entsprechenden Mathematikkenntnissen aus dem vorhandenen Fundus nahezu jede andere Rechenfunktion erstellen lässt.

Zur mathematischen Bibliothek des Arduino zählen unter anderem:

Grundrechenarten: Addition, Subtraktion, Multiplikation, Division
Fortgeschrittene Funktionen: abs, constrain, map, max, min, pow, Potenz, Wurzel
Trigonometrie: sin, cos, tan

Der Arduino bringt von Haus aus einen emulierten Monitor mit, auf dem sich beispielsweise Texte und Rechenergebnisse darstellen lassen. Dadurch kann auf den Einsatz einer externen LCD-Anzeige verzichtet werden. Dieser Monitor wird über das Menü ›Werkzeuge‹ unter dem Menüpunkt ›Serieller Monitor‹ oder über die Tastenkombination STRG+SHIFT+M aufgerufen.

Anfangs präsentiert sich dieser Monitor ohne irgendwelche Einträge:

Beim Programmieren eines Computers muss diesem zunächst mitgeteilt werden, welche Variablen im Programm vorkommen und mit welchen Werten diese gefüllt sind. Diese Variablen müssen einem Datentyp entsprechen, der ihrem Verwendungszweck entspricht. Folgende Datentypen sind beim Arduino im Zusammenhang mit mathematischen Aufgaben besonders wichtig:

  • bool (true oder false)
  • byte (speichert eine vorzeichenlose 8-bit-Zahl von 0 bis 255)
  • char (zum Speichern von ASCII-Zeichen)
  • const (unveränderliche Konstante)
  • double (Flieskommazahl mit doppelter Genauigkeit)
  • float (Flieskommazahl)
  • int (Ganzzahl von -32.768 bis +32.767)
  • long (Ganzahl von -2.147.483.648 bis 2.147.483.647)
  • word (speichert eine vorzeichenlose 16-bit-Zahl von 0 bis 65535)

Erste Mathe-Gehversuche mit dem Arduino:

Um ein erstes Testprogramm zu schreiben, das eine Integerzahl mit den Grundrechenarten manipuliert, sowie daraus die Potenz beziehungsweise die Wurzel berechnet, muss diese Zahl im Sketch zunächst bestimmt und ihr ein Datentyp zugweisen werden. Soll beispielsweise die Zahl 16 als Intergerzahl für die vorgesehenen Berechnungen genutzt werden, so ist eine Variable mit der Bezeichnung ›zahl‹ anzulegen, der der Datentyp ›Integer‹ zugewiesen wird. Dies geschieht wie folgt:

int zahl = 16;

Hinweis: Es ist nicht nötig, direkt der Variablen bereits bei der Deklaration einen Wert zuzuweisen, kann jedoch gemacht werden, wie am obigen Beispiel zu sehen ist. Alternativ ist es möglich, der Variable dann einen Wert zuzuweisen, wenn ein solcher benötigt wird.

Das Ergebnis der Berechnung muss wiederum in einer Variablen abgelegt werden, deren Datentyp ebenfalls vom Typ ›Integer‹ sein soll. Die Anlage ist wie folgt zu tätigen:

Int ergebnis;

In der Variablen ›zahl‹ befindet sich nun die Zahl 16, die als Integerzahl definiert wurde. Mit dieser Zahl lassen sich die im Arduino implementierten mathematischen Funktionen testen. Damit die Ergebnisse auf dem Monitor mitgelesen werden könne, muss dieser zunächst initialisiert werden, was wie folgt geschieht:

Serial.begin(9600);

Ein Sketch für den mathematischen Testlauf könnte auszugsweise so aussehen:

zahl = 16;
Serial.print("Ausgangswert = ");
Serial.println(zahl); //Taste an Monitor ausgeben
ergebnis = zahl + zahl;
Serial.print(zahl); Serial.print(" + "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = zahl - zahl;
Serial.print(zahl); Serial.print(" - "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = 5 * zahl;
Serial.print("5 x "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = 5 / zahl;
Serial.print("5 / "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis =sq(zahl);
Serial.print("Potenz aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis =sqrt(zahl);
Serial.print("Wurzel aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);

Auf dem Monitor wird Folgendes sichtbar:

Es wird deutlich, dass der Befehl ›Serial.print‹ sich bestens eignet, fortlaufend Zeichen auf den Monitor zu drucken, ohne dass der Cursor in die nächste Zeile springt. Dies passiert erst durch den Befehl › Serial.println‹.

Wie sich jedoch zeigt, sind die Ergebnisse nur solange korrekt, solange keine Flieskommaoperationen nötig werden, um das Ergebnis mathematisch richtig auszugeben. So ist die Berechnung 5/16 selbstverständlich nicht Null, sondern 0,3125.

Damit dieser Mangel beseitigt wird, müssen die Variablen ›zahl‹ und ›ergebnis‹ einen Datentyp bekommen, der Flieskommaoperationen erlaubt, was beispielsweise mit ›float‹ möglich wird.

Die beiden Variablen werden demnach wie folgt umgeschrieben:

float zahl = 16;
float ergebnis;

Das Ergebnis des erneuten Rechendurchlaufs ist:

Es zeigt sich, dass die Berechnung nun passt.

Möchte man mehr Nachkommastellen in den Berechnungen haben, so muss im Befehl Serial.println oder Serial.print lediglich die gewünschte Nachkommastelle angegeben werden. Ein allgemeines Beispiel wäre: Serial.println(Flieskommazahl, Nachkommastelle). Im Sketch würde der Befehl mit fünf Nachkommastellen beispielsweise wie folgt aussehen:

Serial.println(ergebnis,5);

Der Monitor präsentiert den Rechenlauf wie folgt:

Trigonometrische Funktionen:

Selbstverständlich besitzt der Arduino-Befehlssatz auch trigonometrische Funktionen, sodass es mühelos möglich ist, beispielsweise die Länge einer Ankathete eines Dreiecks zu berechnen, wenn ein Winkel und beispielsweise die Gegenkathete gegeben sind.

Die Deklaration der trigonometrischen Funktionen lauten:

Sin();
cos();
tan();

Zwischen den Klammern ist jeweils der Winkelwert einzutragen, der allerdings in Bogenmaß erwartet wird. Aus diesem Grund muss im Sketch eine weitere Variable definiert werden, um den umgerechneten Wert aufzunehmen. Nachfolgend ein Beispiel:

Float winkel;

Um einen Winkel, der in Dezimalgrad vorliegt, in Bogenmaß umzurechnen, ist folgende Formel zu nutzen:

Soll beispielsweise der Winkel von 28 Grad in Bogenmaß umgerechnet werden, so ergibt sich folgendes Ergebnis:

Da im vorliegenden Beispiel die Variable ›zahl‹ mit dem gewünschten Rechenwert belegt ist, genügt es, diese Variable zur Berechnung im Zusammenhang mit den trigonometrischen Funktionen heranzuziehen. So wird beispielsweise der in der Variablen ›zahl‹ stehende Winkelwert von Dezimalgrad in Bogenmaß wie folgt berechnet:

Der Sinus ergibt sich anschließend wie folgt:

Am Monitor erscheint folgende Ausgabe:

Wie zu sehen ist, wurde die Ergebnisausgabe auf 12 Nachkommastellen ausgeweitet, wodurch eine Prüfung auf die Rechengenauigkeit des Datentyps ›float‹ möglich wird. Es zeigt sich, dass dieser Datentyp für sehr genaue Berechnungen ungeeignet ist. So wird beispielsweise als Ergebnis für den Sinus aus 28 der Wert

ausgegeben. Ein Taschenrechner gibt hingegen das Ergebnis

aus. Somit ergibt sich ab der siebten Stelle eine Abweichung, die durchaus geeignet ist, bei hochgenauen Berechnungen einen nicht hinnehmbaren Fehler zu produzieren. Aus diesem Grund einet sich der Arduino nur eingeschränkt für mathematisch exakte Berechnungen. Es fehlt ihm ein mathematischer Co-Prozessor. Da hilft auch der Datentyp ›double‹ nichts, der eine doppelte Genauigkeit der Flieskommaberechnungen verspricht.

Nichtsdestotrotz bleiben noch viele Projekte, bei denen die Rechengenauigkeit des Arduino völlig ausreichend ist. Nachfolgend noch ein Auszug des Programms, um das Ergebnis der Ausführungen nachvollziehen zu können.

zahl = 28;
winkel = zahl*PI/180;
Serial.print("Ausgangswert = ");
Serial.println(zahl);
ergebnis = zahl + zahl;
Serial.print(zahl); Serial.print(" + "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = zahl - zahl;
Serial.print(zahl); Serial.print(" - "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = 5 * zahl;
Serial.print("5 x "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis = 5 / zahl;
Serial.print("5 / "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis,5);
ergebnis =sq(zahl);
Serial.print("Potenz aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis =sqrt(zahl);
Serial.print("Wurzel aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis);
ergebnis =sin(winkel);
Serial.print("Sinus aus "); Serial.print(zahl); Serial.print(" = "); Serial.println(ergebnis,12);
ergebnis =cos(winkel);
Serial.print("Cosinus aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis,12);
ergebnis =tan(winkel);
Serial.print("Tangens aus "); Serial.print(zahl); Serial.print(" = ");
Serial.println(ergebnis,12);

War dieser Artikel für Sie hilfreich?

Bitte bewerten Sie diese Seite durch Klick auf die Symbole.

Zugriffe heute: 1 - gesamt: 4681.