Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Code for a Buzzlight Speed & Agility Training Game.
- * Version 3: Consists of one master and one slave.
- * A button on the master sends a signal to the slave. The slave responds by acknowledging the signal and illuminating a light.
- * When the master receives the acknowledgement, it illuminates a corresponding light.
- * When a button on the slave is pressed, the slave informs the master, which extinguishes it's corresponding light.
- *
- * This is the master.
- */
- #include <SPI.h> // Include the Serial Peripheral Interface library.
- #include <nRF24L01.h> // Include the library for the radio module.
- #include <RF24.h> // Include the radio driver.
- #include <Wire.h>
- #include <LiquidCrystal_I2C.h>
- LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
- // For nRF24L01 Pinout, see here: https://howtomechatronics.com/wp-content/uploads/2017/02/NRF24L01-Pinout-NRF24L01-PA-LNA--768x512.png
- // For wiring diagram (UNO and NANO) see here: https://howtomechatronics.com/wp-content/uploads/2017/02/NRF24L01-and-Arduino-Tutorial-Circuit-Schematic.png
- #define CE_PIN 7 // define which pin the CE is attached to (9 on UNO, 7 on NANO, 7 on RFNANO)
- #define CSN_PIN 8 // define which pin the CE is attached to (10 on UNO, 8 on NANO, 8 on RFNANO)
- #define RF_PWR_HIGH
- RF24 radio(CE_PIN, CSN_PIN); // Create an instance of the radio
- // Constants don't change
- const byte slaveAddressA[5] = {'R', 'x', 'A', 'B', 'A'}; // An array to store the address of Slave A
- const byte slaveAddressB[5] = {'R', 'x', 'A', 'B', 'A'}; // An array to store the address of Slave B (not yet configured)
- const int buttonPinA = 2; // the number of the pushbutton pin A
- const int ledPinA = 3; // the number of LED pin A
- const unsigned long sendInterval = 500; // ms between initiations of the radio routine
- const unsigned long debounceInterval = 500; //ms between possible button pushes
- const int serialUpdateInterval = 500; // ms between serial output updates.
- unsigned long prevSerial; // variable for storing the last millis at which the serial was updated
- unsigned long prevSendMillis; // variable for storing the last time at which the message was sent
- unsigned long prevButtonMillis; // variable for storing the last time the button was pressed (for debouncing)
- unsigned long currentMillis; // variable for storing the millis at the start of each loop iteration
- int ackData[2] = { -1, -1}; // to hold the two values coming from the slave
- bool buttonAActive = 0; // bool to store whether the button has been pressed
- int masterAMode = 0; // integer storing the mode that the master is in, relating to slave A.
- char dataToSend[10] = "9"; // array to store the data the radio will send.
- char txNum = '0'; // 'transmit number' - the single digit we will transmit.
- bool newData = false; // bool to store whether or not data has been received.
- //===============
- void setup() { // this code runs once, when the unit is switched on or rebooted.
- Serial.begin(9600); // open the serial port, ready for troubleshooting
- lcd.init(); // initialize the lcd
- radio.begin(); // start the radio module.
- radio.setDataRate( RF24_250KBPS ); // set the radio data rate
- radio.enableAckPayload(); // enable the radio feature that allows the slave to reply.
- radio.setRetries(5, 5); // delay, count // 5 gives a 1500 µsec delay which is needed for a 32 byte ackPayload
- pinMode(ledPinA, OUTPUT); // set the output pin to output mode.
- pinMode(LED_BUILTIN, OUTPUT);
- }
- //=============
- void loop() { // this code runs repeatedly
- currentMillis = millis(); // take note of the time this loop started
- checkButtonState(); // take note of the button states
- masterMode(); // establish which mode the unit is in, for each of the slaves (only one so far)
- prepareMessage(); // build the message that will be sent.
- sendMessageA(); // send the message to slave A
- // sendMessageB(); // send the message to slave B (Not yet operational)
- processAck(); // process the acknowledgement number from the slave
- lightLocalLED(); // light up the attached LED if a confirmation has been recieved from the slave.
- updateLCD();
- updateSerial(); // primarily for troubleshooting, update the serial monitor.
- }
- //================
- void checkButtonState() { // take note of the button states
- if ((currentMillis - prevButtonMillis) >= debounceInterval) { // if it's been at least 'debounceInterval' ms since the button was last pressed,
- if (digitalRead(buttonPinA) == HIGH) {
- buttonAActive = 1;
- prevButtonMillis = millis();
- }
- }
- }
- //================
- void masterMode() { // decides what the mastermode should be
- if (masterAMode == 0 && buttonAActive == 1) { // if the current mode is 0 and the button has been pressed
- masterAMode = 1; // mastermode is set to 'activated, waiting for confirmation' from the slave
- buttonAActive = 0;
- }
- if (masterAMode == 1 && ackData[0] == 1) { // if the slave has confirmed that it is activated
- masterAMode = 2; // mastermode is set to 'activated, confirmed' by the slave
- buttonAActive = 0;
- }
- if (masterAMode == 2 && ackData[0] == 2) { // if the button has been pressed and the slavemode is activated
- masterAMode = 3; // mastermode is deactivated, waiting for confirmation from the slave
- buttonAActive = 0;
- }
- if ((masterAMode == 1 || masterAMode == 2) && buttonAActive == 1) { // if the button has been pressed in mastermode 1 or 2
- masterAMode = 0; // mastermode is deactivated, waiting for confirmation from the slave
- buttonAActive = 0;
- }
- if (masterAMode == 3 && ackData[0] == 2) {
- masterAMode = 0;
- }
- }
- //================
- void prepareMessage() {
- if (masterAMode == 0 || masterAMode == 3) {
- txNum = '0';
- }
- if (masterAMode == 1 || masterAMode == 2) {
- txNum = '1';
- }
- dataToSend[0] = txNum;
- }
- //================
- void sendMessageA() {
- radio.openWritingPipe(slaveAddressA);
- if ((currentMillis - prevSendMillis) >= sendInterval) {
- bool rslt;
- rslt = radio.write( &dataToSend, sizeof(dataToSend) );
- // Always use sizeof() as it gives the size as the number of bytes.
- // For example if dataToSend was an int sizeof() would correctly return 2
- if (rslt) {
- if ( radio.isAckPayloadAvailable() ) {
- radio.read(&ackData, sizeof(ackData));
- newData = true;
- }
- }
- else {
- Serial.println(" Acknowledge but no data ");
- }
- prevSendMillis = currentMillis;
- }
- }
- //================
- void sendMessageB() {
- radio.openWritingPipe(slaveAddressB);
- if ((currentMillis - prevSendMillis) >= sendInterval) {
- bool rslt;
- rslt = radio.write( &dataToSend, sizeof(dataToSend) );
- // Always use sizeof() as it gives the size as the number of bytes.
- // For example if dataToSend was an int sizeof() would correctly return 2
- if (rslt) {
- if ( radio.isAckPayloadAvailable() ) {
- radio.read(&ackData, sizeof(ackData));
- newData = true;
- }
- }
- else {
- Serial.println(" Acknowledge but no data ");
- }
- prevSendMillis = currentMillis;
- }
- }
- //=================
- void processAck() {
- // slaveAMode = ackData[0];
- }
- //================
- void lightLocalLED() {
- if (masterAMode == 2) {
- digitalWrite(ledPinA, HIGH);
- digitalWrite(LED_BUILTIN, HIGH);
- // Serial.println("LIGHT HIGH");
- } else {
- digitalWrite(ledPinA, LOW);
- digitalWrite(LED_BUILTIN, LOW);
- // Serial.println("LIGHT LOW");
- }
- }
- //================
- void updateLCD()
- {
- // Print a message to the LCD.
- lcd.backlight();
- lcd.setCursor(2,0);
- lcd.print("Hello World!");
- //lcd.setCursor(0,1);
- //lcd.print("");
- }
- //================
- void updateSerial() {
- if ((currentMillis - prevSerial) >= serialUpdateInterval) {
- Serial.print(" masterAMode ");
- Serial.print(masterAMode);
- Serial.print(" buttonAActive ");
- Serial.print(buttonAActive);
- Serial.print(" txNum ");
- Serial.print(txNum);
- Serial.print(" Sent: ");
- Serial.print(dataToSend);
- if (newData == true) {
- Serial.print(" Ack recd: ");
- Serial.print(ackData[0]);
- Serial.print(", ");
- Serial.print(ackData[1]);
- newData = false;
- }
- prevSerial = currentMillis;
- Serial.println();
- }
- }
- //=================
Advertisement
Add Comment
Please, Sign In to add comment