Neuigkeiten    Das Projekt    Technik    RoboSpatium    Unterstützung    Stichwortverzeichnis    Download    Reaktionen    Spiele    Gadgets    Kontakt   




<<< C: Basisfunktionen         Python: GPIOs schalten >>>

C: GPIO als Ausgang

Der Schaltplan zum Kapitel

GPIO mit LED und Vorwiderstand an Arduino UNO
Abbildung 1:
Um eine LED blinken lassen zu können, muss diese natürlich auch mit dem Mikrocontroller - hier einem Arduino UNO - verkabelt werden. Alles zum korrekten Anschließen von LEDs an GPIOs gibt's im Kapitel zu LEDs mit Hilfe von GPIOs schalten.
Welche Pins welche Funktion haben, ist im Kapitel zur Hardware des Arduino UNO nachzulesen.

Blinkende LED

Das üblicherweise erste Programm zu "Physical Computing" besteht darin, eine LED blinken zu lassen. Ich mache da keine Ausnahme:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(1000);  
  digitalWrite(5, LOW);  
  delay(1000);  
 
}  
    

Eine mit Vorwiderstand(!) zwischen Pin 5 und Masse (GND) angeschlossene LED blinkt, sobald das Programm zu dem Mikrocontroller hochgeladen wurde.
Am Arduino UNO ist eine interne LED an Pin 13 angeschlossen, somit funktioniert das Programm auch ohne zusätzliche Hardware, wenn ihr das Programm abändert ("5" in "13"). Die kleine orangefarbene LED auf dem UNO Board blinkt in disem Fall.
Alle Pins sind standardmäßig als Eingang geschaltet. Der Pin, an dem die LED angeschlossen ist, muss daher zuerst als als Ausgang definiert werden, was in dem Block "Setup" gemacht wird:
pinMode(5, OUTPUT);
Erst dann kann die LED mit dem Befehl:
digitalWrite(5, HIGH);
eingeschaltet und mit dem Befahl:
digitalWrite(5, LOW);
wieder ausgeschaltet werden. damit die Schaltvprgänge nicht schneller ablaufen, als ihr mit dem bloßen Auge erfassen könnt, werden Pausen mit dem Befehl:
delay(1000);
dazwischen eingefügt. Vernachlässigt man die sehr kleine Zeitspanne für das Ein- und Ausschalten, so dauert ein Durchlauf des Programmblocks "Loop" 2 Sekunden. Die LED ist in der Hälfte der Zeit eingeschaltet, also während 50% der Gesamtdauer eines "Loop" Durchgangs.

Asynchron blinkende LED

Um die LED nur kurz ein-, aber lange auszuschalten, müssen die delay() Zeilen abgeändert werden:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  <br>  
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(500);  
  digitalWrite(5, LOW);  
  delay(1500);  
 
}  
    

Nach wie vor dauert ein Durchlauf des "Loop" Blocks 2 Sekunden, die LED ist in diesem Zeitraum aber nur noch für 500 Millisekunden, also 0.5 Sekunden eingeschaltet. Die Einschaltdauer beträgt nur noch ein Viertel, also 25%.

Schnell blinkende LED

Als nächstes ändern wir die Zeitdauer für einen Durchgang des "Loop" Blocks, indem wir erneut die delay() Zeilen ändern.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(125);  
  digitalWrite(5, LOW);  
  delay(375);  
 
}  
    

Jetzt dauert ein Durchlauf des "Loop" Blocks nur noch 0.5 Sekunden, die LED ist in diesem Zeitraum für nur noch für 125 Millisekunden, also 0.125 Sekunden eingeschaltet, was aber nach wie vor einem Vietel der Gesamtdauer, also 25% entspricht.

Sehr schnell blinkende LED

Nun lassen wir die LED mal sehr schnell blinken:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(10);  
  digitalWrite(5, LOW);  
  delay(30);  
 
}  
    

Ein Durchlauf des "Loop" Blocks dauert jetzt nur noch 0.04 Sekunden, also 40 Millisekunden. Die LED ist in diesem Zeitraum für nur 10 Millisekunden, also 0.01 Sekunden eingeschaltet, was aber nach wie vor einem Vietel der Gesamtdauer, also 25% entspricht. Die einzelnen Schaltvorgänge könnt ihr mit dem bloßen Auge nicht mehr mitverfolgen. Die LED scheint ständig eingeschaltet zu wein. Dass das allerdings nicht der Fall ist, könnt ihr sichtbar machen, indem die delay() Statements erneut abgeändert werden:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(5);  
  digitalWrite(5, LOW);  
  delay(35);  
 
}  
    

Nach wie vor leuchtet die LED scheinbar durchgehend, die Leuchtkraft hat allerdings nachgelassen. Die LED ist nur noch während:
100 / ( (35 + 5) / 5 ) = 12.5%
der Gesamtdauer eingeschaltet. Die Einschalt- im Vergleich zur Gesamtdauer bezeichnet man als Tastgrad. Je höher dieser Tastgrad, um so heller leuchtet die LED.
Die an einen Verbraucher abgegebene Leistung ( entsprechend der Leuchtkraft der LED ) kann mit dieser Methode gesteuert werden. Dabei verwendet man eine möglichst kleine Gesamtdauer für den Programmblock. Den Kehrwert der Gesamtdauer des "Loop" Blocks bezeichnet man als die Frequenz (f), also als Anzahl der Schaltvorgänge pro Sekunde:
f = 1 / (TEIN + TAUS) = 1 / (0.035 + 0.005) = 25Hz
Die Leistungssteuerung eines Verbrauchers mit dieser Methode bezeichnet man als Pulsweitenmosulation (PWM).
Experimentiert einfach mal mit unterschiedlichen Werten in den delay() Statements.

Es darf nichts stören

Wird die LED nach dem oben angegebenen Beispiel in ihrer Helligkeit gesteuert, so darf in dem "Loop" Block aber nichts anderes mehr gemacht werden, denn sonst stimmt die Rechnung nicht mehr. Fügen wir in dem Beispiel oben mal ein paar Zeilen Programmcode ein:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  digitalWrite(5, HIGH);  
  delay(5);  
  digitalWrite(5, LOW);  
  delay(35);  
 
  for(i=0; i<1000; i++){  
    digitalRead(7);  
  }  
 
}  
    

Wenn ihr dieses Programm startet, leuchtet die LED deutlich dunkler als zuvor. Der Grund liegt darin, dass der "Loop" Block nun deutlich länger dauert, da neben dem Schalten der LED noch der Pin 7 1000mal eingelesen wird, was eine nennenswerte Zeitdauer beansprucht. Somit steigt die Gesamtdauer, die Einschaltdauer bleibt mit 5 Millisekunden aber gleich. Der Tastgrad sinkt, die LED leuchtet weniger hell.

analogWrite()

Um jegliche Störung eines Pulsweitensignals auszuschließen, besitzen Mikrocontroller eine extra-Hardware, die das Abarbeiten der Schaltdauer übernimmt und das völlig unabhängig vom Rest des Programms. Um diese Hardware zu nutzen, gibt es die Funktion:
analogWrite(Pin, PulseWidth);
An diese müssen zwei Parameter übergeben werden:
Die Nummer des Pins, der geschaltet werden soll und der Tastgrad. Der Tastgrad wird nicht in Prozent angegeben, sondern als ganzzahliger Wert, der zwischen 0 und 255 liegen muss. Dabei entspricht 0 einer immer ausgeschalteten LED, 255 einer immer eingeschalteten LED. Der Wert 63 entspricht einem Tastgrad von 25% (25,098%). Die Grundfrequenz dieses Signals ist vom Mikrocontroller fest vorgegeben und kann mit analogWrite() nicht geändert werden. An Pin 5 des Arduino UNO beträgt diese 980Hz. Nicht alle Pins besitzen die Möglichkeit, PWM mit analogWrite() auszugeben. Am Arduino UNO Board sind diese Pins mit einer Tilde (˜) vor der Nummer gekennzeichnet. Es handelt sich um die Pins 3, 5, 6, 9, 10 und 11. Auch für die analogWrite() Funktion muss der entsprechende Pin in dem "Setup" Block zuerst als Ausgang geschaltet werden:
1
2
3
4
5
6
7
8
9
10
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  analogWrite(5, 63);  
}  
    

Das Programm wird deutlich kürzer.
Mit analogWrite() bleibt die LED konstant hell, auch wenn wir weitere Befehle in den "Loop" Block einfügen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void setup() {  
  // put your setup code here, to run once:  
  pinMode(5, OUTPUT);  
 
}  
 
void loop() {  
  // put your main code here, to run repeatedly:  
  analogWrite(5, 63);  
 
  for(i=0; i<1000; i++){  
    digitalRead(7);  
  }  
 
}  
    



<<< C: Basisfunktionen         Python: GPIOs schalten >>>


Neuigkeiten    Das Projekt    Technik    RoboSpatium    Unterstützung    Stichwortverzeichnis    Archiv    Download    Reaktionen    Spiele    Verweise    Gadgets    Kontakt    Impressum   





Twitter YouTube Hackaday Patreon TPO