Farbwechsel mit RGB-LED-Stripe

Aufgabenstellung

  1. Informieren Sie sich über das Thema “Pulsweitenmodulation”.
  2. Überlegen Sie, wie Sie den LED-Stripe elektrisch betreiben können (Höhe und Art der Betriebsspannung, Stromaufnahme).
  3. Schließen Sie den LED-Stripe so an eine konstante Spannungsquelle an dass alle LEDs leuchten. Messen Sie die Stromaufnahme.
  4. Nun soll die Helligkeit der LEDs (getrennt nach Farben) geregelt werden. Informieren Sie sich, warum der LED-Stripe nicht direkt mit den Ausgängen des Mikrokontrollers verbunden werden darf. Warum und wie geht es dann mit einer H-Brücke?
  5. Entwerfen Sie ein VI in LabVIEW, so dass die Mischfarbe (also die Überlagerung der drei Farben) des LED-Stripes jede Sekunde automatisch wechselt.
  6. Ändern Sie das VI so ab, dass Sie mit Hilfe eines Sensors die Farbe eines Gegenstandes erkennen und anschließend die Mischfarbe des LED-Stripes auf diese Farbe einstellen.
  7. Dokumentieren Sie die erstellte Soft- und Hardware (nutzen Sie dafür z.B. die Software von Fritzing.org).

Hintergrundinfos

Ansteuerung LED-Stripes

Quelle (in Auszügen): Artikel “Wandleuchten” der Zeitschrift c’t, Heft 1/2014

Einfache und preiswerte Mikrocontroller beherrschen die Pulsweitenmodulation an einigen ihrer I/O-Pins bereits hardwareseitig, sodass es keines sonderlichen Programmieraufwands bedarf, um eine LED-Kette damit zu steuern.

Ein Mikrocontroller-Board wie zum Beispiel der Arduino Uno mit seinem ATMega328P-Chip stellt dem Anwender 6 PWM-Pins zur Verfügung. Um eine LED damit zu dimmen, bedarf es lediglich zweier einfacher Befehle: pinMode(ledPin, OUTPUT) in der Setup-Routine und eines analogWrite(ledPin, helligkeit) im eigentlichen Programm, wobei ledPin die Nummer des PWM-Ports angibt (z.B. int ledPin = 3) und “helligkeit” für einen Wert zwischen 0 und 255 steht. Die Bezeichnung “analogWrite” für die Ausgabefunktion bezieht sich eigentlich auf echte D/A-Wandler und ist hier im Grunde nicht korrekt, denn sie steuert die Weite des Pulses mit der im Kasten beschriebenen Wirkung. Die Auflösung ist beim Arduino auf – für unsere Zwecke ausreichende – 255 Schritte begrenzt.

Eine einzelne LED kann man direkt an den Ausgangspin des Arduino anschließen, es ist lediglich ein kleiner Vorwiderstand erforderlich, um den Strom zu begrenzen. Bei Standard-LEDs sind 220 Ohm der richtige Wert, der Strom wird damit auf etwa 20 Milliampere begrenzt und viel mehr sollte man den Ausgängen des Mikrocontrollers auch nicht zumuten. Will man Leistungs-LEDs oder gleich ganze LED-Streifen mit handelsüblichen 12 Watt und 1 Ampere steuern, braucht man eine kleine Schaltung, die auch höhere Ströme bewältigt und die man am besten unabhängig vom Arduino mit Strom versorgt.

Am einfachsten geht das mit einem N-Kanal-MOSFET. Wir haben uns für einen IRLIZ44N entschieden, den es bei den einschlägigen Elektronik- Versendern für unter einem Euro gibt. Um ihn mit dem Arduino zu verbinden, braucht man nur einen kleinen Widerstand von 180 Ohm zwischen dem I/O-Pin des Arduino und dem Gate des MOSFET, ein weiterer Widerstand von 10 kOhm zwischen Gate und Masse verhindert das Durchschalten des MOSFET, während der Arduino bootet.

Der MOSFET wird mit seiner Source an den Minuspol der Spannungsquelle und mit Drain an die Kathode der LED-Streifen geschaltet. Andersherum müsste man einen P-Kanal-MOSFET einsetzen. Glücklicherweise verwenden die handelsüblichen RGB-LED-Streifen einen gemeinsamen Pluspol und jeweils einen einzelnen Anschluss für den Minuspol der einzelnen Farben, sodass man sie ohne Probleme mit unserer Schaltung verbinden kann. Für einen RGB-Streifen benötigt man drei MOSFETs, also pro Farbe einen, und belegt damit auch drei PWM-Ausgänge des Arduino.

Der IRLIZ44N vermag Ströme bis zu 30 Ampere zu schalten, womit theoretisch dem Anschluss einer kompletten Disco-Beleuchtung nichts im Wege stünde. In der Praxis ist allerdings das verwendete Netzteil der limitierende Faktor. Sofern es nicht mit dem LED-Streifen geliefert wird, muss man sich separat ein Netzteil besorgen, das den erforderlichen Strom liefert.

Üblicherweise können die gängigen LED-Streifen nach jeweils drei LEDs getrennt werden, weil sich immer drei LEDs einen Vorwiderstand teilen. Das entspricht einer Länge von 10 Zentimetern und einem Strom von etwa 20 Milliampere je Farbe. Für 100 Zentimeter käme also mit einem 500-Milliampere- Netzteil gerade so aus. Falls man den Arduino selbst ebenfalls über das 12-V-Netzteil versorgen will, was problemlos möglich ist, sollte man noch etwa 100 Milliampere dazu rechnen. Die Massen des Arduino-Boards und des 12-V-Netzteils für die LEDs müssen in jedem Fall verbunden werden!

Pulsweitenmodulation (PWM)

Quelle: Artikel “Pulsweitenmodulation” auf Mikrocontroller.net
Einleitung

Bei der Pulsweitenmodulation (engl. Pulse Width Modulation, abgekürzt “PWM”) wird die Ein- und Ausschaltzeit eines Rechtecksignals bei fester Grundfrequenz variiert. Das Verhältnis  bezeichnet man als “Tastverhältnis” (laut DIN IEC 60469-1: Tastgrad) (engl. Duty Cycle, meist abgekürzt DC, bitte nicht verwechseln mit Direct Current = Gleichstrom ). Das Tastverhältnis ist eine Zahl zwischen 0 und 1.

Wie leicht zu erkennen ist gilt für den “Mittelwert” der Spannung mit der Periode :

 ist dabei normalerweise 0V,  die Betriebsspannung , z. B. 5V. Deshalb kann man vereinfacht schreiben:

.
Beispiele

Die folgenden Beispiele zeigen PWM-Signale mit einem Tastverhältnis von 75% bzw. 25%.

Beispiel 1

Beispiel 2

Leistung

Steuert man mit einem pulsweitenmodulierten Signal direkt einen ohmschen Verbraucher an (z. B. Heizdraht), so ist darauf zu achten, dass man zur Bestimmung der Leistung nicht einfach

rechnen darf, sondern die Leistung während der Ein- und Ausschaltzeit getrennt betrachten muss:

Da praktisch fast immer gilt  sowie 

kann man vereinfacht schreiben und damit rechnen.

Beispiel

Der Mittelwert dieser Spannung ist:

Würde man mit diesem Wert die Leistung berechnen, so käme man auf:

Der richtige Wert ist jedoch:

Bei 0V lässt sich kürzen:

Anwendung
Digitaler Verstärker statt linearer Verstärker

Eine Heizung (Beispiel) mit 10O-Widerstand soll mit bis zu 12 V angesteuert werden. Dazu wird ein 13 V-Netzteil sowie ein linearer Verstärker verwendet (ein linearer Verstärker braucht immer eine etwas höhere Betriebsspannung als die maximale Ausgangsspannung).

Sollen nun 12 V auf die Heizung gegeben werden, fällt (fast) die gesamte Spannung über der Heizung selber ab, am Verstärker fällt nur 1 V ab. Es fließen ca. 1,2 A, es werden ca. 14,4 W in der Heizung in Wärme umgesetzt, im Verstärker ca. 1,2 W, der Wirkungsgrad beträgt 92%.

Wenn jetzt aber nur noch 6 V an der Heizung anliegen sollen, müssen am linearen Verstärker die restlichen 7 V abfallen. D.h. von den 13 V, welche konstant vom Netzteil geliefert werden, fallen 7 V am Verstärker und 6 V an der Heizung ab. Die Transistoren des linearen Verstärkers sind nur halb durchgesteuert. Es fließt ein Strom von ca. 600 mA, in der Heizung werden ca. 3,6 W in Wärme umgesetzt. Allerdings werden auch 4,2 W im Verstärker in Wärme umgesetzt! Der Wirkungsgrad ist nur noch 46%!

Im Gegensatz dazu sind bei einer PWM die Transistoren des digitalen Verstärkers immer nur entweder voll durchgesteuert oder gar nicht durchgesteuert. Im ersteren Fall fällt nur eine geringe Verlustleistung über dem Transistor ab, da die Sättigungsspannung  sehr gering ist (meist weniger als 1 V). Im zweiten Fall fällt gar keine Verlustleistung über dem Transistor ab, da kein Strom fließt (P=U*I). Im Fall der 6 V an der Heizung beträgt das notwendige Tastverhältnis 0,23. D.h. nur während 23% der PWM-Periode wird Verlustleistung im digitalen Verstärker erzeugt und zwar ca.

Der Wirkungsgrad liegt bei 92%!

Motorsteuerung

Eine der Hauptanwendungen für PWM ist die Ansteuerung von (Gleichstrom-) Motoren. Der große Vorteil von PWM ist hier der gute Wirkungsgrad. Würde man einen Digital-Analog-Wandler mit einem nachgeschalteten analogen Verstärker zur Ansteuerung verwenden, dann würde im Verstärker eine sehr hohe Verlustleistung in Wärme umgewandelt werden. Ein digitaler Verstärker mit PWM hat dagegen sehr geringe Verluste. Die verwendete Frequenz liegt meist im Bereich von einigen 10kHz. Zur Berechnung der Drehzahl eines Motors kann im Normalfall der Mittelwert der PWM-Spannung als Betriebsspannung angenommen werden.

… Der Artikel auf Artikel “Pulsweitenmodulation” auf Mikrocontroller.net geht noch etwas weiter. Die dort aufgeführten Beispiele spielen aber für die Übung keine Rolle …


Motorsteuerung mit einem H-Bridge IC

Quelle: Wikipedia, Artikel “Brückenschaltung”, Stand: 09/2014

Eine Brückenschaltung – auch H-Schaltung, H-Brücke oder Vollbrücke genannt – ist eine elektrische Schaltung, bei der in der Grundform fünf Zweipole in Form des Großbuchstabens H zusammengeschaltet sind. Die Querverbindung heißt Brückenzweig.

 

Quelle: www.arduino-tutorial.de/2010/06/motorsteuerung-mit-einem-h-bridge-ic/

Da eine selbst gebaute H-Bridge relativ viele Teile benötigt, bietet es sich an, einen IC zu verwenden. Gängiges Modell ist der L293D, der zwei Motoren unabhängig von einander steuern kann. Es handelt sich um einen IC im DIL16 Gehäuse, d.h. er hat 16 Beinchen.

Auf einer Platine werden die inneren Beinchen (Pin 4,5,12,13) mit dem GND verbunden und dienen der Wärmeableitung. Auf dem Breadboard muss nur eines der vier mit dem GND verbunden werden.

Im Beispiel werden zwei Motoren vom Arduino gesteuert. Der Strom kommt aus einer Batterie. Natürlich kann hier auch Netzteil verwendet werden. Wenn es sich um kleine Motoren handelt (z.B. Vibrationsmotoren), können diese auch direkt vom Arduino mit Strom versorgt werden. Hierfür muss in der Schaltung lediglich die orange Leitung an der H-Brigde mit dem 5V+ verbunden werden.

Die H-Bridge L293D hält einen kurzzeitigen Strom von 1,2 A und einen dauerhaften Storm von 600 mA pro Kanal aus.

Ein großer Vorteil der L293D sind die integrierten Dioden, die Induktionsströme abfangen, die beim Nachdrehen des Motors entstehen.

Sollten höhere Ströme erreicht werden, sollte man auf die Verwendung eines alternativen ICs zurückgreifen. Hier bietet sich z.B. der L6205N an.

Code-Beispiel

  1. int motor1_A=11;
  2. int motor1_B=10;
  3. int motor1_Speed=9;
  4. int motor2_A=5;
  5. int motor2_B=4;
  6. int motor2_Speed=3;
  7. void setup(){
  8.   pinMode(motor1_A,OUTPUT);
  9.   pinMode(motor1_B,OUTPUT);
  10.   pinMode(motor2_A,OUTPUT);
  11.   pinMode(motor2_B,OUTPUT);
  12. }
  13. void loop(){
  14.   // motor1
  15.   for (int i=0; i>256; i+=5){
  16.     digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
  17.     digitalWrite(motor1_B,LOW);
  18.     analogWrite(motor1_Speed,i); // speed counts from 0 to 255
  19.     delay(20);
  20.   }
  21.   for (int i=255; i>0; i-=5){
  22.     digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
  23.     digitalWrite(motor1_B,LOW);
  24.     analogWrite(motor1_Speed,i); // speed counts from 0 to 255
  25.     delay(20);
  26.   }
  27.   // motor2
  28.   for (int i=0; i<256; i+=5){
  29.     digitalWrite(motor2_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
  30.     digitalWrite(motor2_B,LOW);
  31.     analogWrite(motor2_Speed,i); // speed counts from 0 to 255
  32.     delay(20);
  33.   }
  34.   for (int i=255; i>0; i-=5){
  35.     digitalWrite(motor2_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
  36.     digitalWrite(motor2_B,LOW);
  37.     analogWrite(motor2_Speed,i); // speed counts from 0 to 255
  38.     delay(20);
  39.   }
  40.   // turn vice versa
  41.   // motor1
  42.   for (int i=0; i<256; i+=5){
  43.     digitalWrite(motor1_A,LOW); // A = LOW and B = HIGH means the motor will turn left
  44.     digitalWrite(motor1_B,HIGH);
  45.     analogWrite(motor1_Speed,i); // speed counts from 0 to 255
  46.     delay(20);
  47.   }
  48.   for (int i=255; i>0; i-=5){
  49.     digitalWrite(motor1_A,LOW); // A = LOW and B = HIGH means the motor will turn left
  50.     digitalWrite(motor1_B,HIGH);
  51.     analogWrite(motor1_Speed,i); // speed counts from 0 to 255
  52.     delay(20);
  53.   }
  54.   // motor2
  55.   for (int i=0; i<256; i+=5){
  56.     digitalWrite(motor2_A,LOW); // A = LOW and B = HIGH means the motor will turn left
  57.     digitalWrite(motor2_B,HIGH);
  58.     analogWrite(motor2_Speed,i); // speed counts from 0 to 255
  59.     delay(20);
  60.   }
  61.   for (int i=255; i>0; i-=5){
  62.     digitalWrite(motor2_A,LOW); // A = LOW and B = HIGH means the motor will turn left
  63.     digitalWrite(motor2_B,HIGH);
  64.     analogWrite(motor2_Speed,i); // speed counts from 0 to 255
  65.     delay(20);
  66.   }
  67. }