Mit PCA9685 LED langsam hoch dimmen

Hallo zusammen,

ich möchte mit dem Arduino und dem PCA9685 Board unsere Treppe, sprich die einzelnen Stufen, mit LED Streifen beleuchten.

Die einzelnen Streifen sollen, je nach Laufrichtung durch einen Bewegungsmelder aktiviert, nach und nach an gehen, und nach einer bestimmten Zeit wieder ausgehen. Dafür habe ich auch soweit ein sehr primitiven Sketch zusammen gebastelt, der diese Anforderungen erfüllt.

#include <Adafruit_PWMServoDriver.h>

#include <Wire.h>                       
#include <PCA9685.h>

PCA9685 pwmController;                  // Library using default Wire and default linear phase balancing scheme

int PIR_oben = 4; // Eingang für HC-S501 oben
int PIR_unten = 7; // Eingang für HC-S501 unten

int PIR_Stat_oben; // Variable für den Status von PIR_oben
int PIR_Stat_unten; // Variable für den Status von PIR_unten

int pause=500;




void setup() {
    Serial.begin(115200);

    Wire.begin();                       // Starte I2C
    Wire.setClock(400000);              // Setze Baudrate für I2C, 100kHz, 400kHz, und 1000kHz möglich

    pwmController.resetDevices();       // Software reset aller PCA9685 Karten

    pwmController.init(B000000);        // Setze I2C Adresse; Pinne zum setzen der Adresse auf dem PC9685: A5-A0 
    pwmController.setPWMFrequency(200); // Default is 200Hz, supports 24Hz to 1526Hz

    pinMode(PIR_oben, INPUT);           // PIR_oben Pin 4 als Eingang deklarieren
    pinMode(PIR_unten, INPUT);          // PIR_unten Pin 7 als Eingang deklarieren

    digitalWrite(PIR_oben,HIGH);        // Pullup an Ausgang 4 aktivieren
    digitalWrite(PIR_unten,HIGH);       // Pullup an Ausgang 7 aktivieren

    

//#####################################_\/_\/_ERSTER_TEST_\/_\/_###################################################################


   pwmController.setChannelPWM(0, 255 << 4); // Schalte Stufe 1 EIN
   delay(pause);
   pwmController.setChannelPWM(1, 255 << 4); // Schalte Stufe 2 EIN
   delay(pause);
   pwmController.setChannelPWM(2, 255 << 4); // Schalte Stufe 3 EIN
   delay(pause);
   pwmController.setChannelPWM(3, 255 << 4); // Schalte Stufe 4 EIN
   delay(pause);
   pwmController.setChannelPWM(4, 255 << 4); // Schalte Sufe 4 EIN
   delay(pause);
   pwmController.setChannelPWM(5, 255 << 4); // Schalte Sufe 4 EIN
   delay(pause);
   pwmController.setChannelPWM(6, 255 << 4); // Schalte Sufe 4 EIN
   delay(pause);
   pwmController.setChannelPWM(7, 255 << 4); // Schalte Sufe 4 EIN

   delay(1750);                              // Warte 2 Sekunden

   pwmController.setChannelPWM(0, 256 << 4); // Schalte Stufe 1 AUS
   delay(pause);
   pwmController.setChannelPWM(1, 256 << 4); // Schalte Stufe 1 AUS
   delay(pause);
   pwmController.setChannelPWM(2, 256 << 4); // Schalte Stufe 1 AUS
   delay(pause);
   pwmController.setChannelPWM(3, 256 << 4); // Schalte Stufe 1 AUS
 
   Serial.println(pwmController.getChannelPWM(0)); // Should output 2048, which is 128 << 4


//#######################################_/\_/\__ERSTER_TEST_#/\_/\_####################################################################

}

void loop(){

   PIR_Stat_oben = digitalRead(PIR_oben);
   PIR_Stat_unten = digitalRead(PIR_unten);


   if (PIR_Stat_oben==LOW) 
   {
    pwmController.setChannelPWM(0, 255 << 4); // Schalte Stufe 1 EIN
    delay(pause);
    pwmController.setChannelPWM(1, 255 << 4); // Schalte Stufe 2 EIN
    delay(pause);
    pwmController.setChannelPWM(2, 255 << 4); // Schalte Stufe 3 EIN
    delay(pause);
    pwmController.setChannelPWM(3, 255 << 4); // Schalte Stufe 4 EIN
    delay(5000);
   } 
   else 
   {
   pwmController.setChannelPWM(0, 256 << 4); // Schalte Stufe 1 AUS
   pwmController.setChannelPWM(1, 256 << 4); // Schalte Stufe 1 AUS
   pwmController.setChannelPWM(2, 256 << 4); // Schalte Stufe 1 AUS
   pwmController.setChannelPWM(3, 256 << 4); // Schalte Stufe 1 AUS
   }

      if (PIR_Stat_unten==LOW) 
      {
       pwmController.setChannelPWM(3, 255 << 4); // Schalte Stufe 4 EIN
       delay(pause);
       pwmController.setChannelPWM(2, 255 << 4); // Schalte Stufe 3 EIN
       delay(pause);
       pwmController.setChannelPWM(1, 255 << 4); // Schalte Stufe 2 EIN
       delay(pause);
       pwmController.setChannelPWM(0, 255 << 4); // Schalte Stufe 1 EIN
       delay(5000);
       } 
       else 
       {
       pwmController.setChannelPWM(0, 256 << 4); // Schalte Stufe 1 AUS
       pwmController.setChannelPWM(1, 256 << 4); // Schalte Stufe 1 AUS
       pwmController.setChannelPWM(2, 256 << 4); // Schalte Stufe 1 AUS
       pwmController.setChannelPWM(3, 256 << 4); // Schalte Stufe 1 AUS
       }
       
}

Einziges Problem dabei ist, dass die LED’s von jetzt auf gleich volle Helligkeit haben.

Wie kann ich diese dazu bewegen, langsam hoch zu dimmen?

MfG maxdor

Moin,

ich kann nirgends eine Funktion zum Dimmen sehen...

Hallo,

d.h. es besteht keine Möglichkeit eine LED wie in dem Video langsam hoch zu dimmen?

d.h. es besteht keine Möglichkeit eine LED wie in dem Video langsam hoch zu dimmen?

Der Programmierer, also du bestimmst, was das Programm tut.

hi,

Du hast ja bei den beispielen (in der arduino-IDE) für den PCA einiges dabei. sieh Dir das mal an, da wird gedimmt.

gruß stefan

Das Dimmen ist sehr einfach- du mußt es eben nur dem MC sagen, dass er es machen soll.

Du könntest dafür z.b. deinen aktuellen Wert mit dem Sollwert vergleichen. Ist da eine Differenz sagst du eben, dass er sich dem in Schritten annähern soll (bei 8bit stehen dir max 256 Schritte zur Verfügung). Und dann legst du noch fest in welchem zeitlichen Abstand das erfolgen soll...

Ich hab mal vor wenigen Wochen einen Sketch hier veröffentlicht, der die Zeit zwischen den einzelnen Schritten abhängig von der aktuellen Stufe dynamisch anpaßt, damit das Dimmen Augenkompatibel erfolgt- das habe ich seit dem auch bei allen Lampen und bin sehr zufrieden damit.

Hallo,

vielen Dank für eure Antworten.

Ich habe mich heute hingesetzt und habe etwas weiter gemacht. Kleiner Erfolg ist auch da, die 1. LED wird brav hoch gedimmt.

Allerdings habe ich das Problem, dass er mir die Variable “b” nicht hoch zählt, wenn “a” 50 erreicht hat. Kann mir einer sagen woran das liegen könnte?

void loop(){

   PIR_Stat_oben = digitalRead(PIR_oben);
   PIR_Stat_unten = digitalRead(PIR_unten);


   if (PIR_Stat_oben==LOW)                      // Wenn Bewegungsmelder oben schaltet
   {

      for (int a=1; a<255; a++)                 // Errechne PWM für Stufe 1
        {
        pwmController.setChannelPWM(0, a << 4);
        delay(15);


        if (a==50)
        {
          b++;
          pwmController.setChannelPWM(1, b << 4);
          
          {

          delay(15);
          }
        }
        }  
        delay(5000);
   }

Schmeiß doch erstmal die delays raus.... bei meinem Beispiel siehst du wie es geht...

Schreib Dir doch einfach Serial.println(a); in die for-Schleife und auch in das if.
Da siehst Du, wo Dein Programm lang läuft.

Und natürlich Serial.begin(9600); ins Setup (oder 115200 wenns schneller sein soll) Du musst nur den Seriellen Monitor der IDE auf die gleiche Baudrate stellen.

Das hilft unheimlich beim Verständnis der Abläufe.

Verabschiede Dich auf die Dauer von delay(...) und schau Dir die Lösung mit millis() an. Suche mal nach BlinkWithoutDelay oder der Nachtwächtererklärung (kein Witz).
Während Delay macht der Prozessor nichts, vereinfacht gesagt. Für kurze Tests kann man das machen, es gibt aber später Probleme.

Gruß Tommy