nfr24l01 drei Arduinos wie komunizieren

Hallo zusammen,

ich habe mir vor einer Woche einige NRF24 Module bestellt, weil ich ein kleines Netzwerk aufbauen möchte.
Nun habe ich mich langsam an das Thema herangetastet und einige tutorials und Beispielsketche durchgearbeitet. Ich habe hinbekommen, dass sich von Arduino Nr1 eine Nachricht an Arduino Nr2 sende, so dass bei Betätigung eines Knopfes an A1 eine LED an A2 leuchtet.

Die nächste Erweiterung die ich hin bekommen habe: ich kann an A1 einen knopf betätigen und LED an A2 leuchtet. Dazu kommt nun Knopf an A2 lässt LED an A1 leuchten.

Soweit so gut. Beim nächsten Versuch habe ich einen dritten Arduino ins Spiel gebracht:
Knopf an A1 lässt LED an A2 leuchten
Knopf an A1 lässt LED an A3 leuchten
Juhu, geht auch…

Also nächste Erweiterung:
Knopf an A1 lässt LED an A2 leuchten
Knopf an A1 lässt LED an A3 leuchten
Knopf an A2 lässt LED an A1 leuchten
Geht auch!

Aber jetzt wird’s tricky, bzw. will einfach nicht mehr funktionieren… Bin am verzweifeln. So solls aussehen:
Knopf an A1 lässt LED an A2 leuchten
Knopf an A1 lässt LED an A3 leuchten
Knopf an A2 lässt LED an A1 leuchten
Knopf an A3 lässt LED an A1 leuchten (eine 2te LED, also nicht die eine Zeile drüber)

Anbei mal die Sketche:

suzusagen der MASTER:


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int sa=2;
int sb=3;
boolean stata=0;
boolean statb=0;
boolean buttonstate=0;
boolean buttonstatee=0;

int leda=6;
int ledb=5;
RF24 radio(7,8);

const byte rxAddr[6]={“null”,“eins”,“zwei”,“drei”};

void setup() {
// put your setup code here, to run once:
pinMode(leda,OUTPUT);
pinMode(ledb,OUTPUT);
pinMode(sa,INPUT);
pinMode(sb,INPUT);
radio.begin();
Serial.begin(115200);

//radio.openReadingPipe(0,rxAddr[2]);
//radio.openReadingPipe(0,rxAddr[3]);
//radio.setRetries(15, 15);
radio.setPALevel(RF24_PA_MIN);

}

void loop() {
while(radio.available());
radio.openWritingPipe(rxAddr[1]);
radio.stopListening();
stata=digitalRead(sa);
radio.write(&stata, sizeof(stata));

while(radio.available());
radio.openWritingPipe(rxAddr[0]);
radio.stopListening();
statb=digitalRead(sb);
radio.write(&statb, sizeof(statb));

/////////////////////
radio.openReadingPipe(0,rxAddr[2]);
radio.startListening();
while(!radio.available());

radio.read(&buttonstate,sizeof(buttonstate));

if(buttonstate==LOW){
digitalWrite(leda,HIGH);
}
else{
digitalWrite(leda,LOW);
}
radio.stopListening();

/*
/////////////////////
radio.openReadingPipe(0,rxAddr[2]);
radio.startListening();
while(!radio.available());
radio.read(&buttonstatee,sizeof(buttonstatee));
if(buttonstatee==LOW){
digitalWrite(ledb,HIGH);
}
else{
digitalWrite(ledb,LOW);
}
radio.stopListening();
*/
}


jetzt Slave 1:


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int led=6;
boolean buttonstate=0;
int sa=5;
int stata;

RF24 radio(7, 8);

const byte rxAddr[6]={“null”,“eins”,“zwei”,“drei”};

void setup(){
pinMode(sa,INPUT);
pinMode(led, OUTPUT);
Serial.begin(115200);

radio.begin();

radio.setPALevel(RF24_PA_MIN);
}

void loop(){
radio.startListening();
radio.openReadingPipe(0, rxAddr[0]);
while(!radio.available());
radio.read(&buttonstate, sizeof(buttonstate));
if (buttonstate==LOW){
digitalWrite(led,HIGH);
Serial.println(buttonstate);
}
else{
digitalWrite(led,LOW);
Serial.println(buttonstate);
}
/////////////////////////////////
radio.stopListening();
while(radio.available());
radio.openWritingPipe(rxAddr[2]);
stata=digitalRead(sa);
radio.write(&stata,sizeof(stata));
}


und Slave 2:


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int led=6;
boolean buttonstate=0;
int sa=5;
int stata;

RF24 radio(7, 8);

const byte rxAddr[6]={“null”,“eins”,“zwei”,“drei”};

void setup(){
pinMode(sa,INPUT);
pinMode(led, OUTPUT);
Serial.begin(115200);

radio.begin();

radio.setPALevel(RF24_PA_MIN);
}

void loop(){
radio.startListening();
radio.openReadingPipe(0, rxAddr[1]);
while(!radio.available());
radio.read(&buttonstate, sizeof(buttonstate));
if (buttonstate==LOW){
digitalWrite(led,HIGH);
Serial.println(buttonstate);
}
else{
digitalWrite(led,LOW);
Serial.println(buttonstate);
}
/*
/////////////////////////////////
radio.stopListening();
while(radio.available());
radio.openWritingPipe(rxAddr[3]);
stata=digitalRead(sa);
radio.write(&stata,sizeof(stata));
*/
}


ach ja verwende TMRh20 Lib…

Kann mir jemand einen Tipp geben was ich anpassen muss?!?!?

Ja, passe bitte deine Sketche an.
Die werden fehlerhaft angezeigt, da du keine Code-Tags verwendest.
Setze die Sketche also in Code-Tags, das kannst du auch nachträglich noch machen.
Dann werden die auch besser angezeigt und können auch endlich auf mobilen Geräten besser gelesen werden.

Ich hoffe jetzt kann man es besser verarbeiten…

master.ino (1.46 KB)

Slave1.ino (836 Bytes)

Slave2.ino (846 Bytes)

Johannes81:
Ich hoffe jetzt kann man es besser verarbeiten...

Nein, die lassen sich auf einem Mobilen Gerät erst garnicht öffnen.
Warum verwendest du keine Code-Tags ? das hilft uns allen.

jetzt aber :art:

MASTER

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int sa=2;
int sb=3;
boolean stata=0;
boolean statb=0;
boolean buttonstate=0;
boolean buttonstatee=0;

int leda=6;
int ledb=5;
RF24 radio(7,8);

const byte rxAddr[][6]={"null","eins","zwei","drei"};

void setup() {
  // put your setup code here, to run once:
  pinMode(leda,OUTPUT);
  pinMode(ledb,OUTPUT);
  pinMode(sa,INPUT);
  pinMode(sb,INPUT);
radio.begin();
Serial.begin(115200);

//radio.openReadingPipe(0,rxAddr[2]);
//radio.openReadingPipe(0,rxAddr[3]);
//radio.setRetries(15, 15);
radio.setPALevel(RF24_PA_MIN);

}

void loop() {
while(radio.available());
  radio.openWritingPipe(rxAddr[1]);
  radio.stopListening();
  stata=digitalRead(sa);
  radio.write(&stata, sizeof(stata));

  
  while(radio.available());
  radio.openWritingPipe(rxAddr[0]);
  radio.stopListening();
  statb=digitalRead(sb);
  radio.write(&statb, sizeof(statb));

  /////////////////////
  radio.openReadingPipe(0,rxAddr[2]);
  radio.startListening();
  while(!radio.available());
 
  radio.read(&buttonstate,sizeof(buttonstate));

  if(buttonstate==LOW){
    digitalWrite(leda,HIGH);
  }
  else{
    digitalWrite(leda,LOW);
  }
  radio.stopListening();

  /*
  /////////////////////
  radio.openReadingPipe(0,rxAddr[2]);
  radio.startListening();
  while(!radio.available());
  radio.read(&buttonstatee,sizeof(buttonstatee));
  if(buttonstatee==LOW){
    digitalWrite(ledb,HIGH);
  }
  else{
    digitalWrite(ledb,LOW);
  }  
  radio.stopListening();
 */
}

salve 1

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int led=6;
boolean buttonstate=0;
int sa=5;
int stata;

RF24 radio(7, 8);

const byte rxAddr[][6]={"null","eins","zwei","drei"};

void setup(){
  pinMode(sa,INPUT);
  pinMode(led, OUTPUT);
  Serial.begin(115200);

  radio.begin();
 
  radio.setPALevel(RF24_PA_MIN);
}


void loop(){
  radio.startListening();
   radio.openReadingPipe(0, rxAddr[0]);
  while(!radio.available());
  radio.read(&buttonstate, sizeof(buttonstate));
  if (buttonstate==LOW){
    digitalWrite(led,HIGH);
    Serial.println(buttonstate);
  }
  else{
    digitalWrite(led,LOW);
    Serial.println(buttonstate);
  }
  /////////////////////////////////
  radio.stopListening();
  while(radio.available());
  radio.openWritingPipe(rxAddr[2]);
  stata=digitalRead(sa);
  radio.write(&stata,sizeof(stata));
}

Slave 2

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int led=6;
boolean buttonstate=0;
int sa=5;
int stata;

RF24 radio(7, 8);

const byte rxAddr[][6]={"null","eins","zwei","drei"};

void setup(){
  pinMode(sa,INPUT);
  pinMode(led, OUTPUT);
  Serial.begin(115200);

  radio.begin();
  
  radio.setPALevel(RF24_PA_MIN);
}


void loop(){
  radio.startListening();
  radio.openReadingPipe(0, rxAddr[1]);
  while(!radio.available());
  radio.read(&buttonstate, sizeof(buttonstate));
  if (buttonstate==LOW){
    digitalWrite(led,HIGH);
    Serial.println(buttonstate);
  }
  else{
    digitalWrite(led,LOW);
    Serial.println(buttonstate);
  }
  /*
  /////////////////////////////////
  radio.stopListening();
  while(radio.available());
  radio.openWritingPipe(rxAddr[3]);
  stata=digitalRead(sa);
  radio.write(&stata,sizeof(stata));
  */
}

schon mal Danke und die Geduld mit mir

Mit dieser Art der blockierenden (und teilweise sinnfreien) Programmierung wird das nie richtig funktionieren.

  while(radio.available());

Das blockiert deinen Arduino bis zum Sankt-Nimmerleins-Tag falls wirklich ein Paket da wäre.
Also eine prima Gelegenheit den Master zu killen.

Ich würde eine andere Strategie benutzen, ohne Master/Slave Zuordung.

Alle Knoten lauschen auf Pakete auf ihre Adresse,
wird eine Taste betätigt,
stopListening,
Absetzen des Kommandos an den entsprechenden Knoten,
hat das geklappt, wieder zum Lauschen übergehen,
ansonsten das Senden wiederholen.

Also etwa so (ohne Wiederholung der Sends im Fehlerfall):

#include <Bounce2.h>
// https://github.com/thomasfredericks/Bounce2
#include <RF24.h>

const byte pinTaste1 = 2;
const byte pinTaste2 = 3;
const byte leda = 6;
const byte ledb = 5;

const byte rxAddr[][6] = {"null", "eins", "zwei", "drei"};

RF24 radio(7, 8);
Bounce Taste1;
Bounce Taste2;

byte packet;

void setup() {
  pinMode(leda, OUTPUT);
  pinMode(ledb, OUTPUT);
  Taste1.attach(pinTaste1, INPUT_PULLUP);
  Taste2.attach(pinTaste2, INPUT_PULLUP);
  Serial.begin(115200);
  radio.begin();
  radio.openReadingPipe(1, rxAddr[0]);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(&packet, sizeof(packet));
    digitalWrite(ledb, packet);
  }
  bool taste1Betaetigt = Taste1.update();
  bool taste2Betaetigt = Taste2.update();
  if (taste1Betaetigt || taste2Betaetigt) {
    radio.stopListening();
    if (taste1Betaetigt) {
      radio.openWritingPipe(rxAddr[1]);
      packet = Taste1.fell();
      radio.write(&packet, sizeof(packet));
    }
    if (taste2Betaetigt) {
      radio.openWritingPipe(rxAddr[2]);
      packet = Taste2.fell();
      radio.write(&packet, sizeof(packet));
    }
    radio.startListening();
  }
}

Für Tasten die gegen GND schalten, ohne externe PullUps oder PullDowns.

Gute Idee, danke schon mal Whandall
Probier ich.
Melde mich mit Ergebnissen

Ok, der Code leuchtet mir soweit ein. Habe nur eine Frage zu den ankommenden Packeten!

if (radio.available()) {
radio.read(&packet, sizeof(packet));
digitalWrite(ledb, packet);

Wie kann ich unterscheiden ob ledA oder ledB angesprochen werden soll?

Bei deinem Prinzip (Senden von einem Bool) überhaupt nicht.

Wenn du zwei oder mehr Leds steuern willst brauchst du mehr Informationen.

Denkbar wäre z.B.

#include <Bounce2.h>
// https://github.com/thomasfredericks/Bounce2
#include <RF24.h>

const byte pinTaste1 = 2;
const byte pinTaste2 = 3;
const byte leda = 6;
const byte ledb = 5;

const byte rxAddr[][6] = {"null", "eins", "zwei", "drei"};

RF24 radio(7, 8);
Bounce Taste1;
Bounce Taste2;

struct Packet {
  byte befehl;
  byte target;
} packet;
enum {
  ausschalten,
  einschalten,
};
enum {
  nimmLedA,
  nimmLedB,
};

void setup() {
  pinMode(leda, OUTPUT);
  pinMode(ledb, OUTPUT);
  Taste1.attach(pinTaste1, INPUT_PULLUP);
  Taste2.attach(pinTaste2, INPUT_PULLUP);
  Serial.begin(115200);
  radio.begin();
  radio.openReadingPipe(1, rxAddr[0]);
  radio.setPALevel(RF24_PA_MIN);
  radio.enableDynamicPayloads();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(&packet, sizeof(packet));
    if (packet.befehl == einschalten) {
      if (packet.target == nimmLedA) {
        digitalWrite(leda, HIGH);
      } else if (packet.target == nimmLedB) {
        digitalWrite(ledb, HIGH);
      }
    } else if (packet.befehl == ausschalten) {
      if (packet.target == nimmLedA) {
        digitalWrite(leda, LOW);
      } else if (packet.target == nimmLedB) {
        digitalWrite(ledb, LOW);
      }
    }
  }
  bool taste1Betaetigt = Taste1.update();
  bool taste2Betaetigt = Taste2.update();
  if (taste1Betaetigt || taste2Betaetigt) {
    radio.stopListening();
    if (taste1Betaetigt) {
      radio.openWritingPipe(rxAddr[1]);
      packet.target = nimmLedA;
      packet.befehl = Taste1.fell() ? einschalten : ausschalten;
      radio.write(&packet, sizeof(packet));
    }
    if (taste2Betaetigt) {
      radio.openWritingPipe(rxAddr[2]);
      packet.target = nimmLedB;
      packet.befehl = Taste2.fell() ? einschalten : ausschalten;
      radio.write(&packet, sizeof(packet));
    }
    radio.startListening();
  }
}

Hallo Whandall,

ich möchte mich für deine Hilfe ganz herzlich bedanken. Hab es mit Hilfe deines Vorschlages hinbekommen! Danke.
Es war nurnoch eine Kleinigkeit, dass ich einmal eine Radio.stopListening(); außerhalb der Klammern setzen musste.
Danke :sunglasses:

Johannes81:
Es war nurnoch eine Kleinigkeit, dass ich einmal eine Radio.stopListening(); außerhalb der Klammern setzen musste.

Zeig doch mal deine Verbesserung, irgendwie fehlt mir der Glaube an "musste". :wink: