#include <SPI.h> #include "RF24.h" #include <EEPROM.h> /* Hardware connections from Arduino Nano to nRF24L01 * CE -> D9 * CSN -> D10 * SCK -> D13 * MOSI -> D11 * MISO -> D12 * IRQ -> N/C * * Set up both Nano + RF24 the same way. Make the transmitter radio 1 and the receiver radio 0 * On the receiver, setup a relay driven by D8 */ // **************** User configuration *************** // set this as radio 0 or 1 bool radioNumber = 1; /* Hardware configuration */ RF24 radio(9,10); // Network topology uint8_t addresses[][6] = {"1Node","2Node"}; // Role management typedef enum { role_xmit = 1, role_recv=0 } role_e; const char* role_friendly_name[] = { "Receive", "Transmit" }; role_e role = role_recv; // State management typedef enum { state_free_serial = 0, state_obtain_code = 1, state_idle = 2 } state_t; state_t currentState = state_free_serial; // EEPROM #define ID_WAS_WRITTEN 0x1D #define ID_ADDR 1 #define TRANSMITTER_ID 0x74 // 't' #define RECEIVER_ID 0x72 // 'r' #define RELAY_PIN 8 #define RELAY_SET_CMD 0x666 // code the transmitter sends to toggle relay #define RELAY_SET_RESPONSE 0x333 // success code returned by receiver #define RELAY_NOT_SET_RESPONSE 0x111 // no success code returned by receiver // "Button" - we're not using a physical button here // instead we are looking for a "B" on the serial input // to the transmitter bool buttonPressed = false; void setup() { Serial.begin(9600); Serial.println( F("RF24 remote relay test") ); // read the EEPROM first and see if we have a hardware ID if( EEPROM.read(0) == ID_WAS_WRITTEN ) { // we can extract the ID and set a default role radioNumber = (EEPROM.read(ID_ADDR) == TRANSMITTER_ID)?1:0; role = (radioNumber == 1 )?role_xmit:role_recv; Serial.print( F("EEPROM Radio # ") ); Serial.println(radioNumber); } else { Serial.println( F("*** PRESS 'T' to begin transmitting to the other node") ); } // configure our radio radio.begin(); radio.setPALevel(RF24_PA_MIN); if( radioNumber ) { radio.openWritingPipe(addresses[1]); radio.openReadingPipe(1,addresses[0]); } else { radio.openWritingPipe(addresses[0]); radio.openReadingPipe(1,addresses[1]); } if( role == role_recv ) { digitalWrite(RELAY_PIN, LOW); pinMode(RELAY_PIN, OUTPUT); } radio.startListening(); } void loop() { if( role == role_xmit ) { uint16_t start_time = micros(); radio.stopListening(); if( buttonPressed ) { buttonPressed = false; uint16_t sendData = RELAY_SET_CMD; Serial.println(F("Now sending button press")); if (!radio.write( &sendData, sizeof(uint16_t) )){ Serial.println(F("*** ERROR: failed to send")); } radio.startListening(); unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds boolean timeout = false; while( !radio.available() ) { if (micros() - started_waiting_at > 200000 ){ // If waited longer than 200ms, indicate timeout and exit while loop timeout = true; break; } } if( timeout ) { Serial.println(F("*** WARN: response timed out")); } else { uint16_t response; radio.read( &response, sizeof(uint16_t)); Serial.print(F("Received response: 0x")); Serial.println(response, HEX); } } } // xmit role // if we are the receiver else { uint16_t code; if( radio.available() ) { while( radio.available() ) { radio.read( &code, sizeof(uint16_t) ); } radio.stopListening(); if(code == RELAY_SET_CMD ) { digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN)); code = RELAY_SET_RESPONSE; } else { code = RELAY_NOT_SET_RESPONSE; } radio.write( &code, sizeof(uint16_t) ); radio.startListening(); Serial.print(F("Sent response ")); Serial.println(code,HEX); } } // rcv role // each pass check if user wants to switch if( Serial.available() ) { if( currentState == state_obtain_code ) { uint8_t code = Serial.read(); // mark that we've written an ID EEPROM.write(0,0x1D); EEPROM.write(ID_ADDR, code); currentState == state_idle; } else { char c = toupper(Serial.read()); if( c == 'T' && role == role_recv ) { Serial.println(F("*** CHANGING TO XMIT ROLE ***")); role = role_xmit; } else if( c== 'R' && role == role_xmit ) { Serial.println(F("*** CHANGING TO RCV ROLE ***")); role = role_recv; radio.startListening(); } else if( c == 'B' && role == role_xmit ) { Serial.println(F("*** BUTTON PRESSED ***")); buttonPressed = true; } else if( c == 'S' ) { // next pass through serial read loop will // obtain the code to use Serial.println("Type 't' for radio1/xmit or 'r' for radio0/receive"); currentState = state_obtain_code; } } } }