Last active
November 2, 2016 18:40
-
-
Save svenk/c78a26bccb9df6eb750dadf6a2c7fbae to your computer and use it in GitHub Desktop.
3Farben LED Arduino für Heribert
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Kommentierte Fassung fuer ein Arduino-Testprogramm | |
**/ | |
// Anschlussbelegung: | |
#define PIN_ROT 2 | |
#define PIN_GRUEN 3 | |
#define PIN_BLAU 4 | |
// Taste (Button) an Pin 7 anschließen! | |
// Ton-Dauer in Millisekunden | |
#define TON_DAUER 200 | |
// Die folgenden Konstanten werden nur der Übersicht halber | |
// in einem enum definiert. Eine eigentliche Variable, die diesen | |
// Datentyp nutzen kann, wird nicht benutzt. Sie könnte etwa mit | |
// enum Farben bla = Rot; | |
// definiert werden. | |
enum Farben | |
{ | |
Rot = 1, | |
Gruen = 2, | |
Blau = 4, | |
}; | |
void setup() { | |
// Funktionsaufrufe der Arduino-Programmierbibliothek: | |
// https://www.arduino.cc/en/Reference/PinMode | |
pinMode(PIN_ROT, OUTPUT); | |
pinMode(PIN_GRUEN, OUTPUT); | |
pinMode(PIN_BLAU, OUTPUT); | |
pinMode(7, INPUT_PULLUP); | |
} | |
// eine globale Variable vom Typ Ganzzahl. | |
int LED_FARBE = 0; | |
void loop() { | |
// Die Funktion TasteGedrueckt() wird erst weiter unten definiert. | |
// Mit einem normalen C bzw. C++-Compiler würde hier ein Fehler kommen | |
// und die Kompilierung abbrechen. Die Arduino-IDE hingegen erzeugt automatisch | |
// eine "forward Declaration", dadurch wird die Reihenfolge der Funktionen egal. | |
if(TasteGedrueckt()) | |
{ | |
LED_FARBE++; | |
if(LED_FARBE > 7) | |
{ | |
LED_FARBE = 0; | |
} | |
// hier wird setzeLed mit dem Parameter LED_FARBE aufgerufen. Mit Referenz auf die | |
// unten stehende Erläuterung: Das ist das gleiche wie f(5). | |
SetzeLed(LED_FARBE); | |
} | |
} | |
// mit "void SetzeLed(int farbe)" wird eine Funktion definiert. Siehe | |
// https://www.arduino.cc/en/Reference/FunctionDeclaration das Bild "Anatomy of a C function" | |
// die erklärt, wie das funktioniert: | |
// void -> ist der Rückgabewert (kein Rückgabewert) | |
// int farbe -> ist ein Parameter vom Typ Ganzzahl den man in der Funktion "farbe" nennt | |
// Funktionen kann man gut einführen am Beispiel von mathematischen Funktionen: Aus | |
// der Parabel f(x) = x^2 wird in C einfach | |
// int f(int x) { | |
// return x*x | |
// } | |
// und kann dann mit f(5) u.ä. im Code aufgerufen werden | |
void SetzeLed(int farbe) | |
{ | |
// Das einfache "&" ist eine bitweise Operation. In ihrer Binärdarstellung werden | |
// nun die Zahlen, die in "farbe" und der Konstanten "rot" gespeichert sind mit der | |
// UND-Operation verrechnet, das if() wertet zu WAHR aus, wenn die entstehende Zahl | |
// nicht Null ist, also mindestens ein Bit gesetzt ist. | |
// | |
// Ich denke die bitweise Operation ist hier ueberfluessig, ein einfacher Vergleich | |
// if(farbe == Rot) ist besser. | |
if(farbe & Rot) | |
{ | |
digitalWrite(PIN_ROT, HIGH); | |
} | |
else | |
{ | |
digitalWrite(PIN_ROT, LOW); | |
} | |
// Das hier ist die Kurzschreibweise für obiges if/else. | |
digitalWrite(PIN_GRUEN, (farbe & Gruen)?HIGH:LOW); | |
digitalWrite(PIN_BLAU, (farbe & Blau)?HIGH:LOW); | |
switch(farbe) //Generieren der Töne | |
{ | |
case 0: | |
noTone( 9 ); | |
break; // break sorgt dafuer, dass es nun aus dem switch rausgeht | |
case Gruen+Blau: | |
tone(9, 440, TON_DAUER ); | |
break; | |
case Blau: | |
tone(9, 500, TON_DAUER ); | |
break; | |
default: | |
tone(9, 1200, 100 ); | |
noTone(9); | |
delay(30) | |
tone(9, 1200, 100); | |
} | |
} | |
// Fun Fact: Die kleinste addressierbare Einheit in einem 8-bit-Rechner ist | |
// das Byte mit 8 Bit. Dieser bool benötigt daher in Wirklichkeit 8 bit Speicher. | |
// Ein Compiler kann das aber im Zweifelsfall auf Assemblerlevel optimieren, | |
// Compiler sind sehr schlau. Ist aber nur eine Randbemerkung zu deiner Randbemerkung. | |
bool TasteGedrueckt() | |
{ | |
if(digitalRead(7) == HIGH) | |
{ | |
// Taste nicht gedrückt, gehe sofort zurück | |
return false; | |
} | |
// hier kommen wir nur an, wenn die Taste bei der Messung gerade | |
// als gedrückt schien. | |
delay(5); | |
while(digitalRead(7) == LOW) | |
{ | |
// Ich denke das hier ist ein komischer Trick, der die Funktion von loop() | |
// ausnutzt: Wir verharren in einer Endlosschleife solange die Taste | |
// ungedrueckt scheint. Sobald die gedrückt ist, warten wir eine Milli- | |
// Sekunde und gehen dann raus aus der Funktion. | |
// Die eigentliche Entprellung geht also implizit beim nächsten | |
// Funktionsaufruf los mit den 5ms Warten. | |
delay(1); | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment