Vorwissen: Simon Grafs Kurs „Vom Transistor zur CPU“
In diesem Auftrag geht es darum, den Arduino und dessen Programmiersprache C++ kennenzulernen.
Hier geht es darum, sich mit den wichtigsten Sprachelementen von C++ vertraut zu machen. Verwende dazu parallel das Arduino Programmieren Tutorial.
Diese Aufgabe kann auch mit dem Simulator (https://wokwi.com/projects/294342288335700490) gelöst werden. Verwende aber besser deinen Arduino.
primes
die Primzahlen $2,3,5,7,11,13$. Gebe diese im Sekundentakt der Reihe nach aus. Ist der Code am Ende des Arrays angelangt, so soll er wieder von vorne beginnen usw. Schreibe den Code so, dass er auch funktioniert, wenn man dem Array weitere Zahlen hinzufügt.rollDice
vom Typ int
, welche kein Argument entgegennimmt und eine Zufallszahl von $1$ bis $6$ zurück gibt. Rufe nun im Sekundentakt diese Funktion auf und gebe das Resultat aus.Arduino-Box richten:
Benenne das Arduino-File Laufschrift.ino
.
Schliesse das LCD-Display an (siehe Arduino Programmieren Tutorial) und gebe darauf „Hello EFIF“ aus.
Programmiere darauf eine Laufschrift.
Tipp: Verwende den Datentypen String. Es gibt sehr hilfreiche Befehle, um diese zu manipulieren. Siehe dazu: https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
Eine LED zum Leuchten bringen und die Blink-Frequenz mit einem Potentiometer einstellen
Benenne das Arduino-File DiscoDisco.ino
.
Bringe zuerst einmal eine LED auf dem Breadboard zum Leuchten. Beachte:
Studiere das Kapitel zur Verwendung von analogen und digitalen Pins.
Verbinde nun eine der Verbindungen der LED mit einem der digitalen Inputs/Outputs des Arduinos (Uno: Pins 2 bis 13, vermeide Pins 0 und 1). Lege nun am entsprechenden Pin HIGH an, damit die LED leuchtet. Lasse nun die LED blinken. Verwende dazu die Delay-Funktion.
Mit einem Potentiometer soll nun die Blink-Frequenz eingestellt werden können. Verbinde die Anschlüsse 1 & 3 des Potentiometers mit Vcc und GRN. Verbinde Anschluss 2 des Potentiometers mit einem der analogen Inputs/Outputs A0 bis A3 des Arduinos. Lese den Wert, der dort angelegt wird, nun ein. Dreht man das Potentiometer, so variiert der Wert im Bereich $0$ bis $1023$. Nutze diesen Wert, um die Frequenz festzulegen.
Die Helligkeit einer LED mit einem Poti steuern. Die Lampe über zwei Knöpfe an und ausschalten.
Benenne das Arduino-File HelligkeitLED.ino
.
Um die Helligkeit einer LED einstellen zu können, würde sich ein analoger Output-Pin anbieten, da dieser, im Gegensatz zu einem digitalen Output, auch Werte zwischen 0V und 5V annehmen kann.
Trotzdem wollen wir für diese Aufgabe die LED an einem digitalen Pin anschliessen. Um die Helligkeit einstellen zu können, so müssen wir auf einen Trick zurückgreifen: Man muss die LED blinken lassen: Schnell genug, damit man es nicht als Blinken wahrnimmt aber langsam genug, damit die LED weniger hell erscheint.
Diesen Code kann man natürlich selbst schreiben. Einfacher aber ist es, wenn man die LED an einen PWM-Pin anschliesst (digitale Pins mit Tilde-Symbol). PWM steht für Pulse Width Modulation. Der Output wechselt dabei periodisch zwischen LOW und HIGH, wobei man die Breite des Pulses mit einer Zahl zwischen 0 und 255 angeben kann: analogWrite(PIN_NR,puls_breite);
Siehe dazu auch die Grafiken im Manual zu PWM.
Füge nun zwei Schalter hinzu. Schliesse diese an digitale Inputs. Mit digitalRead
kann man abfragen, ob der Knopf gedrückt wird oder nicht. Mit einem Schalter soll die LED ein-, mit dem anderen ausgeschaltet werden können.
Mache eine Kopie deines Codes und benenne das File HelligkeitLED2.ino
. Entferne nun einen der Schalter. Man soll nun mit nur einem Schalter die LED ein- und ausschalten können.
Einfaches Testprogramm zur Vorbereitung auf den Chronometer unten.
delay()
Funktion kann man einfach eine LED zum Blinken bringen. Doch die Verwendung dieser Funktion bringt grosse Nachteile mit sich. Welche wären die? Bespreche mit Kolleg:in.Einen Chronometer, also eine Stoppuhr, programmieren. Die Bestzeiten sollen im EEPROM des Arduinos gespeichert werden.
Benenne das Arduino-File Chronometer.ino
.
Verbinde die drei Schalter mit dem Arduino, von denen soll dann jeweils einer:
Programmiere den Arduino nun so, dass man die Zeit stoppen kann. Drückt.man auf den Startknopf, so beginnt die Zeit zu laufen. Drückt man auf den Stoppknopf, so wird die Messung gestoppt. Drückt man nun den Startknopf erneut, so startet eine neue Messung. Die Zeit wird auf dem Display in der oberen Zeile in Millisekunden ausgegeben.
millis(); // gibt einem die Zeit seit Programmstart in Millisekunden an.
Formattiere nun die Zeitanzeige. Diese soll im Format Minuten:Sekunden:Hundertstelsekunden, also zum Beispiel 04:12:05, sein. Schreibe dazu eine eigene Funktion.
Erzielt man eine neue Bestzeit, so soll diese im EEPROM gespeichert werden. Damit ist diese Zeit auch noch verfügbar, wenn man die Spannungsquelle vom Arduino trennt. Auf das EEPROM kannst du mit EEPROM.read und EEPROM.write zugreifen. Die Bestzeit soll auf der zweiten Zeile des Displays angezeigt werden. Wird der Arduino neu gestartet, so soll die bereits vorhandene Bestzeit aus dem EEPROM gelesen und angezeigt werden.
Drückt man den dritten (bisher nicht genutzten) Schalter, so soll die Bestzeit zurückgesetzt werden.
Im EEPROM des Arduino Uno kann man insgesamt 1024 Bytes speichern. Um nun eine grössere Zahl darin zu speichern, muss diese Zahl in einzelne Bytes zerlegt werden. Mit z & 0x0000FF
extrahiert man das erste Byte des longs z. Dabei steht 0x0000FF für die Zahl 00….001111 in Hexadezimalschreibweise (deshalb das 0x). Der Operator & ist dabei die bitweise Und-Verknüpfung. Das zweite Bit extrahiert man dann mit (z & 0x00FF00) >> 8;
Der Befehl >> 8
verschiebt das Resultat um 8 bits nach rechts.
ACHTUNG: Achte darauf, dass nicht in jedem Durchgang des Loops ins EEPROM geschrieben wird/vom EEPROM gelesen wird. Ansonsten wird es beschädigt! Speichere nur dann, wenn eine neue Bestzeit erzielt wurde.
Anstelle von nur einer Bestzeit sollen die fünf besten Zeiten sortiert im EEPROM gespeichert werden. Drückt man die dritte Taste Kurz, soll man durch dir Bestzeiten durchklicken können.
Um dies realisieren zu können, benötigst du ein Array, in welchem du mehrere Werte speichern kannst. Mit
long arr[5];
deklarierst du ein Array namens arr
, welches 5 longs speichern kann. Beachte, dass die Grösse eines Arrays im Nachhinein nicht mehr verändert werden kann. Die Elemente des Arrays sind durchnummeriert. Um auf ein Element eines Arrays zuzugreifen, verwenden wir eckige Klammer, z.B. arr[2]
. Beachte, dass das erste Element den Index 0 (und nicht 1!!!) hat. Das erste Element ist also arr[0]
, das fünfte und letzte ist arr[4]
.
Möchtest du auf alle Elemente eines Arrays zugreifen, kannst du eine for-Schleife verwenden. Möchtest du z.B. alle Elemente auf den Wert 42 setzen (warum auch nicht?), kannst du dies wie folgt machen:
for (int i=0; i < 5; i++) { // zählt alle Zahlen durch von i=0 bis und mit i=4 arr[i] = 42; }
Die Bestzeiten müssen sortiert werden. Dafür kannst du die vordefinierte Funktion qsort
verwenden. Besser (und interessanter) ist aber, einen eigenen Sortieralgorithmus zu schreiben. Die einfachste Möglichkeit ist der sogenannte Select:
Wähle das erste Element des Arrays aus. Vergleiche dieses nun mit allen Elementen rechts davon (mit höherem Index). Wann immer eines der rechten Elemente grösser ist: Vertausche die beiden. Hast du das erste Element mit allen anderen verglichen, so weist du, dass das erste Element das kleinste ist. Nun wählst du das zweite Element und vergleichst dieses mit allen Elementen rechts davon usw.
Tipp: Verwende zwei ineinander verschachtelte for-Schleifen.
Datum: EF IF-Tag, 22.01.2023
Idee: Alle setzen an diesem Tag ein eigenes, kleines Arduino-Projekt um. Am späteren Nachmittag präsentieren alle den anderen ihre (hoffentlich fertigen) Projekte. Für das Projekt wird eine kurze Dokument erstellt.
Die Dokumentation sollte 1-2 A4-Seiten lang sein und muss folgendes Beinhalten:
Abgabe: PDF im Teams-Chat an sca bis am Abend des EF-Tags.
Idee: Eigenes Arduino-Projekt über Zeitraum von mehreren Wochen realisieren. Wird benotet.