Problem: Helligkeit- und Farbenmodus mit Rotary Encoder

Moin Moin liebes Forum,

mein Name ist Jens und ich arbeite momentan an zwei RGBW-Wlan-Lampen. Eine Lampe ist dabei die "Cheflampe" sie besitzt einen Rotary Encoder mit dem Helligkeit und Farbe gesteuert werden und sendet die Daten zur anderen Lampe. Der Helligkeit- und der Farbenmodus wird durch den Druckknopf des Rotary Encoders gewechselt.

Ich verwende dafür:

2x Arduino Uno
2x Xbee S1
2x CREE MC-E RGBW Link
Drehgeber (Rotation ohne Anschlag) mit Push Button

Klingt alles gut, aber ich bin ein Anfänger was das Coden angeht und zu meinen Code hätte ich ein paar Fragen an Euch. :slight_smile:

Mit der Wlan verbindung beschäftige ich mich später, da konnte ich bereits eine Verbindung zwischen den Arduinos herstellen konnte.

Momentan arbeite ich noch an Code für die beiden Modi.

Ich habe ein kleines Video gedreht: Youtube

Mein Code:

/* Encoder Library - Basic Example
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 *
 * This example code is in the public domain.
 */

#include <Encoder.h>

// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
Encoder myEnc(2, 3);
//   avoid using pins with LEDs attached

int encoderSwitchPin = 12;
int whitePin = 8;
int bluePin = 9;
int greenPin = 10;
int redPin = 11;

int brightness = 0;
int colorval = 0;
int maxval = 0;

int switchstatus = HIGH;
int reading;
int previous = LOW;

long time = 0;
long debounce = 200;

boolean isInBrightnessMode = true;

boolean buttonPushed = false;

int currentColorNumber = 0;

int redval2 = 0;
int greenval2 = 0;
int blueval2 = 0;
int whiteval2 = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");

  pinMode(encoderSwitchPin, INPUT);

  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(whitePin, OUTPUT);

  digitalWrite(encoderSwitchPin, HIGH);
}

long oldPosition  = -999;

void loop() {

  //HELLIGKEIT________

  if (isInBrightnessMode) {
    brightness = oldPosition; //Speicherung des Brightnesswert, wenn Modi gewechselt wird
  }

  else {
    brightness != oldPosition; //Speicherung des Brightnesswert
  }

  if (oldPosition < -10) {
    myEnc.write(-10);  //Untere Begrenzung des Drehgebers
  }

  if (isInBrightnessMode && oldPosition > 255) {
    myEnc.write(255);  //Obere Begrenzung des Drehgebers
  }


  brightness = constrain(brightness, 0, 255);  //
  brightness = map(brightness, 0, 255, 0, 255);

  //Serial.println("Brightness");
  //Serial.println(brightness);

  //___________

  

  //COLOR____________

  colorval = oldPosition;

  if (isInBrightnessMode) {
    colorval != oldPosition;
  }

  maxval = brightness;

  //  if (buttonPushed == true) {
  //    myEnc.write(colorval);
  //    }

  if (colorval < 100) {
    redval2 = map(colorval, 0, 100, brightness, brightness);
    greenval2 = map(colorval, 0, 100, brightness, 0);
    blueval2 = map(colorval, 0, 100, brightness, 0);
    whiteval2 = map(colorval, 0, 100, brightness, 0);
  }

//___________

  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;

    Serial.println("NewPosition");
    Serial.println(newPosition);
  }

  if (digitalRead(encoderSwitchPin)) {
    //button is not being pushed
    buttonPushed = false;
    //    Serial.println("Brightness Mode");
  } else {
    //button is being pushed
    if (buttonPushed == true)
      return;
    Serial.println("button pushed");
    buttonPushed = true;
    isInBrightnessMode = !isInBrightnessMode;
    myEnc.write(brightness);  //Zurücksetzung auf den Brightnesswert
  }

  reading = digitalRead(encoderSwitchPin);

  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (switchstatus == HIGH)
      switchstatus = LOW;   
    else
      switchstatus = HIGH;

    time = millis();
  }

  if (isInBrightnessMode) {

    analogWrite(ledPin, brightness);   
    analogWrite(redPin, brightness);
    analogWrite(greenPin, brightness);
    analogWrite(bluePin, brightness);
    analogWrite(whitePin, brightness);
  }
  else {

    //RED Modus;
    analogWrite(redPin, redval2);
    analogWrite(greenPin, greenval2);
    analogWrite(bluePin, blueval2);
    analogWrite(whitePin, whiteval2);

  }



  previous = reading;
}

Was ich möchte:

  • Das der BrightnessMode immer die selbe Farbe hat wie der ColorMode, und im BrightnessMode logischerweise die Helligkeit und im ColorMode die Farbigkeit eingestellt wird.
  • Das im Colormode man durch die wichtigsten Farben smooth durchscrollen kann. Pro Farbe: map(0, 100, 0, brightness) (oder so).

Meine Probleme:

  • Ich glaube mein ColorMode Ansatz ist nicht grade optimal (so wie warscheinlich der komplette code auch :wink: ). Ich glaube da gibts eine bessere Methode, die ich nicht kenne vllt. mit void arbeiten oder so.
  • Der Helligkeitmode hat nicht die selbe Farbe wie der Colormode.

Meine Überlegungen:

Die Brightness nur als Begrenzer für den ColorMode verwenden.
--- aber wie?! :cry:

Nebensache:
Die whiteled geht als letztes an im brightnessmode (kann man kurz im video sehen), das liegt denke ich an der begrenzten Voltzahl die das Arduino liefert, stimmt das?
Muss ich die LED mit einer externen Stromversorgung befeuern ?
Oder Kann ich iwie mehr aus dem Arduino rausholen?

Ich würde mich freuen wenn mir jemand paar Tipps geben kann :slight_smile:

lg Jens

Hast Du HSV versucht?

Grüße Uwe

EgoJacky:
Ich würde mich freuen wenn mir jemand paar Tipps geben kann :slight_smile:

Wie Uwe schreibt: Du stellst die Farbe im HSV-System ein, bei Dir offenbar nur Hue (Farbwert), Sättigung stets=100% und Value für die Helligkeit.

Und den eingestellten HSV-Wert rechnest Du dann nach RGB um, um dann die LEDs mit Farbwerten anzusteuern.

Von den Umrechnungsroutinen mußt Du Dir nur was aussuchen, das in Deinem Fall paßt. Für HSV-RGB Konvertierungsroutinen gibt es glaube ich verschiedene Standards:

  1. Umrechnung von 'float' Gleitkommazahlen, jeweils im Wertebereich 0,000 bis 1,000
  2. Umrechnung von 'float' Gleitkommazahlen, Hue von 0,000 bis 360,000, S und V von 0,000 bis 1,000
  3. Umrechnung von 'int' Ganzzahlen, mit H im Bereich 0...360, S im Bereich 0..100, V im Bereich 0..100
  4. Umrechnung von 'int' Ganzzahlen, jeweils im Wertebereich 0...255

Da müßtest Du Dir das passende raussuchen, je nach erforderlicher Auflösung und Genauigkeit.