WireLess Gate Shield V1.0

WireLess Gate Shield is an Arduino-compatible expansion card designed to build a system of receiving / transmitting and broadcasting various wireless commands and data. For maximum coverage possible wireless communication interfaces on the board has an IR receiver interface for connecting popular transceiver nRF24L01 + and RFM69HW. Additionally, the board has a real time clock module DS1307.

Model: 113990088

Features

Layout and schematics

On the left side WireLess Gate Shield are interfaces to wireless modules:

Between wireless modules is U.FL connector for external antenna for RFM69HW. If you plan to use the regular antenna (bit of wire required length) - it is possible to solder directly to the board Schild (near the connector U.FL)

To the right and slightly above the module is RFM69HW LED LED1 "RF433"

In the central part of the board is a slot for a backup battery for clock module DS1307

To the right and slightly below the slot for the battery - I2C-connector.

On the right side is (top-down):

Basic functionality

In the basic version (without the use of Ethernet Shield) may organize a wireless gateway between the radios and the IR receiver.

Command (or data) can be broadcast between all three wireless interfaces according to the logic of that program the user.

Availability of real-time clock module will automate the sending of any data or commands with reference to the date / time.

Device Management can be organized using a button located on the Shield.

Expansion Capabilities

Additionally WireLess Gate Shield can connect any i2c device using Grove-compatible connections (sensors, displays, etc.).

WireLess Gate Shield was designed to be fully compatible with Ethernet Shield - so you can use these two together Schild to create even more advanced wireless control device (logging on SD-card and presenting data on a web page, manage wireless devices via the web).

Interfaces

Features WireLess Gate Shield

Wireless Modules

Both wireless module RFM69HW and nRF24l01 + connected hardware bus SPI.

Selection of a particular wireless module is a low potential for the establishment of the appropriate chip select pin:

'Warning', 'If you have installed, but the software is not involved RFM69HW, be sure to install NSS pin of this module in state HIGH (otherwise it will interfere with the normal operation nRF24l01 + and Ethernet Shield.

Automatic display of the wireless modules

LED indication of the wireless module is implemented as follows:

When radios are not active - at the appropriate pines chip select (CSN and NSS) there is a high potential, with the appearance of the clock at pin SCK does not lead to the ignition of the LEDs. If the same MK "communicates" with any wireless module to select it at the appropriate Pina (CSN and NSS) is set low potential and at the same timing pulses at pin SCK "ignite" the corresponding LED.

Thus, the user is not required to arrange for any additional programming work on the MC to indicate operation of the module.

Features

If necessary, SMD-LED to replace the usual outs (eg to embed the finished device in a cute case with display):

Modification to control via IR

Custom LED can be replaced by LED3 pin IR LED and thereby further expand the use of WireLess Gate Shield (for example, a command sent via any wireless interface or LAN - control devices using infrared commands).

Libraries

Required Library

To use the WireLess Gate Shield requires the following libraries:

Additionally required libraries that are used when working RF24 and LCD-display:

Libraries are examples of them just to understand how they work.

Features use libraries

NRF24l01 +

Module Initialization nRF24l01 + as follows:

...

//RF24 radio(CE,CSN);
RF24 radio(7,8);

...

RFM69HW

To work with a wireless module RFM69HW need to make minor corrections to the file RFM69.h follows:

At the beginning of the file to find the line:

#define SPI_CS               SS // SS is the SPI slave select pin, for instance D10 on atmega328
#define RF69_IRQ_PIN          2 // INT0 on AVRs should be connected to DIO0 (ex on Atmega328 it's D2)

And replace them with:

//#define SPI_CS               SS // SS is the SPI slave select pin, for instance D10 on atmega328
//#define RF69_IRQ_PIN          2 // INT0 on AVRs should be connected to DIO0 (ex on Atmega328 it's D2)
#define SPI_CS               9 // SS is the SPI slave select pin, for WireLess Gate Shield - D9
#define RF69_IRQ_PIN          3 // INT1 on AVRs should be connected to DIO0 (ex on Atmega328 it's D3)

Additionally, the file RFM69.cpp need to find the line:

void RFM69::isr0() { selfPointer->interruptHandler(); }

And replace them with:

//void RFM69::isr0() { selfPointer->interruptHandler(); }
void RFM69::isr1() { selfPointer->interruptHandler(); }

Module Initialization RFM69HW as follows:

...

  resetRFM69();
  radio.setCS(9); // NSS - D9
  radio.initialize(FREQUENCY,NODEID,NETWORKID);

...

'Note:' Working with RFM69HW determined by the state of its registers. For more tinctures for specific endpoints required by the rules in the file RFM69.cpp function RFM69 :: initialize To better understand the purpose registers read the file RFM69registers.h (also included in the library), and documentation radio RFM69HW

Demonstration

Code for the main unit with WireLess Gate Shield (works with RTC, IR, RFM69HW, nRF24l01 +)

All results are displayed in the Serial Monitor

 
#include <RFM69.h>
#include <SPI.h>
#include "RF24.h"
#include <IRremote.h>
#include <Wire.h>
#include "RTClib.h"
 
RF24 radio24(7,8); 
 
RTC_DS1307 RTC;
 
int RECV_PIN = 5;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
// create a framework for the transmission of values
typedef struct{         
  int SensorID;        // ID sensor
  int CommandTo;       // command module number ...
  int Command;         // command
  // 0 - answer 
  // 1 - get the value
  // 2 - set the value
  int ParamID;         // parameter identifier
  float ParamValue;    // value
  boolean Status;      // status
  // 0 - read-only (RO)
  // 1 -  can change the (RW)
  char Comment[16];    // comment
}
Message;
 
Message sensor; 
 
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
 
volatile boolean waitRF24 = false;
 
#define NODEID      99
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_433MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED         6
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack
 
#define RFM69_RESET 14  //A0
#define RFM69_NSS 9
#define RFM69_DIO0 3
 
#define BUTTON 15 // A1
 
#define MOSI 11
#define MISO 12
#define SCK 13
 
int TRANSMITPERIOD = 500; //transmit a packet to gateway so often (in ms)
byte sendSize=0;
boolean requestACK = false;
RFM69 radio;
 
int delta=2000;
 
unsigned long blinkStop;
unsigned long timeReady;
 
typedef struct {		
  int           nodeId; //store this nodeId
  unsigned long uptime; //uptime in ms
  float         temp;   //temperature maybe?
} 
Payload;
Payload theData;
 
void setup() {
  Serial.begin(SERIAL_BAUD);
 
  pinMode(LED, OUTPUT);
 
  pinMode(RFM69_NSS, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(SCK, OUTPUT);
 
  pinMode(RFM69_RESET, OUTPUT);
  pinMode(RFM69_DIO0, INPUT);
 
  pinMode(BUTTON, INPUT);
 
  digitalWrite(RFM69_NSS, HIGH);
  digitalWrite(7, HIGH);
 
  resetRFM69();
  radio.setCS(RFM69_NSS);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
 
  //radio.setHighPower(); //uncomment only for RFM69HW!
 
  radio.encrypt(KEY);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
 
  radio24.begin();
  // optionally, increase the delay between retries & # of retries
  radio24.setRetries(15,15);
  radio24.setChannel(119);
  // по умолчанию СЛУШАЕМ
  radio24.openWritingPipe(pipes[1]);
  radio24.openReadingPipe(1,pipes[0]);
  radio24.startListening();
 
  delay(20);
 
  attachInterrupt(0, isr_RF24, FALLING);
 
  irrecv.enableIRIn();
 
  Wire.begin();
  RTC.begin();
 
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}
 
long lastPeriod = -1;
void loop() {
 
  //check for any received packets
  if (radio.receiveDone())
  {
    Serial.print('[');
    Serial.print(radio.SENDERID, DEC);
    Serial.print("] ");
    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);
    Serial.print("   [RX_RSSI:");
    Serial.print(radio.readRSSI());
    Serial.print("]");
 
    if (radio.ACK_REQUESTED)
    {
      radio.sendACK();
      Serial.print(" - ACK sent");
      delay(10);
    }
    Serial.println();
  }
 
  int currPeriod = millis()/TRANSMITPERIOD;
  if (currPeriod != lastPeriod)
  {
    //fill in the struct with new values
    theData.nodeId = NODEID;
    theData.uptime = millis();
    theData.temp = radio.readTemperature();//91.23; //it's hot!
 
    Serial.print("Sending struct (");
    Serial.print(sizeof(theData));
    Serial.print(" bytes) ... ");
    if (radio.sendWithRetry(GATEWAYID, (const void*)(&theData), sizeof(theData)))
      Serial.print(" ok!");
    else Serial.print(" nothing...");
    Serial.println();
    lastPeriod=currPeriod;
  }
 
  listenRF24();
 
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
    blinkStop=millis()+100;
    digitalWrite(LED, HIGH);
  }
 
  if (digitalRead(BUTTON)==LOW) {
    blinkStop=millis()+1000;
    digitalWrite(LED, HIGH);
  }
 
  if (millis()>blinkStop) {
    digitalWrite(LED, LOW);
  }
 
  if(millis()>timeReady){
    timeReady=millis()+2000;
    DateTime now = RTC.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
}
}
 
void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}
 
void resetRFM69(){
  digitalWrite(RFM69_RESET, HIGH);
  delay(1);
  digitalWrite(RFM69_RESET, LOW);
  delay(10);
}
 
void isr_RF24(){
  waitRF24 = true;
}
 
void listenRF24() {
  if (waitRF24) {
    waitRF24 = false;
    if ( radio24.available() )
    {
      bool done = false;
      while (!done)
      {
        done = radio24.read( &sensor, sizeof(sensor) );
        if(sensor.Command == 0) {  
          Serial.print(sensor.SensorID);
          Serial.print("  ");
          Serial.print(sensor.ParamID);
          Serial.print("  ");
          Serial.print(sensor.ParamValue);
          Serial.print(" ");
          Serial.println(sensor.Comment);
        }
      }
    }
  }
}

Code for "receiver" (for the test used Arduino Nano and RFM69HW module on the breadboard)

 
#include <RFM69.h>
#include <SPI.h>
 
#define NODEID      1
#define NETWORKID   100
#define FREQUENCY   RF69_433MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED         6
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack
 
#define RFM69_RESET 14
 
RFM69 radio;
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
 
typedef struct {		
  int           nodeId; //store this nodeId
  unsigned long uptime; //uptime in ms
  float         temp;   //temperature maybe?
} Payload;
Payload theData;
 
void setup() {
  Serial.begin(SERIAL_BAUD);
  pinMode(RFM69_RESET, OUTPUT);
  pinMode(3, INPUT);
  resetRFM69();
  radio.setCS(9);
  //delay(10);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
 
  //radio.setHighPower(); //uncomment only for RFM69HW!
 
  radio.encrypt(KEY);
  radio.promiscuous(promiscuousMode);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
}
 
byte ackCount=0;
void loop() {
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input == 'r') //d=dump all register values
      radio.readAllRegs();
    if (input == 'E') //E=enable encryption
      radio.encrypt(KEY);
    if (input == 'e') //e=disable encryption
      radio.encrypt(null);
    if (input == 'p')
    {
      promiscuousMode = !promiscuousMode;
      radio.promiscuous(promiscuousMode);
      Serial.print("Promiscuous mode ");Serial.println(promiscuousMode ? "on" : "off");
    }
 
    if (input == 'd') //d=dump flash area
    {
      Serial.println("Flash content:");
      int counter = 0;
 
      while(counter<=256){
        //Serial.print(flash.readByte(counter++), HEX);
        Serial.print('.');
      }
      //while(flash.busy());
      Serial.println();
    }
    if (input == 'D')
    {
      Serial.print("Deleting Flash chip content... ");
      //flash.chipErase();
      //while(flash.busy());
      Serial.println("DONE");
    }
    if (input == 'i')
    {
      Serial.print("DeviceID: ");
      //word jedecid = flash.readDeviceId();
      //Serial.println(jedecid, HEX);
    }
  }
 
  if (radio.receiveDone())
  {
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
    Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");
    if (promiscuousMode)
	{
      Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
    }
 
    if (radio.DATALEN != sizeof(Payload))
      Serial.print("Invalid payload received, not matching Payload struct!");
    else
    {
      theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
      Serial.print(" nodeId=");
      Serial.print(theData.nodeId);
      Serial.print(" uptime=");
      Serial.print(theData.uptime);
      Serial.print(" temp=");
      Serial.print(theData.temp);
    }
 
    if (radio.ACK_REQUESTED)
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      Serial.print(" - ACK sent.");
 
      // When a node requests an ACK, respond to the ACK
      // and also send a packet requesting an ACK (every 3rd one only)
      // This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
      if (ackCount++%3==0)
      {
        Serial.print(" Pinging node ");
        Serial.print(theNodeID);
        Serial.print(" - ACK...");
        delay(3); //need this when sending right after reception .. ?
        if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0))  // 0 = only 1 attempt, no retries
          Serial.print("ok!");
        else Serial.print("nothing");
      }
    }
    Serial.println();
    Blink(LED,3);
  }
}
 
void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}
 
void resetRFM69(){
  digitalWrite(RFM69_RESET, HIGH);
  delay(1);
  digitalWrite(RFM69_RESET, LOW);
  delay(10);
}

Product versions

Revision Description Release
0.9 Prototype 05.05.2014
1.0 Public version 05.07.2014

Applications

Questions and Answers

How to buy

This product can be purchased:
China (shipping worldwide)
Elecrow store
Seeed store

Russia
Devicter store

Links

Copyright (c) 2008-2016 Seeed Development Limited (www.seeedstudio.com / www.seeed.cc)
This static html page was created from http://www.seeedstudio.com/wiki