NRF24l01 senden, empfangen + bestätigung

Hallo,

Ich schreibe gerade ein Code für RC-Sender und RC-Empfänger(Futterboot) was auch in einer Richtung sehr gut funktioniert.
In meinem Beispiel versende ich ein Potiwert für die Beschleunigung.

Nun würde ich gern empfangene Daten gleich zurück an den Sender/TFT-Display schicken.

Irgend wie hab ich mich festgefahren, könnte bitte jemand mein Code ansehen?

Danke im voraus.


Sender:

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

RF24 radio(8, 9);
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
int Acceleration = 92;  //Poti

void setup() {
  Serial.begin(9600);
  radio.begin ();
  radio.setAutoAck (1);
  radio.setRetries (15, 15);
  radio.enableAckPayload ();
  radio.setPayloadSize (32);
  radio.openWritingPipe (address [0]);
  radio.openReadingPipe(1, address[0]);
  radio.setChannel (0x60);
  radio.setPALevel (RF24_PA_MAX);
  radio.setDataRate (RF24_250KBPS);
  radio.powerUp ();
}

void loop() {
  Serial.print("Sende: "); Serial.println(Acceleration);
  radio.write(&Acceleration, int(Acceleration));
  delay(1000);
}

Empfänger:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(8, 9);      // NRF24l01+pa+lna Funk
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
int SendeMich = 2020;

void setup() {
  Serial.begin(9600);
  radio.begin ();
  radio.setAutoAck (1);
  radio.setRetries (15, 15);
  radio.enableAckPayload ();
  radio.setPayloadSize (32);
  radio.openReadingPipe(1, address[0]); //open ok, wo/wie wird die geschlossen?
  radio.setChannel (0x60);
  radio.setPALevel (RF24_PA_MAX);
  radio.setDataRate (RF24_250KBPS);
  radio.powerUp ();
  radio.startListening();
}

void loop() {
  byte pipeNo; // verstehe ich nicht ;(
  int gotByte;
  while ( radio.available(&pipeNo)) {
    radio.read( &gotByte, int(gotByte) );
    Serial.print("Empfange: "); Serial.println(gotByte);
  }
  delay(500);
}

sub7:
Irgend wie hab ich mich festgefahren, könnte bitte jemand mein Code ansehen?

Meine erste Maßnahme bei der Fehlersuche ist immer, den Code so kurz und lesbar zu machen, wie es möglich ist. Deinen Code habe ich zwar durchgescrollt, aber da ich auch horizontal scrollen müsste, um ihn ganz sehen zu können, habe ich es beim sehr kurzen Scrollen gelassen. Wenn ich genauer gucken soll, musst Du den Code schon deutlich straffen. Falls Dich interessiert, was ich vor der Fehlersuche noch an Maßnahmen ergreife, lies hier.

Beim Überarbeiten des Codes findest Du den Fehler möglicherweise selbst :slight_smile:

Gruß

Gregor

radio.read( &gotByte, int(gotByte) );
radio.read( &gotByte, sizeof(gotByte) );

int(gotByte) liefert hier einen quasi zufälligen Wert.
DAS willst du nicht.
Das geht ins Auge.

@gregorss

Code gestrafft, Link besucht.
die "Acceleration" sendet die "92", wird auch empfangen.
wie gesagt ich würde gern den Wert der "Acceleration" oder "SendeMich" Variable an den Sender schicken.

@combie

Danke, werde ich im Auge behalten.
Mit "byte pipeNo, gotByte;" erhalte ich Werte von max. 255 (Poti hängt am Mux).

PS: meine "Versuche" habe ich aus dem Code entfernt.

DANKE für eure Hilfsbereitschaft :wink:

sub7:
Code gestrafft, Link besucht.

Na, wenn das nicht deutlich lesbarer ist ...

Was mir auf die Schnelle auffällt: Einmal verwendest Du die Methode startListening(), im anderen Sketch aber nicht.

Weiteres könnte man durch einen Blick in die Headerdatei der Bibliothek(en) ermitteln. Welche Bibliothek(en) zum nRF verwendest Du? Hast Du einen Link auf eine Webseite? Ich habe keine Lust, alle möglichen nRF-Bibliotheken zu installieren und zu durchsuchen.

PS: meine "Versuche" habe ich aus dem Code entfernt.

Ändere Deinen Code beim nächsten Mal nicht nachträglich im Originalposting. So etwas gilt manchmal als äußerst unfein - ganz besonders, wenn es bereits Antworten gibt, die sich darauf beziehen.

Poste den überarbeiteten Code einfach noch einmal, damit Zusammenhänge usw. erhalten bleiben.

Gruß

Gregor

Schau dir das AckPayload Beispiel von Robin2 an, dein Versuch ist untauglich.

Das Datenblatt des NRF zu lesen könnte auch helfen.
Du benutzt widersprüchliche Konfigurationseinstellungen wie z.B.

  radio.enableAckPayload ();
  radio.setPayloadSize (32);

gregorss:
Was mir auf die Schnelle auffällt: Einmal verwendest Du die Methode startListening(), im anderen Sketch aber nicht.
Welche Bibliothek(en) zum nRF verwendest Du?
Ändere Deinen Code beim nächsten Mal nicht nachträglich im Originalposting.

  • mein Fehler
  • nRF24 Bibliothek GitHub
  • Du hast recht, wird nicht gemacht :wink:

Whandall:
Schau dir das AckPayload Beispiel von Robin2 an, dein Versuch ist untauglich.
Das Datenblatt des NRF zu lesen könnte auch helfen.

  • das Meisterwerk von "Robin2" hat mein Problem gelöst. LINK
  • auf jeden Fall, leider hab ich erst hinterher gemacht, sehr nützlich fand ich auch -> RF24 Class Reference

Beispiel von "Robin2" hab ich etwas modifiziert.

Sender:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   8
#define CSN_PIN  9

const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);

char dataToSend[10] = "Message 0";
char txNum = '0';
int ackData[3] = {0, 0, 0}; // um die beiden vom Rx kommenden Werte zu halten
bool newData = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // einmal pro Sekunde senden

void setup() {
    Serial.begin(9600);
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setChannel(75);               // 0-127
    radio.setPALevel(RF24_PA_MIN);      // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, RF24_PA_HIGH=0dBm
    radio.enableAckPayload();
    radio.setRetries(5,5);              // delay, count
    radio.openWritingPipe(slaveAddress);
}

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
////////Sende/////////
    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
    Serial.print("Sende: ");
    Serial.print(dataToSend);
    if (rslt) 
     {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }else{
            Serial.println("  Bestätigt, aber keine Daten!");
        }
        updateMessage();
        }else{
        Serial.println("  Tx fehlgeschlagen");
      }
    prevMillis = millis();
/////////////////

    }
////////PRINT LN/////////   
   if (newData == true) {
        Serial.print("  RX antwortet mit ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.print(ackData[1]);
        Serial.print(", ");
        Serial.println(ackData[2]);
        newData = false;
    }
/////////////////     
}

// So kannst Du sehen, dass neue Daten gesendet werden
void updateMessage() {
        
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

Empfänger:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   8
#define CSN_PIN  9

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10];         // Dies muss mit dataToSend im TX übereinstimmen
int  Acceleration = 12;        // Siehe "ackData"
int  Angle        = 95;
int  Depth        = 22;
int  ackData[3] = {Acceleration, Angle, Depth}; // Die Werte, die an den Master gesendet werden sollen
bool newData = false;

void setup() {
    Serial.begin(9600);
    radio.begin();
    radio.setDataRate( RF24_250KBPS ); // RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps 
    radio.setChannel(75);              // 0-127
    radio.setPALevel(RF24_PA_MIN);     // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, RF24_PA_HIGH=0dBm
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.enableAckPayload();
    radio.startListening();
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // vorbereite Daten
}

void loop() {
  
        if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
        newData = true;
    }

        if (newData == true) {
        Serial.print("Daten erhalten: ");
        Serial.print(dataReceived);
        Serial.print(" Antworte mit: ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.print(ackData[1]);
        Serial.print(", ");
        Serial.println(ackData[2]);
        newData = false;
    }

}

Danke an alle, und bleibt Gesund! :slight_smile: