Hi all,
I am (again) stuck with my nRF24L01. I am trying to build a sort of feedback system, where some people have senders with buttons to vote for and they all send their vote after a certain time to a receiving node. I wanted to use the ack Feature of the nRF24L01 with the RF24 library. However, I can not get the ack answer to work. My master sends the time and a start signal to all nodes on one address. It then changes addresses and is supposed to ask every individual node for their vote, for example after 10 seconds. Thats where the code fails: the sender receives the request to send the vote, but the ack Payload (the vote) is not being successfully transmitted. I will post the full code for understanding, however the important parts are in both sketches at the bottom.
This is the sender(master/receiver):
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <stdio.h>
#define CE_PIN 9
#define CSN_PIN 10
RF24 radio(CE_PIN, CSN_PIN);
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 2;
char startAbfrageDauer[2] = "10"; // Zeit in Sekunden
char startAbfrageSendung[2] = "st";
char endeAbfrageSendung[2] = "en";
char frageAntwort[2] = "na";
int abstimmung = 5;
byte broadcastAdresse[5] = {'0','0','0','0','0'};
byte senderAdresse[5] = {'0','1','0','0','0'};
bool abfrageBeginnen = false;
void setup() {
Serial.begin(9600);
radio.begin();
radio.setDataRate( RF24_2MBPS );
radio.enableAckPayload();
radio.setRetries(3,5);
}
void loop() {
abfrageZyklus();
Serial.println("abfrageZyklus fertig");
}
void abfrageZyklus() {
startAbfrage();
warteZeit();
frageNachAntwort();
}
void startAbfrage() {
radio.openWritingPipe(broadcastAdresse);
Serial.println("startAbfrage");
radio.write(&startAbfrageSendung, sizeof(startAbfrageSendung));
delay(20);
radio.write(&startAbfrageDauer, sizeof(startAbfrageDauer));
radio.stopListening();
//delay(20);
}
void warteZeit() {
radio.powerDown();
//avr_enter_sleep_mode();
unsigned int warteZeit;
sscanf(startAbfrageDauer, "%d", &warteZeit);
delay(warteZeit*1000+3000);
Serial.println("ende Wartezeit");
radio.powerUp();
}
void frageNachAntwort () {
Serial.println("start frageNachAntwort");
radio.openWritingPipe(senderAdresse);
Serial.println("öffne neu");
bool rslt;
rslt = radio.write(&frageAntwort, sizeof(frageAntwort));
Serial.println("radio write");
if (rslt) {
if (!radio.available()){
Serial.println(F("Blank Payload Received."));
}
else {
while(radio.available() ){
radio.read( &abstimmung, 1 );
Serial.println(abstimmung);
}
}
Serial.println("ack aber keine Daten");
}
Serial.println("failed");
}
This is the voter:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Bounce2.h>
#define CE_PIN 9
#define CSN_PIN 10
#define NUM_BUTTONS 4
const uint8_t BUTTON_PINS[4] = {2, 3, 4, 5};
Bounce * buttons = new Bounce[NUM_BUTTONS];
byte masterBroadcastAdresse[5] = {'0','0','0','0','0'};
byte dieserSenderAdresse[5] = {'0','1','0','0','0'};
RF24 radio(CE_PIN, CSN_PIN);
char dataReceived[2];
char dataToSend;
bool starteDenTaster;
bool starteZeit = false;
bool tasterFertig = false;
unsigned int warteZeit;
unsigned long currentMillis;
unsigned long empfangenMillis = 0;
unsigned long buttonMillis = 0;
void setup() {
Serial2.begin(9600);
for (int i = 0; i < NUM_BUTTONS; i++) {
buttons[i].attach( BUTTON_PINS[i] , INPUT_PULLUP ); //setup the bounce instance for the current button
buttons[i].interval(1); // interval in ms
}
radio.begin();
radio.setDataRate( RF24_2MBPS );
radio.enableAckPayload();
//radio.setAutoAck(1);
radio.setRetries(3,5);
}
void loop() {
wartenAufTimer();
if (starteZeit == true && starteDenTaster == true) {
radio.stopListening();
radio.closeReadingPipe(1);
empfangenMillis = millis();
while (millis() - empfangenMillis <= warteZeit*1000) {
Taster();
tasterFertig = true;
}
radio.openReadingPipe(1, dieserSenderAdresse);
radio.startListening();
while (tasterFertig == true) {
antwortenAusgeben();
}
}
}
void wartenAufTimer() {
radio.openReadingPipe(1, masterBroadcastAdresse);
radio.startListening();
if (radio.available()) {
radio.read(&dataReceived, sizeof(dataReceived));
Serial2.println(dataReceived);
if (dataReceived[0] == 'e' && dataReceived[1] == 'n') {
Serial2.println("Zeit abgelaufen: en");
starteDenTaster = false;
}
if (dataReceived[0] == 's' && dataReceived[1] == 't') {
Serial2.println("st ist da");
starteDenTaster = true;
}
else {
Serial2.println("Zahl");
Serial2.println(starteDenTaster);
sscanf(dataReceived, "%d", &warteZeit);
warteZeit = warteZeit;
if (starteDenTaster == true) {
starteZeit = true;
}
}
}
}
void Taster() {
Serial2.println("starteTaster");
for (int i = 0; i < NUM_BUTTONS; i++) {
Serial2.println("frage ab");
buttons[i].update();
if ( buttons[i].fell() ) {
Serial2.println(F("Knopf gedrückt"));
switch (i) {
case 0:
dataToSend = '1';
break;
case 1:
dataToSend = '2';
break;
case 2:
dataToSend = '3';
break;
case 3:
dataToSend = '4';
break;
buttonMillis = millis();
Serial2.println(dataToSend);
}
}
}
}
void antwortenAusgeben() {
Serial2.println(dataToSend);
Serial2.println("startListening");
if (radio.available()){
Serial2.println("is daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
radio.read(&dataReceived, sizeof(dataReceived));
if (dataReceived[0] == 'n' && dataReceived[1] == 'a') {
Serial2.println("habs bekommmmmmmmmmmmmxxxxxxxxxxxxxxxxxxxxxxxxxxxxen");
char data = '1';
Serial2.println(dataToSend);
radio.writeAckPayload(data, &dataToSend, 1);
tasterFertig = false;
}
}
}
I am happy about any advice!