RF24 Ack hinkt 3 "Nachrichten" hinterher

Hallo,

ich habe ein Problem mit der RF24 Library für den nrf24l01 chip.
Ich möchte mit einem Arduino Uno eine Fernbedienung bauen, die einem Raspberry einen Befehl sendet, woraufhin das RPi ein acknowlede Packet mit einem bestimmten Inhalt zurück senden soll, der auf der Fernbedienung danach weiter benutzt werden soll.

Soweit funktioniert auch alles, Ich kann mit dem Arduino und dem angeschlossenem nrf24l01 etwas senden und das RPi, auf dem ebenfalls die RF24 lib in Python läuft, empfängt die Nachrichten auch brav.

Ein Ack packet wird an sich vom RPi dann auch gesendet, wenn ich den Inhalt des Ack packets vom Arduino dann ausgeben lasse, ist es aber immer der Inhalt von vor genau drei gesendeten Befehlen.

Lasse ich also einfach einen Zähler bei 0 Anfangen und bei jeder empfangenen Nachricht am RPi wird der zähler um 1 erhöht und das RPi sendet den Wert des Zählers dann mit dem Ack packet mit zurück, bekomme ich immer einen um drei geringeren Wert. Sendet also zb das RPi bei drei aufeinander folgenden Befehlen 7, 8 und dann 9, sehe ich auf dem RPi dann 4, 5, 6. Wenn ich Zufallszahlen als Ack Packet sende, ist es das selbe. Das Arduino hinkt quasi immer drei Ack Packets zurück. Sendet das RPi so zb nacheinander 4, 3, 7, 5, 8, 6, 5 (Zufallszahlen zwischen 0 und 9) zurück, empfange ich am Arduino 24, 184, 0, 4, 3, 5. Die ersten Drei Zahlen die mir das Arduino anzeigt hat das RPi nie gesendet, danach folgen welche die gesendet wurden, aber eben drei zu spät.

Ich vermute, dass es am Buffer des nrf24l01 liegt, da dieser exakt drei Ack Nachrichten halten kann (wie ich zumindest mal gelesen habe). Ich habe aber auch schon mal versucht, ein paar Nachrichten zu senden und habe dann am Arduino den nrf24l01 Chip durch einen anderen ausgetauscht, während das Arduino lief, trotzdem trat der Ferhler weiterhin auf.

Dass es am RPi liegt, dann ich nicht ausschließen, denn wenn ich nach ein paar gesendeten Befehlen das Python Script stoppe und nach einer kurzen Pause wieder starte und dann wieder mit dem Arduino einen Befehl sende, sollte das Arduino den Stop des Script eigentlich gar nicht bemerkt haben dürfen, trotzdem wird beim ersten gesendetem Befehl, nach ich das Script gestoppt und wieder gestartet habe, beim Arduino angezeigt, dass das Rpi nicht erreichbar wäre. Das RPi hat die Nachricht aber sehr wohl empfangen.

Hat jemand eine Idee, woran das liegen könnte?

Hier ist der (zusammengestrichene) Code der auf dem Arduino läuft:

uint8_t rec[1] = {5};
const uint64_t pipe[1] = {0xF0F0F0F0E1LL};

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

RF24 radio(9, 10);

void setup() {
  Serial.begin(9600);
  radio.begin();
  delay(100);
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.enableDynamicPayloads();
  radio.stopListening();
  radio.openWritingPipe(pipe[0]);
  radio.setRetries(15, 15);
}

void loop() {
  delay(2000);
  radio.powerUp();
  const char text[] = "skr1m4s1";
  radio.write(text, sizeof(text));
  if (radio.isAckPayloadAvailable()) {
    radio.read(rec, sizeof(int));
    Serial.print("Folgender Ack Payload wurde empfangen: ");
    Serial.println(rec[1]);
  }
  else {
    Serial.println("Kein Ack Payload empfangen....");
  }
}

Auf dem RPi läuft dieses Python script:

while True:
    akpl[0] = randint(0,9)
    while not radio.available(0):
        time.sleep(1/100)

    receivedMessage = []
    radio.read(receivedMessage, radio.getDynamicPayloadSize())
    
    radio.writeAckPayload(1, (akpl), len(akpl))
    print akpl[0]

Du hast da etwas grundsätzlich falsch verstanden.

Der Payload wird als Acknowledge für ein Paket verschickt, muss also vor Empfang des Paketes geladen werden.

Das erste Paket bekommt bei dir kein Ack-Payload.

Das was du nach dem Empfang eines Paketes lädst, ist - so wie du es machst - das Ack-Payload des nächsten Pakets.

Du könntest 3 Ack-Payloads gleichzeitig laden, also maximal drei Pipes mit Ack-Payload versorgen.

Da eh schon ein Versatz von einem Paket da ist, machen mehrere für eine Pipe wenig Sinn.

... danke. einfach danke :):)

Ich bin nie auf die Idee gekommen, mal etwas vor die While True schleife im Python code zu packen.

   akpl[0] = randint(0,9)
    radio.writeAckPayload(1, akpl, len(akpl))
    
    while not radio.available(0):
        time.sleep(1/100)
...

das läuft jetzt. Jetzt bekomme ich den jeweils richtigen Payload.

Ok, und beim Arduino den rec[0] zu lesen statt den rec[1] hat in der tat auch was gebracht.

... Leider funktioniert zwar so das nicht, was ich mir vorgenommen hatte (nachdem das RPi was empfangen hatte, sollte es was damit machen und je nach dem etwas anderes mit dem Ack zurück schicken) Wenn man den Payload vom Ack schon vor dem empfangen definieren muss, geht das so natürlich nicht. Aber jetzt bin ich schon mal ein großes Stück weiter :) danke