Hello,
I have a serious problem with my nrf24l01 setup. I need up to eight wirless quizbuttons connected to one master. I followed Robin2's "Two way transmission, auto ack" examples and wrote my code according to them. All works well with the current code (see below). However when I connect more than 3 buttons, the systems doesn't work anymore. When I connect 4 or more buttons, the radio.available in the loop inside the buttons constantly returns false. I have no clue why this is. I've tried multiple things, like setting different setRetries, flush_tx, delaying the send rate of the loop which constantly sends to the buttons. But none of the things I tried worked.
The code:
MASTER:
#include <SPI.h>
#include <nRF24L01.h> //TMRh20
#include <RF24.h>
RF24 radio(7,8);
int n_active_buttons = 0;
const byte number_of_buttons = 8;
const byte BUTTONS[number_of_buttons][5] = {
{'R', 'x', '0', '0', '1'},
{'R', 'x', '0', '0', '2'},
{'R', 'x' ,'0', '0', '3'},
{'R', 'x', '0', '0', '4'},
{'R', 'x', '0', '0', '5'},
{'R', 'x', '0', '0', '6'},
{'R', 'x', '0', '0', '7'},
{'R', 'x', '0', '0', '8'}
};
bool result = false;
unsigned long tempReceiveTime = 0;
unsigned long startTime = 0;
bool PRESS = false;
int test = 0;
struct initDataStruct{
char ID;
int value;
bool wasPressed;
}INIT_ACK_DATA;
struct DataStruct{
char wasButtonPressed;
}ACK_DATA;
struct transmitData{
char askVar = 'o';
}TX_DATA;
class quizButton
{
public:
bool lock = false;
unsigned long startTime;
unsigned long receivedTime;
int score = 0;
byte pipeID[5] = {'R','x','0','0','9'};
};
quizButton buttons[number_of_buttons];
void setup()
{
Serial.begin(115200);
radio.begin();
radio.setPALevel(RF24_PA_HIGH);
radio.setDataRate(RF24_1MBPS);
radio.setChannel(0x66);
radio.setRetries(3,5);
radio.enableAckPayload();
radio.stopListening();
Serial.println("GettingStarted TRANSMITTER");
identifyButtons();
}
void loop()
{
Serial.print("> Wachten op start...");
Serial.read();
while(!Serial.available());
Serial.println("Starten...");
Serial.read();
startTime = micros();
int x = 0;
bool OK = false;
while(true)
{
for(int i=0; i<n_active_buttons; i++)
{
radio.openWritingPipe(buttons[i].pipeID);
radio.stopListening();
OK = radio.write(&TX_DATA, sizeof(TX_DATA));
buttons[i].startTime = micros();
if(OK && radio.isAckPayloadAvailable())
{
radio.read(&test, sizeof(test));
Serial.print(char(buttons[i].pipeID[4]));
Serial.print(": ");
Serial.println(test);
tempReceiveTime = micros();
if(ACK_DATA.wasButtonPressed && !buttons[i].lock)
{
buttons[i].lock = true;
buttons[i].receivedTime = tempReceiveTime;
x++;
}
}
}
if(x == n_active_buttons)
{
break;
}
}
Serial.print("\n");
Serial.println("DONE");
Serial.print("Universal starttime: ");
Serial.println(startTime);
for(int i=0; i<n_active_buttons; i++)
{
Serial.print("Button " + String(i+1) + ": ");
Serial.print("tStart: " + String(buttons[i].startTime) + ", ");
Serial.println("tReceive: " + String(buttons[i].receivedTime) + "\n");
}
}
void identifyButtons()
{
char SEND_ID = '1';
char DONE = 'A';
bool OK = false;
bool thisButtonIsConfigured[8] = {false, false, false, false, false, false, false, false};
char youCanStart = 'Y';
Serial.println("> Voer karakter in om te starten...");
while(true)
{
for(int i=0; i<number_of_buttons; i++)
{
if(!thisButtonIsConfigured[i])
{
radio.openWritingPipe(BUTTONS[i]);
radio.stopListening();
OK = radio.write(&SEND_ID, sizeof(SEND_ID));
if(OK && radio.isAckPayloadAvailable())
{
radio.read(&INIT_ACK_DATA, sizeof(INIT_ACK_DATA));
thisButtonIsConfigured[i] = true;
buttons[i].pipeID[4] = INIT_ACK_DATA.ID;
SEND_ID++;
radio.openWritingPipe(BUTTONS[i]);
radio.stopListening();
radio.write(&DONE, sizeof(DONE));
}
}else{
radio.openWritingPipe(BUTTONS[i]);
radio.stopListening();
radio.write(&DONE, sizeof(DONE));
}
}
Serial.read();
if(Serial.available() > 0)
{
Serial.read();
n_active_buttons = int(SEND_ID - '0');
n_active_buttons--;
Serial.print(n_active_buttons);
Serial.println(" knoppen zijn geconfigureerd");
for(int x=0; x<16; x++)
{
for(int i=0; i<n_active_buttons; i++)
{
radio.openWritingPipe(buttons[i].pipeID);
radio.stopListening();
radio.write(&youCanStart, sizeof(youCanStart));
}
}
break;
}
}
}
The code below is uploaded to each button with each a different value for {'R','x','0','0','1'};
#include <SPI.h>
#include <nRF24L01.h> //TMRh20
#include <RF24.h>
#include <TimerOne.h>
#include <printf.h>
#define BUTTON 2
#define LED 4
RF24 radio(7,8);
byte MASTER[5] = {'R','x','0','0','4'};
int ackData = 0;
bool buttonWasPressed = false;
char myID;
bool PRESS = false;
int YES = 1111;
int NO = 9999;
struct dataStruct{
char wasButtonPressed;
}ACK_DATA;
struct receiveData{
char askVar;
}RX_DATA;
void setup()
{
Serial.begin(115200);
printf_begin();
pinMode(BUTTON, INPUT_PULLUP);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
radio.begin();
radio.setPALevel(RF24_PA_HIGH);
radio.setDataRate(RF24_1MBPS);
radio.setChannel(0x66);
radio.setRetries(3,5);
radio.openReadingPipe(1, MASTER);
radio.enableAckPayload();
radio.startListening();
Serial.println("GettingStarted RECEIVER");
configureID();
}
void loop()
{
digitalWrite(LED, PRESS);
if(!PRESS)
{
PRESS = !digitalRead(BUTTON);
}
if(radio.available())
{
radio.read( &RX_DATA, sizeof(RX_DATA) );
if(PRESS)
{
radio.writeAckPayload(1, &YES, sizeof(YES));
}else{
radio.writeAckPayload(1, &NO, sizeof(NO));
}
}
}
void configureID()
{
char obtainedID = ' ';
while(true)
{
if(radio.available())
{
radio.read( &obtainedID, sizeof(obtainedID) );
if(obtainedID != 'A')
{
myID = obtainedID;
radio.writeAckPayload(1, &MASTER[4], sizeof(MASTER[4]));
}else if(obtainedID == 'A')
{
break;
}
}
}
flashID();
}
void flashID()
{
int ID = myID - '0';
char iCanStart = 'N';
int i = 0;
bool ledState = true;
unsigned long curMil = 0;
unsigned long prevMil = 0;
unsigned long interval = 0;
unsigned long curMilF = 0;
unsigned long prevMilF = 0;
unsigned long intervalF = 200;
interval = (ID * intervalF * 2) + 1000;
Serial.print("interval: ");
Serial.println(interval);
goto STARTHERE;
while(iCanStart != 'Y')
{
curMil = millis();
if(curMil - prevMil > interval)
{
prevMil = curMil;
while(i < ID*2)
{
/*--->*/STARTHERE:
curMilF = millis();
if(curMilF - prevMilF > intervalF)
{
prevMilF = curMilF;
digitalWrite(LED, ledState);
ledState = !ledState;
i++;
}
if(radio.available())
{
radio.read(&iCanStart, sizeof(iCanStart));
}
}
i = 0;
}
if(radio.available())
{
radio.read(&iCanStart, sizeof(iCanStart));
}
}
digitalWrite(LED,LOW);
}
All the setup like the configureID() functions works. I can setup 8 buttons if I want, but the code in the void loop() of program doesn't work above 3 buttons.
Also, the nrf24l01's are connected to an arduino nano. I'm tapping the 3.3V off of the nano. The circuit is mounted on a real pcb. (not perfboard). I have a 100uF capacitor across the 3.3V rail. I'm powering everything from 4 AA batteries.
Thanks in advance.