prismaardvark

MASTER

Dec 29th, 2021
1,197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.75 KB | None | 0 0
  1. /* Code for a Buzzlight Speed & Agility Training Game.
  2.  *  Version 3: Consists of one master and one slave.
  3.  *  A button on the master sends a signal to the slave. The slave responds by acknowledging the signal and illuminating a light.
  4.  *  When the master receives the acknowledgement, it illuminates a corresponding light.
  5.  *  When a button on the slave is pressed, the slave informs the master, which extinguishes it's corresponding light.
  6.  *  
  7.  *  This is the master.
  8.  */
  9.  
  10. #include <SPI.h>        // Include the Serial Peripheral Interface library.
  11. #include <nRF24L01.h>   // Include the library for the radio module.
  12. #include <RF24.h>       // Include the radio driver.
  13. #include <Wire.h>
  14. #include <LiquidCrystal_I2C.h>
  15.  
  16. LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  17.  
  18. // For nRF24L01 Pinout, see here: https://howtomechatronics.com/wp-content/uploads/2017/02/NRF24L01-Pinout-NRF24L01-PA-LNA--768x512.png
  19. // For wiring diagram (UNO and NANO) see here: https://howtomechatronics.com/wp-content/uploads/2017/02/NRF24L01-and-Arduino-Tutorial-Circuit-Schematic.png
  20. #define CE_PIN   7      // define which pin the CE is attached to (9 on UNO, 7 on NANO, 7 on RFNANO)
  21. #define CSN_PIN 8      // define which pin the CE is attached to (10 on UNO, 8 on NANO, 8 on RFNANO)
  22. #define RF_PWR_HIGH
  23.  
  24. RF24 radio(CE_PIN, CSN_PIN); // Create an instance of the radio
  25.  
  26. // Constants don't change
  27. const byte slaveAddressA[5] = {'R', 'x', 'A', 'B', 'A'};  // An array to store the address of Slave A
  28. const byte slaveAddressB[5] = {'R', 'x', 'A', 'B', 'A'};  // An array to store the address of Slave B (not yet configured)
  29. const int buttonPinA = 2;                     // the number of the pushbutton pin A
  30. const int ledPinA = 3;                        // the number of LED pin A
  31.  
  32. const unsigned long sendInterval = 500;       // ms between initiations of the radio routine
  33. const unsigned long debounceInterval = 500;   //ms between possible button pushes
  34. const int serialUpdateInterval = 500;         // ms between serial output updates.
  35.  
  36.  
  37. unsigned long prevSerial;          // variable for storing the last millis at which the serial was updated
  38. unsigned long prevSendMillis;     // variable for storing the last time at which the message was sent
  39. unsigned long prevButtonMillis;   // variable for storing the last time the button was pressed (for debouncing)
  40. unsigned long currentMillis;      // variable for storing the millis at the start of each loop iteration
  41. int ackData[2] = { -1, -1};       // to hold the two values coming from the slave
  42. bool buttonAActive = 0;           // bool to store whether the button has been pressed
  43. int masterAMode = 0;              // integer storing the mode that the master is in, relating to slave A.
  44. char dataToSend[10] = "9";        // array to store the data the radio will send.
  45. char txNum = '0';                 // 'transmit number' - the single digit we will transmit.
  46. bool newData = false;             // bool to store whether or not data has been received.
  47.  
  48. //===============
  49.  
  50. void setup() {            // this code runs once, when the unit is switched on or rebooted.              
  51.   Serial.begin(9600);     // open the serial port, ready for troubleshooting
  52.   lcd.init();                      // initialize the lcd
  53.   radio.begin();          // start the radio module.
  54.   radio.setDataRate( RF24_250KBPS );      // set the radio data rate
  55.   radio.enableAckPayload();               // enable the radio feature that allows the slave to reply.
  56.   radio.setRetries(5, 5);                 // delay, count   // 5 gives a 1500 µsec delay which is needed for a 32 byte ackPayload
  57.   pinMode(ledPinA, OUTPUT);   // set the output pin to output mode.
  58.   pinMode(LED_BUILTIN, OUTPUT);
  59. }
  60.  
  61. //=============
  62.  
  63. void loop() {             // this code runs repeatedly
  64.   currentMillis = millis();   // take note of the time this loop started
  65.   checkButtonState();         // take note of the button states
  66.   masterMode();               // establish which mode the unit is in, for each of the slaves (only one so far)
  67.   prepareMessage();           // build the message that will be sent.
  68.   sendMessageA();             // send the message to slave A
  69.   // sendMessageB();             // send the message to slave B (Not yet operational)
  70.   processAck();               // process the acknowledgement number from the slave
  71.   lightLocalLED();            // light up the attached LED if a confirmation has been recieved from the slave.
  72.   updateLCD();
  73.   updateSerial();             // primarily for troubleshooting, update the serial monitor.
  74. }
  75.  
  76. //================
  77.  
  78. void checkButtonState() {                                                  // take note of the button states
  79.   if ((currentMillis - prevButtonMillis) >= debounceInterval) {            // if it's been at least 'debounceInterval' ms since the button was last pressed,
  80.     if (digitalRead(buttonPinA) == HIGH) {                                          
  81.       buttonAActive = 1;
  82.       prevButtonMillis = millis();
  83.     }
  84.   }
  85. }
  86.  
  87. //================
  88.  
  89. void masterMode() { // decides what the mastermode should be
  90.  
  91.   if (masterAMode == 0 && buttonAActive == 1) { // if the current mode is 0 and the button has been pressed
  92.     masterAMode = 1; // mastermode is set to 'activated, waiting for confirmation' from the slave
  93.     buttonAActive = 0;
  94.   }
  95.   if (masterAMode == 1 && ackData[0] == 1) { // if the slave has confirmed that it is activated
  96.     masterAMode = 2; // mastermode is set to 'activated, confirmed' by the slave
  97.     buttonAActive = 0;
  98.   }
  99.   if (masterAMode == 2 && ackData[0] == 2) { // if the button has been pressed and the slavemode is activated
  100.     masterAMode = 3; // mastermode is deactivated, waiting for confirmation from the slave
  101.     buttonAActive = 0;
  102.   }
  103.   if ((masterAMode == 1 || masterAMode == 2) && buttonAActive == 1) { // if the button has been pressed in mastermode 1 or 2
  104.     masterAMode = 0; // mastermode is deactivated, waiting for confirmation from the slave
  105.     buttonAActive = 0;
  106.   }
  107.   if (masterAMode == 3 && ackData[0] == 2) {
  108.     masterAMode = 0;
  109.   }
  110. }
  111.  
  112. //================
  113. void prepareMessage() {
  114.   if (masterAMode == 0 || masterAMode == 3) {
  115.     txNum = '0';
  116.   }
  117.   if (masterAMode == 1 || masterAMode == 2) {
  118.     txNum = '1';
  119.   }
  120.   dataToSend[0] = txNum;
  121. }
  122.  
  123. //================
  124.  
  125. void sendMessageA() {
  126.   radio.openWritingPipe(slaveAddressA);
  127.   if ((currentMillis - prevSendMillis) >= sendInterval) {
  128.     bool rslt;
  129.     rslt = radio.write( &dataToSend, sizeof(dataToSend) );
  130.     // Always use sizeof() as it gives the size as the number of bytes.
  131.     // For example if dataToSend was an int sizeof() would correctly return 2
  132.     if (rslt) {
  133.       if ( radio.isAckPayloadAvailable() ) {
  134.         radio.read(&ackData, sizeof(ackData));
  135.         newData = true;
  136.       }
  137.     }
  138.     else {
  139.       Serial.println("  Acknowledge but no data ");
  140.     }
  141.     prevSendMillis = currentMillis;
  142.   }
  143. }
  144.  
  145. //================
  146.  
  147. void sendMessageB() {
  148.   radio.openWritingPipe(slaveAddressB);
  149.   if ((currentMillis - prevSendMillis) >= sendInterval) {
  150.     bool rslt;
  151.     rslt = radio.write( &dataToSend, sizeof(dataToSend) );
  152.     // Always use sizeof() as it gives the size as the number of bytes.
  153.     // For example if dataToSend was an int sizeof() would correctly return 2
  154.     if (rslt) {
  155.       if ( radio.isAckPayloadAvailable() ) {
  156.         radio.read(&ackData, sizeof(ackData));
  157.         newData = true;
  158.       }
  159.     }
  160.     else {
  161.       Serial.println("  Acknowledge but no data ");
  162.     }
  163.     prevSendMillis = currentMillis;
  164.   }
  165. }
  166. //=================
  167. void processAck() {
  168.   // slaveAMode = ackData[0];
  169. }
  170. //================
  171.  
  172. void lightLocalLED() {
  173.   if (masterAMode == 2) {
  174.     digitalWrite(ledPinA, HIGH);
  175.     digitalWrite(LED_BUILTIN, HIGH);
  176.   //  Serial.println("LIGHT HIGH");
  177.   } else {
  178.     digitalWrite(ledPinA, LOW);
  179.     digitalWrite(LED_BUILTIN, LOW);
  180.    // Serial.println("LIGHT LOW");
  181.   }
  182. }
  183.  
  184. //================
  185. void updateLCD()
  186. {
  187.   // Print a message to the LCD.
  188.   lcd.backlight();
  189.   lcd.setCursor(2,0);
  190.   lcd.print("Hello World!");
  191.   //lcd.setCursor(0,1);
  192.   //lcd.print("");
  193. }
  194. //================
  195. void updateSerial() {
  196.   if ((currentMillis - prevSerial) >= serialUpdateInterval) {
  197.     Serial.print(" masterAMode ");
  198.     Serial.print(masterAMode);
  199.     Serial.print(" buttonAActive ");
  200.     Serial.print(buttonAActive);
  201.     Serial.print("  txNum ");
  202.     Serial.print(txNum);
  203.     Serial.print(" Sent: ");
  204.     Serial.print(dataToSend);
  205.     if (newData == true) {
  206.       Serial.print("  Ack recd: ");
  207.       Serial.print(ackData[0]);
  208.       Serial.print(", ");
  209.       Serial.print(ackData[1]);
  210.       newData = false;
  211.     }
  212.     prevSerial = currentMillis;
  213.     Serial.println();
  214.   }
  215. }
  216. //=================
Advertisement
Add Comment
Please, Sign In to add comment