Benötige Hilfe bei neopixel, MPR121 und PIR-Sensor

Moin
ich bin noch neu im Thema Arduino und schlage mich mit einer Funktion rum.
Hintergrund
Benutzt werden neopixel, 1 MPR121 und ein PIR Sensor
Der LED-Streifen soll bei einer Bewegung die LEDs einschalten. Das funktioniert.
Die LEDs sollen nach einer Zeit wieder ausgeschaltet werden. Das funktioniert nicht, auch nicht über pixels.clear. Der Timer funktioniert, aber die LEDs gehen nicht aus
Über die Sensortasten des MPR121 soll die Helligkeit der LEDs eingestellt werden können. Funktioniert nicht wirklich. Über Serial.print wird zwar alles richtig geschrieben, aber die LEDs dimmen nicht wirklich.

Den Code habe ich aus verschiedenen Beispielen und der I-Net Suche zusammengesetzt.

Evtl. kann jemand auf den Code einmal schauen und mir sagen was ich hier machen muss

Vorab schon einmal Danke

Ich habe erst einmal für die Tests das ganze über ein Breadboard realisiert. D.h. ich habe 11 Pixel am Arduino hängen.

Hier der Code


#include <Adafruit_NeoPixel.h>
//#ifdef __AVR__
// #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
//#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN        3 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 11 // Popular NeoPixel ring size

#include <Wire.h>
#include "Adafruit_MPR121.h"

#ifndef _BV
#define _BV(bit) (1 << (bit)) 
#endif

// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();

// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

//PIR Sensor
#define SENSOR_PIN 2
int calibrationTime = 30;
long unsigned int low;
long unsigned int pause = 100;
boolean lockLow = true;
boolean takeLowTime;
int PIRValue = 0;

//Light Section
int period = 10000;
unsigned long time_now = 0;
boolean LichtAn = false;
boolean Lichttest = false;
unsigned long now = millis();
unsigned long start = millis();
unsigned long elapsed = 0;

//Brightness Section
float BrightNessfactor = 21; // ensure that the factor multiplied with number of  mpr121 sensors is not above 255
float BrightnessValue = 66; // Max 255 for Brightness


Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels



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

  while (!Serial) { // needed to keep leonardo/micro from starting too fast!
    delay(10);
  }
  
  Serial.println("Adafruit MPR121 Capacitive Touch sensor test"); 

   pinMode(SENSOR_PIN, INPUT);
  
  // Default address is 0x5A, if tied to 3.3V its 0x5B
  // If tied to SDA its 0x5C and if SCL then 0x5D
  if (!cap.begin(0x5A)) {
    Serial.println("MPR121 not found, check wiring?");
    while (1);
  }
  Serial.println("MPR121 found!");

  //PIXEL Section
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
  #endif
  // END of Trinket-specific code.

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels.setBrightness(BrightnessValue);
  pixels.clear(); // Set all pixel colors to 'off'

  

}

void loop() {

 if (LichtAn == false){
    PIRSensor();
 }
 if (LichtAn == true){
   if (Lichttest == false){
   Licht_einschalten();
   }
   else {
  Licht();
  }
 }
  // Get the currently touched pads
  currtouched = cap.touched();
  
  for (uint8_t i=0; i<12; i++) {
    // it if *is* touched and *wasnt* touched before, alert!
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      
     
    }
    // if it *was* touched and now *isnt*, alert!
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
       BrightnessValue = (((i + 1) * BrightNessfactor)+1);
      Serial.print(BrightnessValue); Serial.print(" Brightness ");Serial.print(i); Serial.println(" touched");
          pixels.setBrightness(BrightnessValue);

    pixels.show();   // Send the updated pixel colors to the hardware.
    //pixels.clear();
    }
  }

  // reset our state
  lasttouched = currtouched;


  
 
}

void Licht() {
   
  if (LichtAn == true){
        now = millis();
        elapsed = now - start;  // elapsed: duration
        if (elapsed >= period){
         Serial.println("Licht aus");
         Serial.println(elapsed);
         LichtAn = false;
         Lichttest = false;
         pixels.clear(); 
        //Licht_ausschalten();
        }
  }

}


void PIRSensor() {
  int sensorValue = digitalRead(SENSOR_PIN);
  if (sensorValue == HIGH)
  {
         Serial.println("Schalte Licht ein");
         LichtAn = true;
         start = millis();
         Lichttest = true;
         Licht_einschalten();

      }
     
}


void Licht_einschalten(){
  Serial.println("Schalte das Licht ein ...");
   for(int l=0; l<NUMPIXELS; l++) { // For each pixel...
    pixels.setBrightness(BrightnessValue);
    pixels.setPixelColor(l, pixels.Color(255, 255, 255));
    pixels.show();   // Send the updated pixel colors to the hardware.
  }
}

void Licht_ausschalten(){
 Serial.println("Schalte Licht aus");
 
 for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
  pixels.setPixelColor(i, pixels.Color(0,0,0));
  }
  pixels.show();
}

1 Like

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

good

Sorry, I did not realize that I create my posting in the english section. Thanks for moving into the german section

bette den Code richtig ein.

Danke, habe ich gemacht

zeige mal

  1. damit die Neopixel auch ausgehen, reicht ein strip.clear(); nicht. das löscht nur das pixel-array.. mit strip.show(); muss man es nochmal an die neopixel weitergeben.

  2. setBrightness(x); ist fürs Dimmen nicht empfohlen und sollte nur 1x in der Setup benutzt werden.

The setBrightness() function as currently implemented operates directly on the pixel array and is 'lossy'. Since the original brightness value is not retained, once dimmed, you can never return to the exact original brightness value. The more you dim, the more information you lose.

lieber die pixel mit rgb-werten ansteuern, die du vorher mit einem variablen "brightness"-Wert (0-255) bearbeitet hast... z.B: setPixelColor(n, (brightness*r/255) , (brightness*g/255), (brightness*b/255));

#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include "Adafruit_MPR121.h"
#define NUMPIXELS 11

#define PIN    3
#define SENSOR_PIN 2

#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif

Adafruit_MPR121 cap = Adafruit_MPR121();

// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

//Brightness Section
const byte BrightNessfactor = 21; // ensure that the factor multiplied with number of  mpr121 sensors is not above 255
byte BrightnessValue = 66; // Max 255 for Brightness


Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

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

  Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
  if (!cap.begin(0x5A)) {  // Default address is 0x5A, if tied to 3.3V its 0x5B
    Serial.println("MPR121 not found, check wiring?");// If tied to SDA its 0x5C and if SCL then 0x5D
    while (1);
  } else  Serial.println("MPR121 found!");

  //PIXEL Section
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels.setBrightness(BrightnessValue);
  pixels.clear(); // Set all pixel colors to 'off'
}

void loop() {
  static unsigned long startZeit = 0;
  const uint16_t period = 10000;
  static boolean LichtSchonAn = false;

  if (LichtSchonAn == false) {
    if (digitalRead(SENSOR_PIN))  {
      startZeit = millis();
      Licht_einschalten();
    }
  }
  else {
    if (millis() - startZeit >= period) {
      Serial.println("Licht aus");
      Serial.println(millis() - startZeit);
      Licht_ausschalten();
    }
  }

  currtouched = cap.touched();  // Get the currently touched pads
  for (uint8_t i = 0; i < 12; i++) {
    if ((currtouched & _BV(i)) != (lasttouched & _BV(i)) ) {
      BrightnessValue = uint8_t(((i + 1) * BrightNessfactor) % 254 + 1);
      Serial.print(BrightnessValue); Serial.print(" Brightness "); Serial.print(i); Serial.println(" touched");
      lasttouched = currtouched;
      startZeit = millis();
      Licht_einschalten();
    }
  }
}

void Licht_einschalten() {
  Serial.println("Schalte das Licht ein ...");
  pixels.setBrightness(BrightnessValue);
  pixels.fill( pixels.Color(255, 255, 255), 0, NUMPIXELS);
  pixels.show();
  LichtSchonAn = true;
}

void Licht_ausschalten() {
  Serial.println("Schalte Licht aus");
  for (byte i = BrightnessValue; i > 5; i -= 5) {
    pixels.setBrightness(BrightnessValue);
    pixels.show();
  }
  //pixels.clear();
  LichtSchonAn = false;
}

Oder gleich mit dem HSV-Farbmodell arbeiten (HueSaturationValue) arbeiten.
Das können sowohl FastLed, als auch die AdaFruit-Lib.

Gruß Tommy

das ist doch in diesem Fall unwichtig.

Wenn er die Helligkeit im laufenden Betrieb einstellen will, ist der Informationsverlust alles andere als unwichtig.
Verbreitest Du die Falschaussage aus Bequemlichkeit oder aus Unkenntnis?

Gruß Tommy

hm, was für furchtbaren Schaden entsteht wenn aus 255 eine 245 wird? und ich frage mich, wer "im laufendem Betrieb" hin und her zwieschen Leuchtkraften springen wird ? was ist das für ein Gerät eigentlich?

So etwas kann nur einer sagen, der mit ordentlicher Programmierung nichts am Hut hat. Hauptsache es geht irgendwie in die von Dir gedachte Richtung.

Was am Ursprungsposting hast Du nicht verstanden:

Gruß Tommy

es wird eingestellt, das könntest sogar du sehen. aber nach Leuchtkraft wird du bestimmt nicht erkennen, dass da gerade die Brightness nicht 22, sondern die ganze 23 beträgt. und anstatt mir Schuldgefühl ein zu reden, konntest du einfach array[12] bilden wo exacte Werte für jede Taste gespeichert sind. ich finde es unnötig. so bin ich halt.

Ich nicht und ich werte auch weiter gegen solche Betrachtungsweisen vorgehen.

Gruß Tommy

Wo ist deine Sketch-Variante? oder bist du nur hinter mir her weil du mich minderwertig empfindest?

Leute
bitte nicht streiten.
Ich hatte im Eingangspost nicht beschrieben was ich damit vorhabe.

Der LED-Streifen wird dann mit ca. 60 LEDs hinter einem Spiegelglas unsichtbar angebracht.
Ich habe dazu aus einer Eichenbohle eine Vertiefung gefräst.
Das Spiegelglas wird auf eine dünne Platte für die evtl. notwendige Demontage geklebt. Rundherum auf wird dann der LED-Streifen hinter die Platte geklebt.
Dadurch leuchtet es dann dezent hinter dem Glas.
Der PIR-Sensor schaltet dann das Licht ein, sobald jemand den Raum betritt.
Der Plan ist, das die 12 Sensorflächen des MPR121 verlängert werden mit dünnen Kabeln. Diese Kabel enden dann in Stiften, welche an der Seite der Bohle in Bohrungen verschwinden.
Ich muss noch testen wie nah an der Oberfläche diese Stifte sein müssen damit der entsprechende Sensor angesprochen wird.
Der LED-Streifen soll dann warmweiß leuchten. Als Idee, wahrscheinlich Blödsinn, soll initial beim Einschalten des Lichts ein kurzer Farblauf stattfinden.

Das erst einmal zum Projekt.

Hier die aktuelle Verkabelung als Bild


Ach, nun willst Du die Helligkeit überhaupt nicht mehr mit dem MPR121 steuern?

Was stimmt den nun?

Gruß Tommy

Doch
der MPR121 hat 12 Sensorfelder, darauf löte ich dann die Kabel welche in den Stiften enden. Diese Stifte werden dann in den Bohrungen angebracht. Wenn ich diese nicht unsichtbar unterbringen kann, dann werden eben Messingstifte seitlich in das Holz eingebracht und diese mit dem MPR121 verbunden.

Der Farbton soll weiterhin warmweiß sein. Nur die Helligkeit soll über den MPR121 einstellbar sein.

Evtl. habe ich hier einen Denkfehler.