GithubHelp home page GithubHelp logo

nrf24 / rf24ethernet Goto Github PK

View Code? Open in Web Editor NEW
119.0 20.0 54.0 2.08 MB

OSI Layers 4&5 Wireless (not WiFi) TCP/IP networking on Arduino devices using nrf24l01+ & nrf52x radios

Home Page: http://nrf24.github.io/RF24Ethernet

C++ 24.22% C 75.78%
rf24 c-plus-plus arduino-library ethernet nrf24l01 uip

rf24ethernet's Introduction

Ethernet and TCP/IP Networking for RF24Network

Arduino CLI build PlatformIO build

Easily create home automation scenarios and sensor networks

Updated 2023:

RF24Ethernet requires the RF24, RF24Network and RF24Mesh libraries

Documentation & Setup Info: http://nRF24.github.io/RF24Ethernet

Downloads: http://tmrh20.github.io/

Note: Recent changes to support NRF5x boards prevent usage of RF24 devices with NRF5x boards. Users must use the internal radio with RF24Ethernet. See the nrf_to_nrf Arduino library.


Licenses include, but are not limited to the following.

RF24Ethernet.h, RF24Ethernet.cpp, RF24Server.h, RF24Server.cpp, RF24Client.h, RF24Client.cpp, RF24Udp.h, RF24Udp.cpp, utility/mempool.h, utility/mempool.cpp

Copyright (c) 2014 [email protected], github.com/TMRh20 Copyright (c) 2013 Norbert Truchsess [email protected] All rights reserved.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.


utility/uip.c, utility/uip_arp.h, utility/uip_arp.c, utility/uip_arch.h, utility/uip.h, utility/uipopt.h

Copyright (c) 2001-2003, Adam Dunkels [email protected], [email protected]. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


uip-conf.h, utility/uip-neighbor.h, utility/uip-neighbor.c, utility/uip_timer.h, utility/uip_timer.c, utility/uip_clock.h

Author Adam Dunkels Adam Dunkels [email protected], [email protected] Copyright (c) 2004,2006, Swedish Institute of Computer Science. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Dhcp.h, Dhcp.cpp

DHCP Library v0.3 - April 25, 2009 Author: Jordan Terrell - blog.jordanterrell.com

  • as included in Arduinos stock Ethernet-library, no special licence mentioned here

Dns.h, Dns.cpp

(c) Copyright 2009-2010 MCQN Ltd. Released under Apache License, version 2.0


clock-arch.h, clock-arch.c

Copyright (c) 2010 Adam Nielsen [email protected] All rights reserved.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

rf24ethernet's People

Contributors

2bndy5 avatar per1234 avatar tmrh20 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rf24ethernet's Issues

restore from RF24 power down

I'm trying to create battery powered modules running RF24Ehternet. This requires to put both the arduino and the radio in power down mode. I was wondering if this is even possible?

I already tried some things and part of it seems working. If I only put the arduino in sleep mode and keep the radio running it correctly wakes up and handles ping request I send.

However, if I put the radio in power down (according to some examples seen in RF24Network) it seems not to wakeup based from the ping request.

On the other hand the node can perfectly send data by it self after a wakeup of the watchdog. I call update of the mesh before, but didn't verify yet if that is required.

Now I didn't dig to deep in the sources yet, but at first glance I think it should be possible. However, maybe dynamic mesh allocation interferes here. If you could give me some directions I try to to dig a little bit deeper.

BTW: TMRh20 created a very cool set of libraries here. Great work!!!

Port to RF22 possible? Implications?

Hi folks,
I need thia lib to work with the RF22 driver for 443MHz.
Is it just replacing the RF24 driver with RF22?
(as far as I know they are from the same programmer and the interface should be almost the same)
The datarate of RF22 is much lower.
Are there any implications lower rate will cause?

This lib working on a free low-Frequency LoRa would open endless possibilities.

Awesome library. Very impressed.
I know all the functionalities are already there in RF22/24/xx drivers+EthernetIP+RadioHead but puzzling it together into a working version is what I tried to arlchieve myself for ages till I just found this lib.

Arduino SLIP Gateway - Http Server problems

As I writed on the RF24Mesh lib I'm experiencing some problems on the samples SLIP Gateway and Http Server. When the SLIP Gateway is turned off, then I have to turn off and turn on the Http Server to reestabilish the connection. Is there a work around?
The only modification I apported to the sample is the ce and csn pins (I use 9,10).
Only a question, If I remove the gateway and use directly the raspberry, would it be more reliable or it is the same? Now I've some problem using directly the raspberry but, if you tell me that it will work better then I will work on it..

USB Ethernet support

creating a ticket to bookmark this feature. This is a point I've been thinking about recently and this comes to me as a really neat idea to add to RF24Ethernet: Support of USB Network device.

Idea: create an USB Stick with nRF24l01 supporting one of standard USB Ethernet interfaces (ECM, RNDIS, ...) so the stick is detected by OS as a regular USB ethernet device.

My explorations on this so far:

  • VUsb is probably not a good idea to use as it utilizes USB 1.1 standard only and does not support bulk endpoints that mentioned USB ethernet standards use
  • good way seems to be to use LUFA library; there is a nice example there for simple RNDIS device. But this implies to use an avr chip with USB support
  • it should be possible to use atmega32U4 used in Leonardo, pro micro, etc...
  • mentioned RNDIS example requires better chips with more ram, but it is mainly due to large max ethernet frames, large tcp window and can be reduced to fit to atmega32u4's ram (I did some trials recently there)

The code to be added for this purpose to RF24Network would be probably not that complicated from my point of view and maybe it's already mostly there: get an ethernet frame from LUFA/network, check it's type:

  • arp -> call uip's arp handling & send it back to LUFA or network
  • ip -> get dest mac from uip's arp, and send the frame with ip accordingly via LUFA or network
    ...and that's probably it. No need for any transport/application layer handling, all this is done on host OS level.

Expected scenario - plug Leonardo into usb -> you get an Ethernet device, assign it's IP and here you go, you are connected to RF24 network.

@TMRh20 any opinion about that?

Problem with InteractiveServer_Mesh example

Just to officially open an issue for tracking, there is an issue with this example serving up http requests for any number of days, usually a couple weeks or more before failing to respond to http requests. The example responds to ping and the mesh seems to stay active, but thats it. I should know in 20 days or less whether I have a fix.

Esp8266 example

Hi,

I was looking at your new example with the esp8266 wifi board. The sketch you wrote has to be uploaded on the arduino or on the esp module?
How do you connect it to the arduino?

Which library do you use with esp?

Thanks,
Bye.

Connecting to raspbery pi server

Hello,
I have the following code, i resolved the other issue with client.stop(), now this problem the client dosent want to connect to server after wakeing up from sleep, am I missing a network refresh or something?

// Wake from deep sleep with a keypress demonstration

include <Keypad.h>

include <avr/sleep.h>

include <RF24Network.h>

include <RF24.h>

include <RF24Mesh.h>

include <SPI.h>

include <RF24Ethernet.h>

if !defined arm && !defined ARDUINO_X86

#include <EEPROM.h>

endif

define VBAT_PER_BITS 0.3363075 // Calculated volts per bit from the used battery montoring voltage divider. Internal_ref=1.1V, res=10bit=2^10-1=1023, Eg for 3V (2AA): Vin/Vb=R1/(R1+R2)=470e3/(1e6+470e3), Vlim=Vb/Vin*1.1=3.44V, Volts per bit = Vlim/1023= 0.003363075

define VMIN 1.9 // Battery monitor lower level. Vmin_radio=1.9V

define VMAX 3.3 // " " " high level. Vmin<Vmax<=3.44

/*** Configure the radio CE & CS pins ***/
RF24 radio(14,15);
RF24Network network(radio);
RF24Mesh mesh(radio,network);
RF24EthernetClass RF24Ethernet(radio,network,mesh);

EthernetClient client;

String voltagestr;
String code;
int voltage;
int time = 0;
int BATTERY_SENSE_PIN = A5; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {

{'#','0','*'},
{'9','8','7'},
{'6','5','4'},
{'3','2','1'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {2, 3, 4}; //connect to the column pinouts of the keypad

// number of items in an array

define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

const byte beepPin = 16;
const byte ledPin = 17;
// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

/*

Pin change interrupts.

Pin Mask / Flag / Enable

D0 PCINT16 (PCMSK2 / PCIF2 / PCIE2)
D1 PCINT17 (PCMSK2 / PCIF2 / PCIE2)
D2 PCINT18 (PCMSK2 / PCIF2 / PCIE2)
D3 PCINT19 (PCMSK2 / PCIF2 / PCIE2)
D4 PCINT20 (PCMSK2 / PCIF2 / PCIE2)
D5 PCINT21 (PCMSK2 / PCIF2 / PCIE2)
D6 PCINT22 (PCMSK2 / PCIF2 / PCIE2)
D7 PCINT23 (PCMSK2 / PCIF2 / PCIE2)
D8 PCINT0 (PCMSK0 / PCIF0 / PCIE0)
D9 PCINT1 (PCMSK0 / PCIF0 / PCIE0)
D10 PCINT2 (PCMSK0 / PCIF0 / PCIE0)
D11 PCINT3 (PCMSK0 / PCIF0 / PCIE0)
D12 PCINT4 (PCMSK0 / PCIF0 / PCIE0)
D13 PCINT5 (PCMSK0 / PCIF0 / PCIE0)
A0 PCINT8 (PCMSK1 / PCIF1 / PCIE1)
A1 PCINT9 (PCMSK1 / PCIF1 / PCIE1)
A2 PCINT10 (PCMSK1 / PCIF1 / PCIE1)
A3 PCINT11 (PCMSK1 / PCIF1 / PCIE1)
A4 PCINT12 (PCMSK1 / PCIF1 / PCIE1)
A5 PCINT13 (PCMSK1 / PCIF1 / PCIE1)

*/

// we don't want to do anything except wake
EMPTY_INTERRUPT (PCINT0_vect)
EMPTY_INTERRUPT (PCINT1_vect)
EMPTY_INTERRUPT (PCINT2_vect)

void setup (){

Serial.begin(115200);
Serial.println("Start");
// Set the IP address we'll be using. The last octet mast match the nodeID (9)
IPAddress myIP(10,0,0,20);
Ethernet.begin(myIP);
mesh.begin();

// If you'll be making outgoing connections from the Arduino to the rest of
// the world, you'll need a gateway set up.
IPAddress gwIP(10,0,0,1);
Ethernet.set_gateway(gwIP);
code = String("");
analogReference(INTERNAL); // use the 1.1 V internal reference for battery level measuring
kpd.addEventListener(keypadEvent); // Add an event listener for this keypad
pinMode (ledPin, OUTPUT);
pinMode (beepPin, OUTPUT);

// pin change interrupt masks (see above list)
PCMSK2 |= _BV (PCINT21); // pin 5
PCMSK2 |= _BV (PCINT22); // pin 6
PCMSK2 |= _BV (PCINT23); // pin 7
PCMSK0 |= _BV (PCINT0); // pin 8

} // end of setup

// set pins as keypad library expects them
// or call: kpd.initializePins ();
// however in the library I have that is a private method
void error_beep(){
digitalWrite (beepPin, HIGH);
delay (500);
digitalWrite (beepPin, LOW);
delay (500);
digitalWrite (beepPin, HIGH);
delay (500);
digitalWrite (beepPin, LOW);
delay (500);
}
void reconfigurePins ()
{
byte i;

// go back to all pins as per the keypad library

for (i = 0; i < NUMITEMS (colPins); i++)
{
pinMode (colPins [i], OUTPUT);
digitalWrite (colPins [i], HIGH);
} // end of for each column

for (i = 0; i < NUMITEMS (rowPins); i++)
{
pinMode (rowPins [i], INPUT);
digitalWrite (rowPins [i], HIGH);
} // end of for each row

} // end of reconfigurePins

void goToSleep ()
{
byte i;

// set up to detect a keypress
for (i = 0; i < NUMITEMS (colPins); i++)
{
pinMode (colPins [i], OUTPUT);
digitalWrite (colPins [i], LOW); // columns low
} // end of for each column

for (i = 0; i < NUMITEMS (rowPins); i++)
{
pinMode (rowPins [i], INPUT);
digitalWrite (rowPins [i], HIGH); // rows high (pull-up)
} // end of for each row

// now check no pins pressed (otherwise we wake on a key release)
for (i = 0; i < NUMITEMS (rowPins); i++)
{
if (digitalRead (rowPins [i]) == LOW)
{
reconfigurePins ();
return;
} // end of a pin pressed
} // end of for each row

// overcome any debounce delays built into the keypad library
delay (50);

// at this point, pressing a key should connect the high in the row to the
// to the low in the column and trigger a pin change

set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();

byte old_ADCSRA = ADCSRA;
// disable ADC to save power
ADCSRA = 0;

PRR = 0xFF; // turn off various modules

PCIFR |= _BV (PCIF0) | _BV (PCIF1) | _BV (PCIF2); // clear any outstanding interrupts
PCICR |= _BV (PCIE0) | _BV (PCIE1) | _BV (PCIE2); // enable pin change interrupts

// turn off brown-out enable in software
MCUCR = _BV (BODS) | _BV (BODSE);
MCUCR = _BV (BODS);
sleep_cpu ();

// cancel sleep as a precaution
sleep_disable();
PCICR = 0; // cancel pin change interrupts
PRR = 0; // enable modules again
ADCSRA = old_ADCSRA; // re-enable ADC conversion

// put keypad pins back how they are expected to be
reconfigurePins ();
Serial.println("Radio On");
radio.powerUp();
delay(30);
} // end of goToSleep

void loop () {

int sensorValue = analogRead(BATTERY_SENSE_PIN); // Battery monitoring reading
voltage = sensorValue * VBAT_PER_BITS;
voltagestr = String(voltage,0);
// int batteryPcnt = sensorValue / 10;
// int batteryPcnt = static_cast(((Vbat-VMIN)/(VMAX-VMIN))*100.)
//Serial.println("Awake ");
if(time == 500){
delay(50);
time = 0;
code= " ";
digitalWrite(ledPin, LOW);
client.stop();
delay(50);
radio.powerDown();
delay(50);
Serial.println("Sleeping t-out");
goToSleep();
}else{
time++;
delay(50);
//Serial.println(time);
digitalWrite(ledPin, HIGH);
//byte key = kpd.getKey();
char pressed = kpd.getKey();

 if (pressed){
    code.concat(pressed);
    Serial.print("Code: ");
    Serial.println(code);
    //Serial.println(pressed);
    //Serial.println(sensorValue);
    Serial.print("Battery Voltage: "); Serial.print(voltage); Serial.println(" V");
    //Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");
    digitalWrite(beepPin, HIGH);
    delay (50); 
    digitalWrite(beepPin, LOW);
    delay (50);
 } 

}

} // end of loop
void keypadEvent(KeypadEvent key){
switch (kpd.getState()){

case PRESSED:
    if (key == '#') {     

        write();

  }
 break;
case RELEASED:
        if (key == '#') {

          delay(50);
          digitalWrite(ledPin, LOW);
          delay(50);
          digitalWrite(ledPin, HIGH);
          delay(50);
          digitalWrite(ledPin, LOW);
          delay(50);
          digitalWrite(ledPin, HIGH);
          delay(50);
          digitalWrite(ledPin, LOW);
          delay(50);
          client.stop();
          time = 0;
          code =" ";

          Serial.println("Radio Off"); 
          radio.powerDown();              
          Serial.println("Sleeping"); 
          goToSleep();

    }
    break;



}

}
void write(){

Serial.println(F("connecting"));
IPAddress central(10,0,0,1);
if (client.connect(central, 8000)) {
    Serial.println(F("connected"));
    // Make an HTTP request:
    String path = "GET /0/?voltage="+ voltagestr + "&code="+ code + "&ip=10.0.0.20" + " HTTP/1.1\n";
    char __path[path.length() + 1];
    path.toCharArray(__path,sizeof(__path));

    client.write(__path);

    client.write("Connection: close\n\n");   

}else{
      // if you didn't get a connection to the server:
     Serial.println(F("connection failed"));


    }

}

RF24Ethernet violates GPL V3

I see your library contains an substancial amount of code taken from my work on UIPEthernet (https://github.com/ntruchsess/arduino_uip).
This by itself is totally fine - actually I think it's great you use my code to support totally different hardware. This is what open source is about.

But UIPEthernet is licensed as GPL V3 (http://www.gnu.org/licenses/gpl-3.0.en.html). Some of the files in RF24Ethernet being based on UIPEthernet do not contain any Copyright or licence information which is not compliant with GPL V3 chapter 5:

a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.

compilation error on sample SLIP_InteractiveServer

Hi, I have a compilation error on sample SLIP_InteractiveServer

SLIP_InteractiveServer:44: error: no matching function for call to 'RF24EthernetClass::RF24EthernetClass(RF24&, RF24Network&)'
SLIP_InteractiveServer.ino:44:46: note: candidates are:
In file included from SLIP_InteractiveServer.ino:34:0:
C:\Users\ancattaneo\Documents\Arduino\libraries\RF24Ethernet/RF24Ethernet.h:105:3: note: RF24EthernetClass::RF24EthernetClass()
RF24EthernetClass();

RF24Network is development version

Bye Andrea

Endianess issue on STM32 nodes

I opened an issue over at RF24Gateway (link) that belongs here.
Using RF24Ethernet on STM32duino the bytes if the IP adresses are swapped pairwise. I thought about this a bit and have a solution to propose:
In RF24Ethernet the following code converts the IP into the uip style:

 #define uip_ip_addr(addr, ip) do { \
                      ((u16_t *)(addr))[0] = HTONS(((ip[0]) << 8) | (ip[1])); \
                      ((u16_t *)(addr))[1] = HTONS(((ip[2]) << 8) | (ip[3])); \
                   } while(0)

The HTONS macro is used to convert endianess, but I believe it is actually not necessary to do so: uIP expects the IP as it shows up in an IP header. This order is always the same and can always be constructed the same way from IPadress, since this class is based on a uint8_t[4] array, so the order is fixed. Endianess shouldn't play any roll there.

The proposed solution would be:

#define uip_ip_addr(addr, ip) do { \
                     memcpy(addr, &ip[0], 4); \
                  } while(0)

This works on both the Arduino nano and the STM32 for me. Now, some might argue that memcpy is too blown up, but it actually compiles the arduino code to a smaller size than before. The compiler might even further optimize this, if appropriate:
https://godbolt.org/z/nd8T3KEsb

None of the arduino example sketches connect to gateway

Hello. I've spent the evening reading the docs, checking your youtube videos and reading the comments in the arduino sketches to check if I've been missing something but I just can't get the RF24Ethernet examples to connect to a RF24Gateway running on a raspberry pi.

The sketches compile and upload fine, but they don't register with the gateway (nothing shows up on 'Mesh Info') and it only outputs 'start' to the serial monitor. The interesting thing is that If I use of one the RF24Mesh examples the arduino node shows up on the gateway list.

Missing Definitions in RF24Ethernet_config.h

Hi!
I'm using Arduino UNO (Tested on IDE 1.5.8 and 1.6.3) and when I try to upload the Getting_Started_SimpleClient_Mesh.ino I get the following error:

In file included from C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/RF24Ethernet.h:20:0,
                 from Getting_Started_SimpleClient_Mesh.ino:23:
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/uip-conf.h:81:34: error: 'MAX_PAYLOAD_SIZE' was not declared in this scope
 #define UIP_CONF_BUFFER_SIZE     MAX_PAYLOAD_SIZE
                                  ^
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/uip-conf.h:156:30: note: in expansion of macro 'UIP_CONF_BUFFER_SIZE'
   #define OUTPUT_BUFFER_SIZE UIP_CONF_BUFFER_SIZE - UIP_CONF_LLH_LEN - UIP_TCPIP_HLEN
                              ^
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/RF24Client.h:49:17: note: in expansion of macro 'OUTPUT_BUFFER_SIZE'
  uint8_t myData[OUTPUT_BUFFER_SIZE];
                 ^
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/uip-conf.h:81:34: error: 'MAX_PAYLOAD_SIZE' was not declared in this scope
 #define UIP_CONF_BUFFER_SIZE     MAX_PAYLOAD_SIZE
                                  ^
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/uip-conf.h:156:30: note: in expansion of macro 'UIP_CONF_BUFFER_SIZE'
   #define OUTPUT_BUFFER_SIZE UIP_CONF_BUFFER_SIZE - UIP_CONF_LLH_LEN - UIP_TCPIP_HLEN
                              ^
C:\Users\Giovanni\Documents\Arduino\libraries\RF24Ethernet/RF24Client.h:50:19: note: in expansion of macro 'OUTPUT_BUFFER_SIZE'
  uint8_t myDataIn[OUTPUT_BUFFER_SIZE]; 
                   ^

So I opened the RF24Ethernet_config.h (referenced in uip-conf.h) and the is no
#define DISABLE_USER_PAYLOADS or #define MAX_PAYLOAD_SIZE and other #defines.

There is something wrong!

deploy documentation using Github Pages

This issue is part of an effort to start hosting nRF24 org repos' docs on github per individual repo instead of uploading all RF24* lib's docs to tmrh20.github.io.

I've created a github workflow that builds the docs on every commit. This same workflow will upload the generated HTML files to the "gh-pages" branch upon publishing a new release. Notice I've already taken the liberty to create the "gh-pages" branch for this repo.

  1. For this workflow to work properly, this repo's settings needs to have the "gh-pages" branch set to the Github Pages Source option:
    image
    After enabling this option, I expect the first deployment to Github Pages to render an error message.

  2. Additionally, it would less visually noisy if the "packages" & "environments" sections are hidden in the repo's sidebar settings:
    image

When these stipulations have been met in the repo settings I will submit a PR

Conflicting header inclusion timer

Hi,
Thanks for the awesome library.

Currently compiling the RF24Ethernet for BluePill in PlatformIO cause conflicting inclusion.
Both stm32duino & RF24Ethernet have timer.h. Since Arduino IDE & PlatformIO have different inclusion order, Compiling the library in PlatformIO project cause error.
Already the only known workaround is to fork the library, fix the file names and use the forked library in PlatformIO project.

Thanks

Development - Corrupted message_buffer issue during fragmented packet duplicate disposal

I discoverd an issue on Arduino where a duplicate fragmented packet will corrupt the message_buffer. I have an RF24 node that sends out a message to the base when it comes online. Because of this the RF24NetworkHeader::id will always be the same: 2. The message is always the same too. If I reset the node a few times without sending out any additional fragmented messages the BASE will keep dropping the message. The problem is that something gets messed up with the message_buffer and a portion of each message gets appended to the original each time until the BASE is restarted. Here's an example:

1st:  Payload: rf24/5/online^node 5 online
2nd:  Payload: rf24/5/online^node 5 onlineine
3rd:  Payload: rf24/5/online^node 5 onlineineine
4th:  Payload: rf24/5/online^node 5 onlineineineine

If I split up the if statement and comment out this part at line 422 in RF24Network.cpp the issue goes away but I know the real bug is elsewhere. I just haven't tracked it down yet.

(frag_queue.header.id == header->id && frag_queue.header.from_node == header->from_node)

Problem with TCP ZeroWindow

Hi,

I have a strange problem with ... actually I am not sure. I use PubSub library to access MQTT broker with RF24Ethernet bellow. From time to time publish() returns false, but actually data is published. I went through PubSub implementation and i noticed that on "failed" cases ethernet client write() returns different size than size of data prepared to transfer over that client (line 462 of PubSubClient.cpp):
rc = _client->write(buf+(4-llen),length+1+llen);
I printed out the returned values and the size of buffer to write and it looks like in error cases rc is equal to size of currently sending buffer + size of previously sent buffer. An example:

Publish attempt 1 		raw/sensor/ardClient1/temperature
rc=41
bufsize=41
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/humidity
rc=79
bufsize=38
Failed to publish		connected
Publish attempt 2 		raw/sensor/ardClient1/humidity
rc=38
bufsize=38
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/voltage
rc=75
bufsize=37
Failed to publish		connected
Publish attempt 2 		raw/sensor/ardClient1/voltage
rc=37
bufsize=37
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/temperature
rc=41
bufsize=41
Success				connected
----

As a next step I did a TCP dump from tun interface where my Arduino is connected to (I use RF24Gateway) and there is a correlation between failed publish() and TCP ACK for MQTT PING RESPONSE sent from broker:

...
"15","17.495376","10.10.3.30","10.10.3.13","MQTT","71","Ping Request, Publish Message"
"16","17.496005","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=1 Ack=244 Win=28859 Len=0"
"17","17.496099","10.10.3.13","10.10.3.30","MQTT","42","Ping Response"
"18","17.519380","10.10.3.30","10.10.3.13","TCP","40","[TCP ZeroWindow] 1025 → 1883 [ACK] Seq=244 Ack=3 Win=0 Len=0"
"19","17.815883","10.10.3.30","10.10.3.13","MQTT","69","[TCP ZeroWindow] , Publish Message"
"20","17.856177","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=3 Ack=273 Win=28830 Len=0"
...

10.10.3.30 is my Arduino. TCP Zero Window means "give me a break" so for some reason Arduino is overloaded. From wireshark wiki:

This means that a client is not able to receive further information at the moment, and the TCP transmission is halted until it can process the information in its receive buffer.

Similar situation happens when broker sends Publish to my Arduino:

...
"75","63.738718","10.10.3.13","10.10.3.30","MQTT","73","Publish Message"
"76","63.957258","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"77","64.396158","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"78","65.274099","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"79","66.741943","10.10.3.30","10.10.3.13","MQTT","69","Publish Message"
"80","66.742495","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=40 Ack=1055 Win=28048 Len=0"
"81","67.031025","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1055 Win=28048 Len=33"
"82","67.090560","10.10.3.30","10.10.3.13","MQTT","69","Publish Message"
"83","67.091067","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=40 Ack=1084 Win=28019 Len=0"
"84","67.125260","10.10.3.30","10.10.3.13","TCP","40","[TCP ZeroWindow] 1025 → 1883 [ACK] Seq=1055 Ack=40 Win=0 Len=0"
"85","67.125746","10.10.3.13","10.10.3.30","TCP","40","[TCP Dup ACK 83#1] 1883 → 1025 [ACK] Seq=40 Ack=1084 Win=28019 Len=0"
"86","67.371144","10.10.3.30","10.10.3.13","MQTT","76","Publish Ack, Publish Message"
..

Ok, I understand that some retransmissions may occur due to a sleep/delay in my code. But when frame 75 is ACK in frame 84 again it seems that Arduino TCP window == 0.

Any idea what's going on here and what can be the reason? How to debug it further?

Here is a link to the implementation:
https://bitbucket.org/elvisPA/radiosensornet/raw/9a888cb7845406e0efd82b561870cebe471ca9ff/arduinoSensorFirmware/client.ino

Possible comparison typo in RF24Client.cpp

I was browsing the code and came across this little tidbit:

bool RF24Client::operator==(const RF24Client& rhs) { return data && rhs.data && (data = rhs.data); }

I think perhaps it should be data == rhs.data, or is the assignment intentional?

Communication Issue between SLIP_InteractiveServer and SLIP_Gateway

I am using the latest code downloaded from GitHub. I have very little nRF24 experience and using the libraries to learn. I successfully covered all the examples over the last few weeks up to the RF24Ethernet SLIP_InteractiveServer and SLIP_Gateway. I have made no code changes to the examples, except put a radio.printDetails() in the code to show the configuration. From the documentation it seems the problem is RX_ADDR_P0-1 in the SLIP_InteractiveServer code. I ask your assistance to help correct the addresses.
RF24Ethernet SLIP_InteractiveServer:
image
RF24Ethernet SLIP_Gateway:
image

/*
 * RF24Ethernet Webserver controlling an LED example *
 *
 * **NOTE: This example demonstrates usage the SLIP_Gateway
 *   When using SLIP, there are 3 main differences:
 *    1. The RF24Mesh layer must be used to provide MAC/IP translation
 *    2. The specified RF24Mesh nodeID must be the same as the last octet of the IP
 *        ie: IP: 192.168.1.2  NodeId must be 2
 *
 *    3. The RF24Ethernet library must be configured for TUN
 *       a: Open the uip_conf.h file, make sure to #define UIP_CONF_LLH_LEN 0
 *
 * The following commands must be run on the Linux device to enable slip
 * 1. Connect your Arduino
 * 2. On RPi, cd /dev
 * 3. Type 'ls' and look for a new device ttyUSB<X> where <X> is a number
 * 4. Run   sudo modprobe slip
 * 5. Run   sudo slattach -L -s 115200 -p slip /dev/ttyUSB<X> &
 * 6. Run   sudo ifconfig s<X> 10.10.3.1 dstaddr 10.10.3.2
 * 7. Run   sudo route add -net 10.10.3.0/24 gw 10.10.3.1
 
 * RF24Ethernet uses the uIP stack by Adam Dunkels <[email protected]>
 *
 * This example demonstrates how to configure a sensor node to act as a webserver and
 * allows a user to control a connected LED by clicking links on the webpage
 * The requested URL is used as input, to determine whether to turn the LED off or on
 */


#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <printf.h>
#include <RF24Ethernet.h>
#include "HTML.h"

// Include RF24Mesh and the EEPROM libs
#include "RF24Mesh.h"
#include "EEPROM.h"

/*** Configure the radio CE & CS pins ***/
RF24 radio(7,8);
RF24Network network(radio);
RF24Mesh mesh(radio,network);
RF24EthernetClass RF24Ethernet(radio,network,mesh);

#define LED_PIN A3 //Analog pin A3

// Configure the server to listen on port 1000
EthernetServer server = EthernetServer(1000);

/**********************************************************/

void setup() {
  // Set up the speed of our serial link.
  Serial.begin(115200);
  printf_begin();
  Serial.println("start");
  pinMode(LED_PIN, OUTPUT);


  // This step is very important. When using TUN or SLIP, the IP of the device
  // must be configured as the NodeID in the RF24Mesh layer
  
  mesh.setNodeID(2);
  mesh.begin();

  //Optional
  radio.printDetails();

  // Set the IP address we'll be using.  Make sure this doesn't conflict with
  // any IP addresses or subnets on your LAN or you won't be able to connect to
  // either the Arduino or your LAN...
  
  // NOTE: The last octet/last digit of the IP must match the RF24Mesh nodeID above
  IPAddress myIP(10, 10, 3, 2);
  Ethernet.begin(myIP);

  // If you'll be making outgoing connections from the Arduino to the rest of
  // the world, you'll need a gateway set up.
  IPAddress gwIP(10, 10, 3, 1);
  Ethernet.set_gateway(gwIP);

  // Listen for incoming connections on TCP port 1000.
  server.begin();
  
}


/********************************************************/

uint32_t mesh_timer = 0;

void loop() {

  // This is the last of the differences between this and the regular Interactive Server example
  // If the master node is completely down, and unresponsive for 30 seconds, renew the address
  
  if(millis()-mesh_timer > 30000){ //Every 30 seconds, test mesh connectivity
  
    mesh_timer = millis();
    
    if( ! mesh.checkConnection() ){
        //refresh the network address        
        mesh.renewAddress();
      
     }
  }
  
  size_t size;

  if (EthernetClient client = server.available())
  {
    uint8_t pageReq = 0;
    generate_tcp_stats();
    while ((size = client.available()) > 0)
    {
      // If a request is received with enough characters, search for the / character
      if (size >= 7) {
        char slash[] = {"/"};
        client.findUntil(slash, slash);
        char buf[3] = {"  "};
        buf[0] = client.read();  // Read in the first two characters from the request
        buf[1] = client.read();

        if (strcmp(buf, "ON") == 0) { // If the user requested http://ip-of-node:1000/ON
          led_state = 1;
          pageReq = 1;
          digitalWrite(LED_PIN, led_state);
          
        }else if (strcmp(buf, "OF") == 0) { // If the user requested http://ip-of-node:1000/OF
          led_state = 0;
          pageReq = 1;
          digitalWrite(LED_PIN, led_state);
          
        }else if (strcmp(buf, "ST") == 0) { // If the user requested http://ip-of-node:1000/OF
          pageReq = 2;
          
        }else if (strcmp(buf, "CR") == 0) { // If the user requested http://ip-of-node:1000/OF
          pageReq = 3;
          
        }else if(buf[0] == ' '){
          pageReq = 4; 
        }
      }
      // Empty the rest of the data from the client
      while (client.waitAvailable()) {
        client.read();
      }
    }
    
    /**
    * Based on the incoming URL request, send the correct page to the client
    * see HTML.h
    */
    switch(pageReq){
       case 2: stats_page(client); break;
       case 3: credits_page(client); break;
       case 4: main_page(client); break;
       case 1: main_page(client); break;
       default: break; 
    }    

    client.stop();
    Serial.println(F("********"));

  }

  // We can do other things in the loop, but be aware that the loop will
  // briefly pause while IP data is being processed.

  int save_led_state = led_state;
  
  for(int i=0; i<10; i++){
    digitalWrite(LED_PIN, 1);
    delay(50);
    digitalWrite(LED_PIN, 0);
    delay(50);
    }
    
  digitalWrite(LED_PIN, save_led_state);  

}

/**
* This section displays some basic connection stats via Serial and demonstrates
* how to interact directly with the uIP TCP/IP stack
* See the uIP documentation for more info
*/
static unsigned short generate_tcp_stats()
{
  struct uip_conn *conn;

  // If multiple connections are enabled, get info for each active connection
  for (uint8_t i = 0; i < UIP_CONF_MAX_CONNECTIONS; i++) {
    conn = &uip_conns[i];

    // If there is an open connection to one of the listening ports, print the info
    // This logic seems to be backwards?
    if (uip_stopped(conn)) {
      Serial.print(F("Connection no "));
      Serial.println(i);
      Serial.print(F("Local Port "));
      Serial.println(htons(conn->lport));
      Serial.print(F("Remote IP/Port "));
      Serial.print(htons(conn->ripaddr[0]) >> 8);
      Serial.print(F("."));
      Serial.print(htons(conn->ripaddr[0]) & 0xff);
      Serial.print(F("."));
      Serial.print(htons(conn->ripaddr[1]) >> 8);
      Serial.print(F("."));
      Serial.print(htons(conn->ripaddr[1]) & 0xff);
      Serial.print(F(":"));
      Serial.println(htons(conn->rport));
      Serial.print(F("Outstanding "));
      Serial.println((uip_outstanding(conn)) ? '*' : ' ');

    }
  }
  return 1;
}

Joining nrf module to esp wifi network

Hi,
I quite did not understand the purpose of RF24Ethernet library. With this can I directly communicate between a nrf module and a esp 8266.
Currently I have arduino+nrf at one side, and at the other end I have esp8266+nrf. This works :). I am using RF24Mesh library in order to achieve this. Can I just remove the nrf at the esp end, and join the esp created network (esp soft ap mode) from the arduino+nrf24l01 setup using the RF24Ethernet library?
Thanks,
Debojit

Update Examples

First of all I want to thank you for the library ideea, but, I can't test it on Arduino.

Running Getting Starting Simple server (or other sketches) I encounter this error:
Arduino\libraries\RF24Ethernet\RF24Client.cpp:184: error: 'EXTERNAL_DATA_TYPE' was not declared in this scope

I tried to bypass this defining it, but the next error appeared.

Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp:67: error: 'class RF24Network' has no member named 'multicastRelay'
C:\Users\George\Documents\Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp: In static member function 'static void RF24EthernetClass::tick()':
C:\Users\George\Documents\Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp:206: error: void value not ignored as it ought to be
C:\Users\George\Documents\Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp:207: error: 'RF24NetworkFrame' was not declared in this scope
C:\Users\George\Documents\Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp:207: error: 'frame' was not declared in this scope
C:\Users\George\Documents\Arduino\libraries\RF24Ethernet\RF24Ethernet.cpp:207: error: 'class RF24Network' has no member named 'frag_ptr'

Best Regards,
George Calugar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.