Hi everyone!
First of all, I would like to apologize in advance : english is not my first language therefore please be kind with me if my syntax is not perfect.
My project consists in connected targets, 11 in total (1 start target, 10 "real" targets), designed for NERF play at home.
3 game modes, selected prior to hitting the start target that launches a timer :
- random (activates a random target, needs 10 targets hit to end),
- speed (all 10 targets are activated, game ends when all have been hit)
- infinite (randomly activated targets, game ends when the start target is hit again)
Hardware is as follows :
Start target (master) :
- Arduino Nano,
- NRF24 module for communication with the 10 other targets (slaves)
- SW420 vibration module
- JDY-31 bluetooth module for communication with the main system (a rasp Pi running Python code)
"Real" targets (slaves) :
- Arduino Nano,
- NRF24 module for communication with the master
- SW420 vibration module
What I want to be able to do is as follows :
- Master (start target) receives a command from the python code with Serial (trouhgh the JDY-31)
- Depending on the command, a game mode is selected
- When the master is hit, it communicates with the other targets (using the NRF24 modules) to activate them and wait for their answer
- When an answer is received, the master sends it to the raspberry that either says "i need more" or "that's it, the end".
My python code is almost ready but at this stage I need to progress with the Arduino side of things, to test if everything is working properly one step at a time.
For the Arduino code, I'm an absolute beginner. I started with the blink example, added the condition "if serial input is this, turn on the LED. Then, if the shock sensor is triggered, turn the LED off".
I am starting to grasp how it works but I am currently struggling with the NRF24 communication thing.
The (great) examples provided by Robin2 in his Simple nRF24L01+ 2.4GHz transceiver demo work on my modules. SimpleTx, two way communication and other sketches are working with my modules.
However, they are still a bit too complicated for my understanding and even though I used his work to do some trial and error coding, and tried to deconstruct the code to understand it better, I'm stuck.
Here is where I'm at (as I said, I am a beginner and trying to go step by step) :
- The master can receive a command from Serial, turn on the LED, and when the shock sensor is triggered it communicates with a slave (just one for now).
- The slave is "activated", turns on the LED, waits for the shock sensor to be triggered to turn the LED off and to send a reply to the master.
Problem is : my master does not receive any reply and I don't know if it has been sent by the NRF24 module...
I have tried using radio.startListening() and radio.stopListening() but without good and consistent results.
Any help or guidance would be much appreciated. I am not asking you to write my code for me (i'm a stubborn guy and want to experiment myself, to get better at it, instead of just copy-pasting something).
Here is the current code for my master:
// Master
//RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte masterAddress[5] = {'T','X','a','a','a'};
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
int serialData;
int vit = 12;
int dataRecue;
int shocksensor = 4; //pin de connection du capteur de choc
int LED = 5 ; // pin de la led
//===============
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
pinMode(shocksensor, INPUT);
radio.begin();
radio.setDataRate( RF24_1MBPS );
radio.openWritingPipe(slaveAddress);
radio.openReadingPipe(1, masterAddress);
}
//=============
void loop() {
if(Serial.available() > 0){
serialData = Serial.read();
if (serialData == 'Z'){ // si python lance le mode vitesse
digitalWrite(LED, HIGH);
while (1){
if (digitalRead(shocksensor)){
digitalWrite(LED, LOW);
Serial.println("u"); //démarre le timer côté Python
radio.write( &vit, sizeof(vit) );
radio.startListening();
if ( radio.available() ) {
radio.read(&dataRecue, sizeof(dataRecue)); // réception de la réponse
Serial.println(dataRecue); // contrôle de la réponse
radio.stopListening();
}
break;
}
}
} // fin du mode vitesse dans la boucle
} // fin ifserial available
} // fin de la boucle
//================
And here is the code for my slave :
// Slave 1
//RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte masterAddress[5] = {'T','X','a','a','a'};
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
int dataRecue;
int vit = 21;// valeur à renvoyer mode vitesse
int shocksensor = 4; // pin de connection du capteur de choc
int LED = 5; // pin de la led
//==============
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
pinMode(shocksensor, INPUT);
radio.begin();
radio.setDataRate( RF24_1MBPS );
radio.openWritingPipe(masterAddress);
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
}
//==========
void loop() {
recupdata();
modevitesse();
} // fin boucle principale
//============
void recupdata () { // récupération des infos du master
if ( radio.available() ) {
radio.read( &dataRecue, sizeof(dataRecue) );
Serial.println(dataRecue);
radio.stopListening();
}
}
//================
void modevitesse(){
if (dataRecue == 12) {
digitalWrite (LED, HIGH);
while (1){
if (digitalRead(shocksensor)){
digitalWrite (LED, LOW);
radio.write (&vit, sizeof(vit));
Serial.println(vit); //juste pour le contôle
radio.startListening();
break;
}
}
}
}
My comments are in french but it should be pretty obvious what they mean in english.
Side note : I have carefully read topics where Robin2 explains the concept of "pipes" and "addresses" and (please correct me if I'm wrong), I should be fine with just 1 master address and 1 slave address.
Slaves can listen all the time, waiting for their command, and when they need to reply, they will never do it all at once (they need to be hit first), so no collisions.
Thing is, when the master issues a command to a slave, it needs to wait for an answer that might take some time to come...
Thank you all for your help, I will be happy to share my progress with you here!