Probleme im loop mit nrf24l01 Taster / LED Steuerung

Servus liebe Arduino Experten,

ich habe ein kleines Problem mit meiner Schaltung welches wie folgt aussieht.

Ich arbeite mit Arduino Pro Mini’s. Ich habe ein Arduino (Nr. 1) mit 2 Tastern konfiguriert, welche nach dem Drücken ein Signal über ein nrf24L01 Sender / Empfänger an einen anderen Arduino (Nr. 2) sendet und dort verschiedene LED’s an / abschaltet. Soweit so gut.

ich poste anbei einmal den Code des Empfängers.
Taster 1 schaltet verschiedene LEDs an und nach “loslassen” des Tasters wieder ab. Der 2.te Taster wiederum schaltet andere LED’s nach einer Reihenfolge ab und an (siehe Code schalter 0). Und genau hier liegt das Problem.

Die IF Schleife des 2.ten Tasters soll laut Code auch nur einmal durchlaufen werden. In der Realität wird diese Schleife aber 3-4 mal ausgeführt. Und das ist mir leider unerklärlich.

ich konnte das Problem lösen, indem ich einen weiteren Arduino (Nr. 3) als Signalempfänger der Taster eingesetzt habe und dieser dann wieder die eigentlichen Tasterpins an Arduino Nr. 2 steuert. Allerdings glaube ich, dass es auch ohne den 3.ten Arduino gehen muss, da die Schaltung insoweit ja reibungslos funktioniert.

Hab schon alles mögliche Probiert, leider ohne Erfolg.

Für Hilfe wäre ich sehr dankbar. (Schalter 0 ist derjenige, welche sich in der Realität immer wieder wiederholt)

// receiver

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

int schalter[2];

RF24 radio(8,7);
const uint64_t pipe = 0xE8E8F0F0E1LL;


int LED1 = 4; 
int LED2 = 5; 
int LED3 = 6; 
int LED4 = 9; 


int LED5 = A4; 
int LED6 = 2; 


int LED7 = A5; 
int LED8 = 3;  


void setup(void)
{
// Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();

pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);


}


void loop(void)
{
 
if (radio.available())
{
  
  bool done = false;    
  while (!done)
  {
    
    done = radio.read(schalter, sizeof(schalter));      
    


    if (schalter[0] == 1)
    {
     delay(10);

 
     digitalWrite(LED6, HIGH);
     digitalWrite(LED5, HIGH); 
     delay(100);
     digitalWrite(LED6, LOW);
     digitalWrite(LED5, LOW); 
     delay(100);
     digitalWrite(LED4, HIGH);
     delay(100);
     digitalWrite(LED4, LOW); 
     delay(100);
 

    }
    else 
    {
     digitalWrite(LED4, LOW);
     digitalWrite(LED5, LOW);
     digitalWrite(LED6, LOW);
     
    }
    delay(10);

    
    if (schalter[1] == 1)
    {
     delay(10);
     digitalWrite(LED1, HIGH);
     digitalWrite(LED2, HIGH);
     digitalWrite(LED3, HIGH);
     digitalWrite(LED7, HIGH);
    }
    else 
    {
     digitalWrite(LED1, LOW);
     digitalWrite(LED2, LOW);
     digitalWrite(LED3, LOW);
     digitalWrite(LED7, LOW);
    }
    delay(10);


    
  }

  
}
else
{

}
   
}

Da beide If-Abfragen in der Loop liegen, werden diese selbstverständlich auch immer abgefragt.
Außerdem sehe ich nicht, wo du die Eingangszustände (digitalread) des Empfängers einliest.

eingelesen werden die Zustände durch done = radio.read(schalter, sizeof(schalter));

Das mit den if schleifen in der loop ist schon richtig so und auch nicht das Problem.
Vielleicht nicht ganz deutlich ausgedrückt.

Das Problem liegt darin, das bei diesem Code die erste if Schleife anscheinend mehrmals ausgeführt werden ohne ersichtlichen Grund.

Wirkt sich wie folgt aus: erste if schleife läuft durch, ich lege den Schalter um auf AUS und der Inhalt der Schleife läuft dennoch noch 3 bis 4 mal. Gut ersichtlich, da die LEDs ja leuchten.

Zweite if schleife läuft hingegen problemlos.

Es wäre schön, wenn du den Code wie üblich, in Code-Tags (</>) hier einsetzt, dann ist dieser auch besser lesbar.

Es gibt keine if Schleifen :wink:

Du hast hier eine (sinnlose) Schleife:

while (! done ) { 
done = radio.read(...)
... viel Wartezeit ...
}

Keine Ahnung, warum du dich wunderst, dass radio.read() mehrfach false zurückliefert.

Zum Test würde ich erstmal eine Version ohne delay (und ohne Schleifen) schreiben, die einfach meldet, was kommt.

void loop () {
   if( radio.available() ) {
      int schalter[2]; // warum int, ist das Absicht ???
      radio.read(schalter, 4) ; // sizeof(schalter) ist 4 ! 
      Serial.print(schalter[0]); Serial.println(schalter[1]);
   }
}

P.S. Wenn dir mein Ton ruppig vorkommt, das täuscht. Herzlich willkommen im Forum.

Sollte Dir die Frage durch den Kopf gehen, wie man LEDs ohne delay() zum Blinken bringt, hier eine Anregung:

const byte LED1 = 4;
const byte LED2 = 5;
const byte LED3 = 6;
unsigned long aktMillis;
unsigned long prevMillis;
const int intervall = 100;
byte state = 0;
bool schalter[2];

void setup() {
  Serial.begin(9600);
  Serial.println("Programmanfang");
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    char zeichen = Serial.read();
    switch (zeichen) {
      case '1':
        schalter[0] = true;
        break;
      case '2':
        schalter[0] = false;
        break;
      case '3':
        schalter[1] = true;
        break;
      case '4':
        schalter[1] = false;
        break;
    }
  }

  aktMillis = millis();
  if (schalter[0] == true) {
    if (aktMillis - prevMillis >= intervall) {
      prevMillis = aktMillis;
      switch (state) {
        case 0:
          digitalWrite(LED2, HIGH);
          digitalWrite(LED3, HIGH);
          break;
        case 1:
          digitalWrite(LED2, HIGH);
          digitalWrite(LED3, LOW);
          break;
        case 2:
          digitalWrite(LED2, LOW);
          digitalWrite(LED3, HIGH);
          break;
      }
      state = (state + 1) % 3;
    }
  }
  else {
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
  }

  if (schalter[1] == true) {
    digitalWrite(LED1, HIGH);
  }
  else {
    digitalWrite(LED1, LOW);
  }
}

Danke für die Hilfe und Infos. Leider besteht das Problem nach wie vor.

Ich habe nun folgendes getan (nacheinander).

  1. while Schleife entfernt -> wie beschrieben nur Zeitgewinn

  2. Schalter 0 und 1 vertauscht -> Problem überträgt sich auf neuen Schalter

  3. Zustände ausgelesen mit Serial.print -> Der if Teil (welcher ohne Delays läuft) also nicht an und abschaltet, sondern nur anschaltet, läuft problemlos.

Der 2.te if Teil mit An / Abschaltung, also Delays zeigt auch bei Serial.print zustand 1, dann erneuter durchlauf wieder 1 und das 3 mal nacheinander. Erst dann realisiert er den neuen Zustand 0 = Aus.

Ich denke das Problem liegt daran, das er LED's im if Teil abschaltet. Irgendwie scheint er damit nicht ganz zurecht zukommen. Sobald die Delay's und LED LOW entfernt wurden, funktioniert es problemlos und auch Serial.Print läuft richtig.

Sehr merkwürdig

Dann setze den geänderten Sketch in Code-Tags hier rein, dann können wir auch nachvollziehen was du geändert hast.
Bitte nehme die Code-Tags, damit es für uns lesbarer ist.

aktuell ist Code wie folgt:

// receiver

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

int schalter[2];

RF24 radio(8,7);
const uint64_t pipe = 0xE8E8F0F0E1LL;


int LED1 = 4; 
int LED2 = 5; 
int LED3 = 6; 
int LED4 = 9; 


int LED5 = A4; 
int LED6 = 2; 


int LED7 = A5; 
int LED8 = 3;  


void setup(void)
{
// Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();

pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);


}


void loop(void)
{
 
if (radio.available())
{

    
    radio.read(schalter, sizeof(schalter));      
    
    //Serial.print("Schalter 0 = "); Serial.println(schalter[0]);

    if (schalter[0] == 1)
    {
     delay(10);

 
     digitalWrite(LED6, HIGH);
     digitalWrite(LED5, HIGH); 
     delay(100);
     digitalWrite(LED6, LOW);
     digitalWrite(LED5, LOW); 
     delay(100);
     digitalWrite(LED4, HIGH);
     delay(100);
     digitalWrite(LED4, LOW); 
     delay(100);
 

    }
    else 
    {
     digitalWrite(LED4, LOW);
     digitalWrite(LED5, LOW);
     digitalWrite(LED6, LOW);
     
    }
    delay(10);

    
    if (schalter[1] == 1)
    {
     delay(10);
     digitalWrite(LED1, HIGH);
     digitalWrite(LED2, HIGH);
     digitalWrite(LED3, HIGH);
     digitalWrite(LED7, HIGH);
    }
    else 
    {
     digitalWrite(LED1, LOW);
     digitalWrite(LED2, LOW);
     digitalWrite(LED3, LOW);
     digitalWrite(LED7, LOW);
    }
    delay(10);


    
  

  
}
else
{

}
   
}

seb745:
aktuell ist Code wie folgt:

Habe ich die falsche Brille auf, oder warum sehe ich da immer noch viele delays?

Probiere mal dies:

   if (schalter[0] == 1)
    {
     digitalWrite(LED6, HIGH);
    }
    else 
    {
     digitalWrite(LED6, LOW);
    }

@agmue

hab den alten Code mit delays verwendet, da in mein Code unterschiedliche delay größen verwendet.
Der Einfachheit halber habe ich hier alle auf 100 gesetzt.

Dein Code mit LED 6 HIGH und LOW funktioniert ohne Probleme

seb745:
Dein Code mit LED 6 HIGH und LOW funktioniert ohne Probleme

Da bist Du doch einen Schritt weiter! :slight_smile:

Jetzt schaue Dir mal #5 an.