Farbeinstellung mit Rotary-Encoder - AZ-Delivery

Beschreibung

Mit einer RGB-Leuchtdiode kann man nahezu alle Farben erzeugen indem man Rot, Grün und Blau mit unterschiedlicher Helligkeit mischt. Der folgende Schaltungsvorschlag zeigt, wie man mit Hilfe eines Arduino und eines Rotary-Encoders die Farbe einer RGB-Led beliebig einstellbar macht. Der Druckschalter des Encoders wird dazu verwendet die Farbe auszuwählen, die verändert werden soll. Welche Farbe das gerade ist wird mit der SMD Led angezeigt. Durch Rechtsdrehen des Encoders wird der Wert der gewählten Farbe erhöht oder durch Linksdrehen verringert. Das Ergebnis wird mit der RGB Led angezeigt.

Schaltung

Neben dem Arduino benötigen wir drei Module aus dem 35in1 Arduino Kit,

den Rotary-Encoder die SMD RGB-Led und die normale RGB Led.

Die Anschlüsse sollten wie folgt mit dem Arduino verbunden werden

  • Arduino D2 → Rotary Encoder CLK
  • Arduino D3 → Rotary Encoder SW
  • Arduino D4 → Rotary Encoder DT
  • Arduino D6 → SMD Led R
  • Arduino D7 → SMD Led G
  • Arduino D8 → SMD Led B
  • Arduino D9 → RGB Led R
  • Arduino D10 → RGB Led G
  • Arduino D11 → RGB Led B

Außerdem sind die GND Anschlüsse aller Module mit dem GND des Arduino und der + Anschluss des Rotary-Encoders mit +5V des Arduino zu verbinden.

Für die Anschlüsse Rotary Encoder CLK und Rotary Encoder SW sollten 100nF Kondensatoren gegen Masse geschaltet werden um Störimpulse zu unterdrücken.

Die fertige Schaltung sieht dann so aus.

Schaltung

Module:

Rotary Encoder:

Der Rotary-Encoder ist ein einfaches Gerät. Er enthält eine segmentierte Konaktscheibe und zwei nebeneinader liegende Kontakte A und B durch Drehen wird je nach Drehrichtung zuerst der Konatkt A und dann der Kontakt B über die Scheibe mit Kontakt C verbunden.

codescheibe

Auf dem Logikanalysator sieht das dann so aus (Kanal 0 = Kontakt A bzw. Anschluss CLK am Modul und Kanal 1 = Kontakt B bzw. Anschluss DT am Modul).

Drehen nach rechts bei der fallenden Flanke (rot) ist Kanal 1 immer HIGH:

Drehen nach links bei der fallenden Flanke (rot) ist der Kanal 1 immer LOW:

Man sieht wenn man die fallende Flanke von Kanal 0 betrachtet, kann man aus Kanal 1 die Drehrichtung bestimmen. (1 für rechts und 0 für links). Dies werden wir im Programm nutzen. Die Anzahl der fallenden Flanken gibt den Wert wie weit gedreht wurde.

SMD-Led

Das Modul enthält eine RGB SMD Led mit geeigneten Vorwiderständen sodass 5V direkt an die Anschlüsse R(ot), G(rün) und B(lau) gelegt werden kann.

RGB-Led

Das Modul enthält eine konventionelle RGB Led mit geeigneten Vorwiderständen sodass 5V direkt an die Anschlüsse R(ot), G(rün) und B(lau) gelegt werden kann. Diese Led hat bessere Eigenschaften zur Farbmischung.

Programm:

 

Fconst byte infoLedRed = 6;
const byte infoLedGreen = 7;
const byte infoLedBlue = 8;
const byte colorLedRed = 9;
const byte colorLedGreen = 10;
const byte colorLedBlue = 11;

const byte colSwitch = 2;
const byte pulse = 3;
const byte pulseDirection = 4 ;

const byte delta = 16;

//define some global variables
volatile byte col = 0; //current color red
volatile int redLevel = 128; //red full brightness
volatile int greenLevel = 128; //green is off
volatile int blueLevel = 128; //blue is off



void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//define pin modes
pinMode(infoLedRed, OUTPUT);
pinMode(infoLedGreen, OUTPUT);
pinMode(infoLedBlue, OUTPUT);
pinMode(colorLedRed, OUTPUT);
pinMode(colorLedGreen, OUTPUT);
pinMode(colorLedBlue, OUTPUT);
//define input pins
pinMode(colSwitch, INPUT_PULLUP);
pinMode(pulse, INPUT_PULLUP);
pinMode(pulseDirection, INPUT_PULLUP);
//define interrupts
attachInterrupt(digitalPinToInterrupt(pulse),rotaryPulse, FALLING);
attachInterrupt(digitalPinToInterrupt(colSwitch),changeColor, FALLING);
//set info led
showInfo();
Serial.println("Start:");
}

void loop() {
// put your main code here, to run repeatedly:
analogWrite(colorLedRed,redLevel);
analogWrite(colorLedGreen,greenLevel);
analogWrite(colorLedBlue,blueLevel);
}

//function to set the info led;
void showInfo() {
digitalWrite(infoLedRed,LOW);
digitalWrite(infoLedGreen,LOW);
digitalWrite(infoLedBlue,LOW);
switch(col) {
case 0: digitalWrite(infoLedRed,HIGH);
break;
case 1: digitalWrite(infoLedGreen,HIGH);
break;
case 2: digitalWrite(infoLedBlue,HIGH);
break;
}
}

//interrupt service for switch
//change current color
void changeColor() {
col ++;
if (col == 3) col = 0;
showInfo();
Serial.print("Color: ");
Serial.println(col);
}

//interrupt for rotary pulse
//change color value for current value
void rotaryPulse() {
char msg[50];
byte dir = digitalRead(pulseDirection);
Serial.println(dir); switch (col) {
case 0: redLevel = change(redLevel,dir);
break;
case 1: greenLevel = change(greenLevel,dir);
break;
case 2: blueLevel = change(blueLevel,dir);
break;
}
sprintf(msg,"Color changed Red:%d Blue:%d Green:%d",redLevel,blueLevel,greenLevel);
Serial.println(msg);
}

//increment or decrement level check limits 0 and 255
int change(int level, int dir) {
if (dir == 0) { //left turn
level -= delta;
if (level < 0) level = 0;
} else {
level += delta;
if (level > 255) level = 255;
}
return level;
}

 

Zuerst werden die verwendeten Anschlüsse definiert. colSwitch und pulse wurden auf D3 und D2 gelegt, da diese Eingänge interruptfähig sind. Die Anschlüsse für die RGB Led wurden auf D9, D10 und D11 gelegt, da diese bei allen Arduino Boards für analogen Ausgang (PWM) genutzt werden können.

Außerdem wird der Wert delta definier um den der Farbwert pro Drehimpuls erhöht oder vermindert werden soll.

Dann werden globale Variablen für die gerade aktive Einstellfarbe (col) und für die eingestellten Farbwerte (redLevel, greenLevel, blueLevel) definiert.

In der setup Funktion werden die Anschlüsse vorbereitet und den Anschlüssen colSwitch und pulse Interrupt-Service-Funktionen zugewiesen. Wir triggern den Interrupt auf die negative Flanke.

 

In der loop Funktion werden die eigestellten Farbwerte an die RGB-Led ausgegeben.

Die showInfo Funktion zeigt die gerade ausgewählte Einstellfarbe über die SMD Led an. Wir verwenden hier eine Funktion da diese zweimal benötigt wird.

 

Die changeColor Funktion wird immer dann aufgerufen wenn der Druckknopf des Rotary-Encoders betätigt wurde. Der Wert für die aktuelle Einstellfarbe wird um eins erhöht. Falls er größer als zwei ist wird er wieder auf null gesetzt. Dann wird der aktuelle Wert zur Info an der SMD Led angezeigt und außerdem über die serielle Schnittstelle ausgegeben.

 

Die rotaryPulse Funktion wird immer sann aufgerufen wenn am CLK Ausgang des Rotary-Encoders eine abfallende Flanke auftritt. Zuerst wird der Zustand des DT Ausgangs des Rotary-Encoders ermittelt um die Richtung zu bestimmen. Dann wird abhängig von der aktuellen Einstellfarbe und der Drehrichtung der jeweilige Farbwert verändert. Dies erfolgt in einem Unterprogramm. Zuletzt werden die neuen Werte zur Kontrolle auf die serielle Schnittstelle ausgegeben.

 

Die change Funktion dient dazu einen Farbwert zu erhöhen oder zu vermindern. Die Parameter sind der aktuelle Farbwert und die Richtung. Ist die Richtung = 0 wird der Farbwert verringert sonst erhöht. Wäre der neue Farbwert größer als 255 wird er auf 255 gesetzt. Dasselbe geschieht wenn der neue Wert kleiner als 0 ist, dann wird er auf 0 gesetzt. Der Wert zum Erhöhen bzw. zum Vermindern wurde auf 16 gesetzt kann aber individuell geändert werden.

Für arduinoProjekte für anfänger

2 comments

Michael

Michael

Wie könnte man diese Steuerung für ein ganzes 12v led band erweitern?

Wolfgang

Wolfgang

Achtung : Die Pin Belegung im Sketch stimmt nicht mit der Pin Belegung im Tesxt überein !

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery