Bewegungssensor mit Neopixel

HotSystems:
Fürs WC ? ? ?
:grin:

Noch nie was von Großraum-WCs gehört?

Und wenn, es sind alles nur Ideen/Gedanken, die dem TO helfen sollen.

Da bin ich Deiner Meinung.
Grüße Uwe

uwefed:
Noch nie was von Großraum-WCs gehört?

Ahhh....ok, da macht es Sinn.

Hallo, da bin ich wieder.
Also das mit millis() habe ich halbwegs verstanden. Zumindest so, dass ich den LED Streifen für eine gewünschte Zeit leuchten lassen kann.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN_LED 9 
#define NUMPIXELS 24
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUMPIXELS, PIN_LED, NEO_GRB + NEO_KHZ800);

unsigned long Zeit;  

int sensor = 6;
int cap = 11;
int neo = 9;
int neoStatus = LOW;
int i = 0;

void setup() 
{
  pinMode(cap, INPUT);
  pinMode(sensor, INPUT_PULLUP); 
  pinMode(neo, OUTPUT);
}

void loop() 
{
  
  if (neoStatus == LOW && digitalRead(6) == LOW) 
 {
    if (millis() - Zeit> 1000 ) 
    {
        for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(160,50,60)); 
   pixel.show();
   Zeit = millis();
  }

    }
 } else 
  {
    if (millis() - Zeit> 5000)  
   {
        for(int i = 0; i<NUMPIXELS;i++)
    {

   pixel.setPixelColor(i, pixel.Color(0,0,0)); 
   pixel.show();
    }

 
   }
  }
}

Wenn ich aber den touchsensor mit einspanne, dann flackert der LED Streifen.
Muss ich dafür einen neuen loop schreiben?

Das macht die Bibliothek, bitte löschen:

int neo = 9;
...
  pinMode(neo, OUTPUT);

Wo wird neoStatus verändert?

Wo wird cap verwendet?

agmue:
Das macht die Bibliothek, bitte löschen:

int neo = 9;

...
 pinMode(neo, OUTPUT);



Wo wird neoStatus verändert?

Wo wird cap verwendet?

Danke für den Hinweis.
Hab den code umgeschrieben und "cap" (capacitive sensor) hinzugefügt .
Macht fast, was es machen soll.
Sensor erfasst Bewegung LED Streifen leuchtet für 5 Sekunden in Lila und geht dann aus.
Drücke ich auf den cap, leuchtet der LED Streifen Weiß, bis ich wieder auf den cap drücke.
Allerdings leuchtet der LED Streifen 5 Sekunden nach. Durch rum probieren, stellte ich fest, dass die eingestellte Zeit von dem Sensor übernommen wurde. Wie kann ich das vermeiden?

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN_LED 9 
#define NUMPIXELS 24
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUMPIXELS, PIN_LED, NEO_GRB + NEO_KHZ800);

unsigned long Zeit;  

int sensor = 6;
int cap = 11;

int capStatus = LOW;
int i = 0;

void setup() 
{
  pinMode(cap, INPUT);
  pinMode(sensor, INPUT_PULLUP); 
  pinMode(PIN_LED, OUTPUT);
}

void loop() 
{
  capStatus = digitalRead(cap);
  if (capStatus == LOW && digitalRead(6) == LOW) 
 {
    if (millis() - Zeit> 1000 ) 
    {
        for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(160,50,60)); 
   pixel.show();
   Zeit = millis();
  }

    }
 } else 
  {
    if (millis() - Zeit> 5000)  
   {
        for(int i = 0; i<NUMPIXELS;i++)
    {

   pixel.setPixelColor(i, pixel.Color(0,0,0)); 
   pixel.show();
    }

 
   }
  }
  if (capStatus == HIGH )
         {
          if (millis() - Zeit> 1000)
          {
            for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(250,250,250)); 
   pixel.show();
   Zeit = millis();
          }
         }
            
       }
}

Hallo,

nein es gibt nur einen loop. Wozu soll ein zweiter gut sein ? Wenn man bestimmte Teile nicht bearbeiten will kann man z.B mit if.. verzweigen.

ich sehe auch keinen Touch sensor in Deinem Sketch. Wozu dient die variable Neostatus. Ich glaube auch nicht das Du millis() schon verstanden hast.

Was soll Dein Sketch denn machen ?

ich vermute mit dem Taster sollen alle LED an gehen und wenn der Taster losgelassen wird soll nach 5 s alle aus gehen. Der Sensor soll dann was machen? andere Farbe und dauernd ein ?

Um Dein Programm zu gliedern kannst Du Functions verwenden.

ich habe Dir jetzt mal einen Ansatz gemacht mit zwei Taster und einer LED die ich mit analogWrite unterschiedlich hell einschalte. Du muss halt in die Funktionen die LED Streifen einbauen.

Heinz

const byte btnsens = 6;//
const byte btntouch = 7;
const byte ledpin = 9;
unsigned long altzeit;

bool touch, touchstate;
bool touchhelp; // helpflag für die Flankenerkennung

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btnsens, INPUT_PULLUP);
  pinMode(btntouch, INPUT_PULLUP);
  pinMode(ledpin, OUTPUT);
}

void loop() {
  touch = !digitalRead(btntouch); // einlesen
  if (touch & !touchhelp) {   // Flanke bilden
    touchhelp = true;
    touchstate = !touchstate; // Toggle
    Serial.print(touchstate);
  }

  if (!touch)touchhelp = false; // Reset help Flag
  delay(10); // entprellen
  
  if (touchstate) {
    stripweiss();
  }
  else if (digitalRead(btnsens) == LOW) {
    altzeit = millis();
    striprot();
  }
  else {
    if ( millis() - altzeit > 5000) {
      stripaus();
    }
  }
} // Loop ende 

// ======Funktionen ==============
void stripweiss(){
   analogWrite(ledpin, 255);
  // hier alle weiß ein
}

void striprot(){
  // hier alle rot
  analogWrite(ledpin, 64);
}

void stripaus(){
  //hier alle aus
  analogWrite(ledpin, 0);
}

Rentner:
Was soll Dein Sketch denn machen ?

ich vermute mit dem Taster sollen alle LED an gehen und wenn der Taster losgelassen wird soll nach 5 s alle aus gehen. Der Sensor soll dann was machen? andere Farbe und dauernd ein ?

Sensor erkennt Bewegung = Led Streifen Pink - nach 5 Sekunden Led Streifen aus.
Wenn Touchsensor betätigt = Led Streifen Weiß dauerhaft.
Wenn Touchsensor nochmals betätigt = Led Streifen aus.

kucko:
Sensor erkennt Bewegung = Led Streifen Pink - nach 5 Sekunden Led Streifen aus.
Wenn Touchsensor betätigt = Led Streifen Weiß dauerhaft.
Wenn Touchsensor nochmals betätigt = Led Streifen aus.

Hallo,

dachte ich mir , dann kannst Du meinen Vorschlag sicher gebrauchen

Heinz

Rentner:
Hallo,

dachte ich mir , dann kannst Du meinen Vorschlag sicher gebrauchen

Heinz

Danke, ich werde versuchen es einzubauen.
Noch eine Frage zu den Funktionen.
Müsste es in etwa so aussehen?

void stripweiss() 
{
   for(int i = 0; i<NUMPIXELS;i++)
 {
   pixel.setPixelColor(i, pixel.Color(250,250,250)); 
   pixel.show();
 }
}

Hallo,

fast , das pixel.show() sollte hinter die for schleife. Jedes Pixel setzen und dann alle gemeinsam ein.

show bedient den gesamten streifen und dauert auch ziemlich lange, die Daten müssen ja schließlich nacheinander an jede LED raus.

void stripweiss()
{
  for(int i = 0; i<NUMPIXELS;i++)
  {
    pixel.setPixelColor(i, pixel.Color(250,250,250));
  
  }
pixel.show();
}

Rentner:
Hallo,

fast , das pixel.show() sollte hinter die for schleife. Jedes Pixel setzen und dann alle gemeinsam ein.

show bedient den gesamten streifen und dauert auch ziemlich lange, die Daten müssen ja schließlich nacheinander an jede LED raus.

void stripweiss()

{
 for(int i = 0; i<NUMPIXELS;i++)
 {
   pixel.setPixelColor(i, pixel.Color(250,250,250));
 
 }
pixel.show();
}

Rentner:
Hallo,

fast , das pixel.show() sollte hinter die for schleife. Jedes Pixel setzen und dann alle gemeinsam ein.

show bedient den gesamten streifen und dauert auch ziemlich lange, die Daten müssen ja schließlich nacheinander an jede LED raus.

Hatte es schon vor die "for Schleife" eingebaut. Funktioniert fast richtig. Ein Problem mit dem touchsensor habe ich. Ich muss immer 2 mal rauf drücken um den Status zu ändern.

Hallo Heinz,
kannst mir bitte den folgenden Vorgang aus deinem code erklären.

touch = !digitalRead(btntouch); // einlesen
  if (touch & !touchhelp) {   // Flanke bilden
    touchhelp = true;
    touchstate = !touchstate; // Toggle
    Serial.print(touchstate);
  }

  if (!touch)touchhelp = false; // Reset help Flag
  delay(10); // entprellen

Verstehe das nicht wirklich. Woher kommt das help her?

void stripweiss()
{
...
   pixel.setPixelColor(i, pixel.Color(250,250,250)); 
...

Hat es einen Grund wieso bei Dir Weiß 250,250,250 ist und nicht 255,255,255?
Grüße Uwe

uwefed:

void stripweiss()

{
...
  pixel.setPixelColor(i, pixel.Color(250,250,250));
...




Hat es einen Grund wieso bei Dir Weiß 250,250,250 ist und nicht 255,255,255?
Grüße Uwe

Keinen besonderen, wenn der code endgültig fertig ist, ändere ich das auf 255 :slight_smile:

kucko:
Keinen besonderen, wenn der code endgültig fertig ist, ändere ich das auf 255 :slight_smile:

Ratschlag: Mach das sofort weil Du das ansonsten vergißt.
Grüße Uwe

uwefed:
Ratschlag: Mach das sofort weil Du das ansonsten vergißt.
Grüße Uwe

Vielen Dank für den Ratschlag. Hab's angenommen und umgesetzt.

kucko:
kannst mir bitte den folgenden Vorgang aus deinem code erklären.

touch = !digitalRead(btntouch); // einlesen

if (touch & !touchhelp) {  // Flanke bilden
...

Häufig lautet eine Anforderung: "Wenn ich eine Taste drücke, dann ...". Im Programm wird dann daraus if(!digitalRead(btntouch)) {}. Häufig funktioniert das aber so nicht, da ein µC einen Tastendruck als sehr lang "empfindet", viele loops lang.

Daher wäre die genauere Formulierung: "Wenn sich der Zustand der Taste von nicht gedrückt nach gedrückt ändert, dann ...". Im Programm wird dann daraus der Vergleich von aktuellem zu altem Zustand: if(!akt_touch & alt_touch) {}. Das nennt man Flankenerkennung.

Heinz hat etwas andere Bezeichnungen verwendet wie touchhelp für den alten Zustand, also Hilfsmerker für touch.

Verständlich?

Hallo,

@agmue danke für die Antwort , zeugt mal wieder vom Teamgeist hier im Forum.

ja die Variable xxHelp zu nennen ist ein Überbleibsel aus meiner langjährigen SPS Zeit, es ist halt eine Hilfsmerker zur Bildung einer Flanke.

unter Step5 Zeiten sah das dann in AWL so aus:

U  E2.0       Abfrage Eingang
UN M2.1       Hilfsmerker
=  M2.2       Flanke E2.0
UN E2.0
=  M2.1      Reset Hilfsmerker

Unter Step7 ging das etwas komfortabler

man möge mir den kleinen Abschweifer verzeihen :slight_smile:

@T0 Wenn du den Touch immer zweimal drücken musst könnte es daran liegen das er positiv schaltend ist. dann musst Du das PULLUP weglassen beim pinMode und das ! vor

touch = !digitalRead(btntouch); // einlesen

Heinz

das show gehört immer hinter die for.. Schleife , macht doch sonst keinen Sinn.

Heinz

Rentner:
Hallo,

@agmue danke für die Antwort , zeugt mal wieder vom Teamgeist hier im Forum.

ja die Variable xxHelp zu nennen ist ein Überbleibsel aus meiner langjährigen SPS Zeit, es ist halt eine Hilfsmerker zur Bildung einer Flanke.

unter Step5 Zeiten sah das dann in AWL so aus:

U  E2.0       Abfrage Eingang

UN M2.1       Hilfsmerker
=  M2.2       Flanke E2.0
UN E2.0
=  M2.1      Reset Hilfsmerker




Unter Step7 ging das etwas komfortabler

man möge mir den kleinen Abschweifer verzeihen :) 

@T0 Wenn du den Touch immer zweimal drücken musst könnte es daran liegen das er positiv schaltend ist. dann musst Du das PULLUP weglassen beim pinMode und das ! vor 

touch = !digitalRead(btntouch); // einlesen

Heinz

das show gehört immer hinter die for.. Schleife , macht doch sonst keinen Sinn. 

Heinz

Danke @ agmue und Heinz.
Ich habe das "pixel.show" Richtigkeit halber hinter die for Schleife geschrieben, auch wenn es auch in der for Schleife funktioniert hat( warum auch immer, Hauptsache funktioniert).
Das Problem mit dem touchsensor konnte ich nicht beheben. Nach wie vor muss ich zweimal berühren auch beim ausschalten.
Ich beschreibe es mal kurz:
erster touch = LED Streifen bleibt dunkel
zweiter touch = LED Streifen leuchtet
dritter touch = LED Streifen leuchtet weiterhin
vierter touch = LED Streifen geht aus
Hier ist der Code :

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN_LED 9 
#define NUMPIXELS 24
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUMPIXELS, PIN_LED, NEO_GRB + NEO_KHZ800);

const byte btnsens = 6;    // Lichtschranke
const byte btntouch = 11;  // Capacitive touch

unsigned long altzeit;

bool touch, touchstate;
bool touchhelp; // helpflag für die Flankenerkennung

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btnsens, INPUT_PULLUP);
  pinMode(btntouch, INPUT);
  pinMode(PIN_LED, OUTPUT);
}

void loop() {
  touch = !digitalRead(btntouch); // einlesen
  if (touch & !touchhelp) {   // Flanke bilden
    touchhelp = true;
    touchstate = !touchstate; // Toggle
    Serial.print(touchstate);
  }

  if (!touch)touchhelp = false; // Reset help Flag
  delay(10); // entprellen
  
  if (touchstate) {
    stripweiss();
  }
  else if (digitalRead(btnsens) == LOW) {
    altzeit = millis();
    striprot();
  }
  else {
    if ( millis() - altzeit > 5000) {
      stripaus();
    }
  }
} // Loop ende 

// ======Funktionen ==============
void stripweiss()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(255,255,255)); 
   
  }
  pixel.show();
}

void striprot()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(250,0,0)); 
   
  }
  pixel.show();
}

void stripaus()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(0,0,0)); 
   
  }
  pixel.show();
}

Hallo,

was gibt der Monitor aus , der Status von touchstate müsste sich doch jedesmal ändern. Die Monitorausgabe dazu ist ja noch drin, damit kannst Du das sehen.

oder versuch mal den

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN_LED 9
#define NUMPIXELS 24
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUMPIXELS, PIN_LED, NEO_GRB + NEO_KHZ800);

const byte btnsens = 6;    // Lichtschranke
const byte btntouch = 11;  // Capacitive touch

unsigned long altzeit;

bool touch, touchstate;
bool touchhelp; // helpflag für die Flankenerkennung

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btnsens, INPUT_PULLUP);
  pinMode(btntouch, INPUT);
  pinMode(PIN_LED, OUTPUT);
}

void loop() {
  touch = digitalRead(btntouch); // einlesen  **** hier ist geändert 
  if (touch & !touchhelp) {   // Flanke bilden
    touchhelp = true;
    touchstate = !touchstate; // Toggle
    Serial.print(touchstate);
  }

  if (!touch)touchhelp = false; // Reset help Flag
  delay(10); // entprellen
 
  if (touchstate) {
    stripweiss();
  }
  else if (digitalRead(btnsens) == LOW) {
    altzeit = millis();
    striprot();
  }
  else {
    if ( millis() - altzeit > 5000) {
      stripaus();
    }
  }
} // Loop ende

// ======Funktionen ==============
void stripweiss()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(255,255,255));
   
  }
  pixel.show();
}

void striprot()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(250,0,0));
   
  }
  pixel.show();
}

void stripaus()
{
   for(int i = 0; i<NUMPIXELS;i++)
  {

   pixel.setPixelColor(i, pixel.Color(0,0,0));
   
  }
  pixel.show();
}