Skip to content

Instantly share code, notes, and snippets.

@NSBum
Created March 29, 2018 21:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NSBum/461908892287fe338755c6a088b1b39e to your computer and use it in GitHub Desktop.
Save NSBum/461908892287fe338755c6a088b1b39e to your computer and use it in GitHub Desktop.
Trigger relay remotely using nRF24L01+ modules
#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;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment