Nrf24l1 multi Node

Hallo
Ich habe ein Problem mit Nrf24l01.Ich habe 2 Uno als TX und einen Uno als RX.Die Kopplung der Geräte ist mir gelungen da ein bisschen Kenntnisse durch anderes Projekt vorhanden sind. Ich bekomme von beiden Sendern jeweils ein float und kann mir dies auch seriell anschauen.Mein Problem bei der Sache schalte ich einen Sender aus werden die Daten des anderen in die Variable des ausgeschalteten geschrieben. Meine Frage wo muss ich ansetzen das bei Ausfall eines Senders nicht die Daten des anderen übernommen werden. Mit diesem einfachen Sketch den ich für den RX benutze wird das meiner Meinung nichts.Habe aber auch keine Idee nach 2 Abenden mehr wo der Hebel anzusetzen ist. Vielleicht kann mir jemand auf die
Sprünge Helfen.

mfG
Thorsten4171

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

float temp1;
float temp2;

RF24 radio(7, 8);
byte pipes[][6] = {"0", "1", "2"};
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, pipes[1]);
  radio.openReadingPipe(2, pipes[2]);
  radio.startListening();
}

void loop()
{

  if (radio.available() )
  {
    radio.read(&temp1, sizeof(temp1));
    delay(50);
    radio.read(&temp2, sizeof(temp2));

  }
  Serial.println("Temp1");
  Serial.println(temp1);
  Serial.println("..........");
  Serial.println("Temp2");
  Serial.println(temp2);
  Serial.println("..........");

}

Wenn du mit 2 Sendern arbeitest, die unabhängig voneinander senden, dann wirst du immer Probleme bekommen.
Du musst diese Sender synchronisieren bzw. zum Senden auffordern.
Dazu muss jeder Sender eine ID vorweg senden, an der der Empfänger erkennt welcher Sender das Signal gesendet hat.
Danach kannst du die Auswertung vornehmen.

Du benutzt ungünstige Adressen (4 der 5 Bytes sind 0).
Dein Programm liest zwei Pakete, wenn eines empfangen wurde.
Delays in einem Programm das kommunizieren soll, sind kontraproduktiv.

Versuch doch mal diesen ungetesteten Kode:

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

float temp1;
float temp2;

RF24 radio(7, 8);
byte pipes[][6] = {"0", "1", "2"};
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, pipes[1]);
  radio.openReadingPipe(2, pipes[2]);
  radio.startListening();
}

void loop()
{
byte fromPipe = 0;
  if (radio.available(&fromPipe)) {
    if (fromPipe==1) {
      radio.read(&temp1, sizeof(temp1));
      Serial.print("Temp1 ");
      Serial.println(temp1);
    } else if (fromPipe==2) {
      radio.read(&temp2, sizeof(temp2));
      Serial.print("Temp2 ");
      Serial.println(temp2);
    }
  }
}

Danke für eure Tipps.
Whandall dein Code hat zum Erfolg geführt. Ich hatte auch schon in dieser Richtung probiert aber Mangels an Erfahrung nicht richtig if (radio.available(pipes[1])) konnte ja auch nicht funktionieren wenn ich mir deinen Code anschaue. Wie so oft sitzt das Problem 50 cm vor dem Monitor.

mfG
Thorsten4171

PS
Das delay wird noch durch millis ersetzt. Wenn ich es ohne Pause laufen lasse verschluckt sich manchmal der Empfänger.

Mein Kode hat kein delay, 'verschluckt' sich der auch?
Was auch immer 'verschlucken' bedeutet...

Da du nur ein Programm (Empfänger) der drei beteiligten veröffentlicht hast,
kann man zu der Kommunikation wenig sagen.

Hallo Whandall
Mit verschlucken meine ich folgendes: gelesen und ausgegeben wird temp1 temp2 temp1 temp2.... usw
ohne delay aber temp1 temp2 temp1 temp1 temp2 usw
Wobei kein festes Muster zu erkennen ist wann temp2 ausgelassen wird.

Wollte ja noch den Code mitschicken.

Sender1

//  COM11 //

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

byte a=2;
float temp2=22;

RF24 radio(7, 8);
/*const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };*/
byte pipes[][6] = {"0", "1","2"};
void setup() {
Serial.begin(9600);

radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[2]);

}

void loop()
{

if (a>1){
radio.write(&temp2, sizeof(temp2));
/*delay(10);*/
}
}

Sender2

//  Com10 //

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

byte a;
float temp1=55;
byte tasterPin= 4;
RF24 radio(7, 8);
/*const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };*/
byte pipes[][6] = {"0", "1","2"};
void setup() {
pinMode(tasterPin,INPUT_PULLUP);
Serial.begin(9600);
radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[1]);

}

void loop()
{
  
if (digitalRead(tasterPin)==0){
  a=0;}
  else{
    a=2;}

if(a>1){
radio.write(&temp1, sizeof(temp1));
/*delay(10);*/
}
}

Empfänger

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

float temp1;
float temp2;

RF24 radio(7, 8);
byte pipes[][6] = {"0", "1", "2"};
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, pipes[1]);
  radio.openReadingPipe(2, pipes[2]);
  radio.startListening();
}

void loop()
{
  byte fromPipe = 0;
  if (radio.available(&fromPipe)) {
    if (fromPipe == 1) {
      radio.read(&temp1, sizeof(temp1));
      Serial.print("Temp1 ");
      Serial.println(temp1);
     /* delay(50);*/
    } else if (fromPipe == 2) {
      radio.read(&temp2, sizeof(temp2));
      Serial.print("Temp2 ");
      Serial.println(temp2);
    }
  }
}

Sender 1 blockiert die Kommunikation immer, da er ungebremst andauernd sendet.
(Das ist auch viel zu oft um es mit 9600 Baud auszudrucken.)

Das macht der Sender 2 auch, aber nur wenn die Taste gedrückt ist,
das erzeugt dann zusätzlich jede Menge Kollisionen.

Da deine Pakete nur einen Float enthalten, kann der Empfänger nicht feststellen ob ein Paket fehlt.

Warum willst du Temperaturen mehr als tausendmal in der Sekunde übertragen und ausdrucken?

Die übertragung soll nicht so oft geschehen , der Hintergrund dieser 3 Codestücke ist das ich erst eine sauber Verbindung ohne Fehler hienbekomme möchte und erst dann mit den Dingen weitermache wozu die sache gedacht ist zB Temp übertragen Licht und Wasserpumpe an aus schalten etc.Der Taster im Sketch simuliert nur einen Stromausfall damit ich in der Versuchsphase nicht immer den USB Stecker rausfummeln muß.
Das mit dem Licht und der Pumpe läuft schon .Jezt soll die Sache erweitert werden um ein angedachtes Gewächshaus zu steuer und zu überwachen.

Thorsten4171:
Die übertragung soll nicht so oft geschehen

Warum hast du das dann so programmiert?

Thorsten4171:
der Hintergrund dieser 3 Codestücke ist das ich erst eine sauber Verbindung ohne Fehler hienbekomme möchte

Das ist durch das ungebremste Senden ausgeschlossen.

Danke für den Hinweis. werde mal versuchen das zu ändern und berichten.

Hallo Whandall

Könnte es so besser auf Sendeseite aussehen? Es funktioniert zumindest. Ich bilde mir ein so habe ich den Sender ausgebremst.

//  COM11 //

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

byte a=2;
float temp2=22;
unsigned long vorherigeMillis = 0;
const long    interval = 5000;

RF24 radio(7, 8);
/*const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };*/
byte pipes[][6] = {"0", "1","2"};
void setup() {
Serial.begin(115200);

radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[2]);

}

void loop()
{
unsigned long aktuelleMillis = millis();
if (aktuelleMillis - vorherigeMillis >= interval) {
vorherigeMillis = aktuelleMillis;
Serial.println("jezt sende ich................................");
radio.write(&temp2, sizeof(temp2));

}
Serial.println("tue was anderes");


}

Mit Strg+t in der IDE sieht es auch noch besser lesbar aus:

void loop()
{
  unsigned long aktuelleMillis = millis();
  if (aktuelleMillis - vorherigeMillis >= interval) 
  {
    vorherigeMillis = aktuelleMillis;
    Serial.println("jezt sende ich................................");
    radio.write(&temp2, sizeof(temp2));
  }
  Serial.println("tue was anderes");
}

Danke ich interpretiere das als "bin auf dem richtigen Weg"

Das Senden hast du jetzt begrenzt, dennoch blockiert dein Sendeprogramm an

  Serial.println("tue was anderes");

denn jetzt ist dieser Aufruf völlig unmoderiert.

Verlange von einem Rechner nicht mehr als er leisten kann, sonst gerät dein ganzes Timing durcheinander.

In diesem Teil dachte ich andere Aufgabe wie Temp lesen Bewässerung ein aus schalten etc. zu erledigen.
Solche Anweisungen schreibe ich mir immer wieder rein um zu begreifen wo ich im Programm bin und was es macht. Hoffe das ist nicht falsch und kontraproduktiv

Thorsten4171:
Hoffe das ist nicht falsch und kontraproduktiv

Diese Hoffnung täuscht.

Ein Kommentar an der Stelle erfüllt den gleichen Zweck, behindert aber das restliche Programm nicht.

Thorsten4171:
Danke ich interpretiere das als "bin auf dem richtigen Weg"

Ja, der Interpretation stimme ich zu.

Und als Trost: Die Beschreibung von radio.available() steht an der einen, die von radio.available(&fromPipe) deutlich weiter hinten, da bin ich auch nicht drauf gekommen. Da ist es gut, wenn man jemanden findet, der diese Hürde schon überwunden hat. @Whandall: Das war jetzt ein Lob :slight_smile:

Aber wie mache ich einen Kommentar sichtbar wenn ich z.b in einer Schleife festhänge?Oder verstehe ich das jezt falsch?

Wenn etwas nicht funktioniert sind Debugausgaben natürlich absolut in Ordnung,
einen richtigen Debugger hat man ja nicht zur Verfügung.

Für Statusanzeigen könntest du LEDs an freie Pins hängen,
Pin-I/O ist höllenschnell gegenüber serieller Ausgabe.

Noch etwas das mir auffiel:

radio.write(&temp2, sizeof(temp2));

Du wertest den Rückgabewert dieser Funktion nicht aus, das ist zumindestens in der Testphase
nicht besonders clever.

Wenn die Funktion erfolgreich war, hat der Empänger die Nachricht erhalten und bestätigt,
ansonsten könnte die Übertragung oder die Bestätigung gestört sein.
Im Datenblatt findest du alle möglichen Scenarien beschrieben.