fd
Dependents: xtoff3 CYS_Receiver
Fork of RF24Network by
RF24Network.h@2:a5f8e04bd02b, 2015-11-05 (annotated)
- Committer:
- akashvibhute
- Date:
- Thu Nov 05 05:40:44 2015 +0000
- Revision:
- 2:a5f8e04bd02b
- Parent:
- 0:c3db0798d9aa
- Child:
- 3:dfc8da7ac18c
Updated with TMRh20's RF24 library on Nov/04/2015 from https://github.com/TMRh20; Porting completed on Nov/05/2015
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
akashvibhute | 0:c3db0798d9aa | 1 | /* |
akashvibhute | 0:c3db0798d9aa | 2 | Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com> |
akashvibhute | 0:c3db0798d9aa | 3 | |
akashvibhute | 0:c3db0798d9aa | 4 | This program is free software; you can redistribute it and/or |
akashvibhute | 0:c3db0798d9aa | 5 | modify it under the terms of the GNU General Public License |
akashvibhute | 0:c3db0798d9aa | 6 | version 2 as published by the Free Software Foundation. |
akashvibhute | 0:c3db0798d9aa | 7 | */ |
akashvibhute | 0:c3db0798d9aa | 8 | |
akashvibhute | 0:c3db0798d9aa | 9 | #ifndef __RF24NETWORK_H__ |
akashvibhute | 0:c3db0798d9aa | 10 | #define __RF24NETWORK_H__ |
akashvibhute | 0:c3db0798d9aa | 11 | |
akashvibhute | 0:c3db0798d9aa | 12 | /** |
akashvibhute | 0:c3db0798d9aa | 13 | * @file RF24Network.h |
akashvibhute | 0:c3db0798d9aa | 14 | * |
akashvibhute | 0:c3db0798d9aa | 15 | * Class declaration for RF24Network |
akashvibhute | 0:c3db0798d9aa | 16 | */ |
akashvibhute | 2:a5f8e04bd02b | 17 | #define min(a,b) (a<b?a:b) |
akashvibhute | 0:c3db0798d9aa | 18 | #include <stddef.h> |
akashvibhute | 0:c3db0798d9aa | 19 | #include <stdint.h> |
akashvibhute | 2:a5f8e04bd02b | 20 | #include "RF24Network_config.h" |
akashvibhute | 2:a5f8e04bd02b | 21 | |
akashvibhute | 2:a5f8e04bd02b | 22 | |
akashvibhute | 2:a5f8e04bd02b | 23 | |
akashvibhute | 2:a5f8e04bd02b | 24 | |
akashvibhute | 2:a5f8e04bd02b | 25 | |
akashvibhute | 2:a5f8e04bd02b | 26 | |
akashvibhute | 2:a5f8e04bd02b | 27 | |
akashvibhute | 2:a5f8e04bd02b | 28 | |
akashvibhute | 2:a5f8e04bd02b | 29 | |
akashvibhute | 2:a5f8e04bd02b | 30 | |
akashvibhute | 2:a5f8e04bd02b | 31 | |
akashvibhute | 2:a5f8e04bd02b | 32 | |
akashvibhute | 2:a5f8e04bd02b | 33 | |
akashvibhute | 2:a5f8e04bd02b | 34 | |
akashvibhute | 2:a5f8e04bd02b | 35 | |
akashvibhute | 2:a5f8e04bd02b | 36 | |
akashvibhute | 2:a5f8e04bd02b | 37 | |
akashvibhute | 2:a5f8e04bd02b | 38 | |
akashvibhute | 2:a5f8e04bd02b | 39 | |
akashvibhute | 2:a5f8e04bd02b | 40 | |
akashvibhute | 2:a5f8e04bd02b | 41 | /* Header types range */ |
akashvibhute | 2:a5f8e04bd02b | 42 | #define MIN_USER_DEFINED_HEADER_TYPE 0 |
akashvibhute | 2:a5f8e04bd02b | 43 | #define MAX_USER_DEFINED_HEADER_TYPE 127 |
akashvibhute | 2:a5f8e04bd02b | 44 | |
akashvibhute | 2:a5f8e04bd02b | 45 | /** |
akashvibhute | 2:a5f8e04bd02b | 46 | |
akashvibhute | 2:a5f8e04bd02b | 47 | */ |
akashvibhute | 2:a5f8e04bd02b | 48 | |
akashvibhute | 2:a5f8e04bd02b | 49 | // ACK Response Types |
akashvibhute | 2:a5f8e04bd02b | 50 | /** |
akashvibhute | 2:a5f8e04bd02b | 51 | * **Reserved network message types** |
akashvibhute | 2:a5f8e04bd02b | 52 | * |
akashvibhute | 2:a5f8e04bd02b | 53 | * The network will determine whether to automatically acknowledge payloads based on their general type <br> |
akashvibhute | 2:a5f8e04bd02b | 54 | * |
akashvibhute | 2:a5f8e04bd02b | 55 | * **User types** (1-127) 1-64 will NOT be acknowledged <br> |
akashvibhute | 2:a5f8e04bd02b | 56 | * **System types** (128-255) 192 through 255 will NOT be acknowledged<br> |
akashvibhute | 2:a5f8e04bd02b | 57 | * |
akashvibhute | 2:a5f8e04bd02b | 58 | * @defgroup DEFINED_TYPES Reserved System Message Types |
akashvibhute | 2:a5f8e04bd02b | 59 | * |
akashvibhute | 2:a5f8e04bd02b | 60 | * System types can also contain message data. |
akashvibhute | 2:a5f8e04bd02b | 61 | * |
akashvibhute | 2:a5f8e04bd02b | 62 | * @{ |
akashvibhute | 2:a5f8e04bd02b | 63 | */ |
akashvibhute | 2:a5f8e04bd02b | 64 | |
akashvibhute | 2:a5f8e04bd02b | 65 | /** |
akashvibhute | 2:a5f8e04bd02b | 66 | * A NETWORK_ADDR_RESPONSE type is utilized to manually route custom messages containing a single RF24Network address |
akashvibhute | 2:a5f8e04bd02b | 67 | * |
akashvibhute | 2:a5f8e04bd02b | 68 | * Used by RF24Mesh |
akashvibhute | 2:a5f8e04bd02b | 69 | * |
akashvibhute | 2:a5f8e04bd02b | 70 | * If a node receives a message of this type that is directly addressed to it, it will read the included message, and forward the payload |
akashvibhute | 2:a5f8e04bd02b | 71 | * on to the proper recipient. <br> |
akashvibhute | 2:a5f8e04bd02b | 72 | * This allows nodes to forward multicast messages to the master node, receive a response, and forward it back to the requester. |
akashvibhute | 2:a5f8e04bd02b | 73 | */ |
akashvibhute | 2:a5f8e04bd02b | 74 | #define NETWORK_ADDR_RESPONSE 128 |
akashvibhute | 2:a5f8e04bd02b | 75 | //#define NETWORK_ADDR_CONFIRM 129 |
akashvibhute | 2:a5f8e04bd02b | 76 | |
akashvibhute | 2:a5f8e04bd02b | 77 | /** |
akashvibhute | 2:a5f8e04bd02b | 78 | * Messages of type NETWORK_PING will be dropped automatically by the recipient. A NETWORK_ACK or automatic radio-ack will indicate to the sender whether the |
akashvibhute | 2:a5f8e04bd02b | 79 | * payload was successful. The time it takes to successfully send a NETWORK_PING is the round-trip-time. |
akashvibhute | 2:a5f8e04bd02b | 80 | */ |
akashvibhute | 2:a5f8e04bd02b | 81 | #define NETWORK_PING 130 |
akashvibhute | 2:a5f8e04bd02b | 82 | |
akashvibhute | 2:a5f8e04bd02b | 83 | /** |
akashvibhute | 2:a5f8e04bd02b | 84 | * External data types are used to define messages that will be passed to an external data system. This allows RF24Network to route and pass any type of data, such |
akashvibhute | 2:a5f8e04bd02b | 85 | * as TCP/IP frames, while still being able to utilize standard RF24Network messages etc. |
akashvibhute | 2:a5f8e04bd02b | 86 | * |
akashvibhute | 2:a5f8e04bd02b | 87 | * **Linux** |
akashvibhute | 2:a5f8e04bd02b | 88 | * Linux devices (defined RF24_LINUX) will buffer all data types in the user cache. |
akashvibhute | 2:a5f8e04bd02b | 89 | * |
akashvibhute | 2:a5f8e04bd02b | 90 | * **Arduino/AVR/Etc:** Data transmitted with the type set to EXTERNAL_DATA_TYPE will not be loaded into the user cache. <br> |
akashvibhute | 2:a5f8e04bd02b | 91 | * External systems can extract external data using the following process, while internal data types are cached in the user buffer, and accessed using network.read() : |
akashvibhute | 2:a5f8e04bd02b | 92 | * @code |
akashvibhute | 2:a5f8e04bd02b | 93 | * uint8_t return_type = network.update(); |
akashvibhute | 2:a5f8e04bd02b | 94 | * if(return_type == EXTERNAL_DATA_TYPE){ |
akashvibhute | 2:a5f8e04bd02b | 95 | * uint16_t size = network.frag_ptr->message_size; |
akashvibhute | 2:a5f8e04bd02b | 96 | * memcpy(&myDataBuffer,network.frag_ptr->message_buffer,network.frag_ptr->message_size); |
akashvibhute | 2:a5f8e04bd02b | 97 | * } |
akashvibhute | 2:a5f8e04bd02b | 98 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 99 | */ |
akashvibhute | 2:a5f8e04bd02b | 100 | #define EXTERNAL_DATA_TYPE 131 |
akashvibhute | 2:a5f8e04bd02b | 101 | |
akashvibhute | 2:a5f8e04bd02b | 102 | /** |
akashvibhute | 2:a5f8e04bd02b | 103 | * Messages of this type designate the first of two or more message fragments, and will be re-assembled automatically. |
akashvibhute | 2:a5f8e04bd02b | 104 | */ |
akashvibhute | 2:a5f8e04bd02b | 105 | #define NETWORK_FIRST_FRAGMENT 148 |
akashvibhute | 2:a5f8e04bd02b | 106 | |
akashvibhute | 2:a5f8e04bd02b | 107 | /** |
akashvibhute | 2:a5f8e04bd02b | 108 | * Messages of this type indicate a fragmented payload with two or more message fragments. |
akashvibhute | 2:a5f8e04bd02b | 109 | */ |
akashvibhute | 2:a5f8e04bd02b | 110 | #define NETWORK_MORE_FRAGMENTS 149 |
akashvibhute | 2:a5f8e04bd02b | 111 | |
akashvibhute | 2:a5f8e04bd02b | 112 | /** |
akashvibhute | 2:a5f8e04bd02b | 113 | * Messages of this type indicate the last fragment in a sequence of message fragments. |
akashvibhute | 2:a5f8e04bd02b | 114 | * Messages of this type do not receive a NETWORK_ACK |
akashvibhute | 2:a5f8e04bd02b | 115 | */ |
akashvibhute | 2:a5f8e04bd02b | 116 | #define NETWORK_LAST_FRAGMENT 150 |
akashvibhute | 2:a5f8e04bd02b | 117 | //#define NETWORK_LAST_FRAGMENT 201 |
akashvibhute | 2:a5f8e04bd02b | 118 | |
akashvibhute | 2:a5f8e04bd02b | 119 | // NO ACK Response Types |
akashvibhute | 2:a5f8e04bd02b | 120 | //#define NETWORK_ACK_REQUEST 192 |
akashvibhute | 2:a5f8e04bd02b | 121 | |
akashvibhute | 2:a5f8e04bd02b | 122 | /** |
akashvibhute | 2:a5f8e04bd02b | 123 | * Messages of this type are used internally, to signal the sender that a transmission has been completed. |
akashvibhute | 2:a5f8e04bd02b | 124 | * RF24Network does not directly have a built-in transport layer protocol, so message delivery is not 100% guaranteed.<br> |
akashvibhute | 2:a5f8e04bd02b | 125 | * Messages can be lost via corrupted dynamic payloads, or a NETWORK_ACK can fail, while the message was actually successful. |
akashvibhute | 2:a5f8e04bd02b | 126 | * |
akashvibhute | 2:a5f8e04bd02b | 127 | * NETWORK_ACK messages can be utilized as a traffic/flow control mechanism, since transmitting nodes will be forced to wait until |
akashvibhute | 2:a5f8e04bd02b | 128 | * the payload is transmitted across the network and acknowledged, before sending additional data. |
akashvibhute | 2:a5f8e04bd02b | 129 | * |
akashvibhute | 2:a5f8e04bd02b | 130 | * In the event that the transmitting device will be waiting for a direct response, manually sent by the recipient, a NETWORK_ACK is not required. <br> |
akashvibhute | 2:a5f8e04bd02b | 131 | * User messages utilizing a 'type' with a decimal value of 64 or less will not be acknowledged across the network via NETWORK_ACK messages. |
akashvibhute | 2:a5f8e04bd02b | 132 | */ |
akashvibhute | 2:a5f8e04bd02b | 133 | #define NETWORK_ACK 193 |
akashvibhute | 2:a5f8e04bd02b | 134 | |
akashvibhute | 2:a5f8e04bd02b | 135 | /** |
akashvibhute | 2:a5f8e04bd02b | 136 | * Used by RF24Mesh |
akashvibhute | 2:a5f8e04bd02b | 137 | * |
akashvibhute | 2:a5f8e04bd02b | 138 | * Messages of this type are used with multi-casting , to find active/available nodes. |
akashvibhute | 2:a5f8e04bd02b | 139 | * Any node receiving a NETWORK_POLL sent to a multicast address will respond directly to the sender with a blank message, indicating the |
akashvibhute | 2:a5f8e04bd02b | 140 | * address of the available node via the header. |
akashvibhute | 2:a5f8e04bd02b | 141 | */ |
akashvibhute | 2:a5f8e04bd02b | 142 | #define NETWORK_POLL 194 |
akashvibhute | 2:a5f8e04bd02b | 143 | |
akashvibhute | 2:a5f8e04bd02b | 144 | /** |
akashvibhute | 2:a5f8e04bd02b | 145 | * Used by RF24Mesh |
akashvibhute | 2:a5f8e04bd02b | 146 | * |
akashvibhute | 2:a5f8e04bd02b | 147 | * Messages of this type are used to request information from the master node, generally via a unicast (direct) write. |
akashvibhute | 2:a5f8e04bd02b | 148 | * Any (non-master) node receiving a message of this type will manually forward it to the master node using an normal network write. |
akashvibhute | 2:a5f8e04bd02b | 149 | */ |
akashvibhute | 2:a5f8e04bd02b | 150 | #define NETWORK_REQ_ADDRESS 195 |
akashvibhute | 2:a5f8e04bd02b | 151 | //#define NETWORK_ADDR_LOOKUP 196 |
akashvibhute | 2:a5f8e04bd02b | 152 | //#define NETWORK_ADDR_RELEASE 197 |
akashvibhute | 2:a5f8e04bd02b | 153 | /** @} */ |
akashvibhute | 2:a5f8e04bd02b | 154 | |
akashvibhute | 2:a5f8e04bd02b | 155 | #define NETWORK_MORE_FRAGMENTS_NACK 200 |
akashvibhute | 2:a5f8e04bd02b | 156 | |
akashvibhute | 2:a5f8e04bd02b | 157 | |
akashvibhute | 2:a5f8e04bd02b | 158 | /** Internal defines for handling written payloads */ |
akashvibhute | 2:a5f8e04bd02b | 159 | #define TX_NORMAL 0 |
akashvibhute | 2:a5f8e04bd02b | 160 | #define TX_ROUTED 1 |
akashvibhute | 2:a5f8e04bd02b | 161 | #define USER_TX_TO_PHYSICAL_ADDRESS 2 //no network ACK |
akashvibhute | 2:a5f8e04bd02b | 162 | #define USER_TX_TO_LOGICAL_ADDRESS 3 // network ACK |
akashvibhute | 2:a5f8e04bd02b | 163 | #define USER_TX_MULTICAST 4 |
akashvibhute | 2:a5f8e04bd02b | 164 | |
akashvibhute | 2:a5f8e04bd02b | 165 | #define MAX_FRAME_SIZE 32 //Size of individual radio frames |
akashvibhute | 2:a5f8e04bd02b | 166 | #define FRAME_HEADER_SIZE 10 //Size of RF24Network frames - data |
akashvibhute | 2:a5f8e04bd02b | 167 | |
akashvibhute | 2:a5f8e04bd02b | 168 | #define USE_CURRENT_CHANNEL 255 // Use current radio channel when setting up the network |
akashvibhute | 2:a5f8e04bd02b | 169 | |
akashvibhute | 2:a5f8e04bd02b | 170 | /** Internal defines for handling internal payloads - prevents reading additional data from the radio |
akashvibhute | 2:a5f8e04bd02b | 171 | * when buffers are full */ |
akashvibhute | 2:a5f8e04bd02b | 172 | #define FLAG_HOLD_INCOMING 1 |
akashvibhute | 2:a5f8e04bd02b | 173 | /** FLAG_BYPASS_HOLDS is mainly for use with RF24Mesh as follows: |
akashvibhute | 2:a5f8e04bd02b | 174 | * a: Ensure no data in radio buffers, else exit |
akashvibhute | 2:a5f8e04bd02b | 175 | * b: Address is changed to multicast address for renewal |
akashvibhute | 2:a5f8e04bd02b | 176 | * c: Holds Cleared (bypass flag is set) |
akashvibhute | 2:a5f8e04bd02b | 177 | * d: Address renewal takes place and is set |
akashvibhute | 2:a5f8e04bd02b | 178 | * e: Holds Enabled (bypass flag off) |
akashvibhute | 2:a5f8e04bd02b | 179 | */ |
akashvibhute | 2:a5f8e04bd02b | 180 | #define FLAG_BYPASS_HOLDS 2 |
akashvibhute | 2:a5f8e04bd02b | 181 | |
akashvibhute | 2:a5f8e04bd02b | 182 | #define FLAG_FAST_FRAG 4 |
akashvibhute | 0:c3db0798d9aa | 183 | |
akashvibhute | 0:c3db0798d9aa | 184 | class RF24; |
akashvibhute | 0:c3db0798d9aa | 185 | |
akashvibhute | 0:c3db0798d9aa | 186 | /** |
akashvibhute | 0:c3db0798d9aa | 187 | * Header which is sent with each message |
akashvibhute | 0:c3db0798d9aa | 188 | * |
akashvibhute | 0:c3db0798d9aa | 189 | * The frame put over the air consists of this header and a message |
akashvibhute | 2:a5f8e04bd02b | 190 | * |
akashvibhute | 2:a5f8e04bd02b | 191 | * Headers are addressed to the appropriate node, and the network forwards them on to their final destination. |
akashvibhute | 0:c3db0798d9aa | 192 | */ |
akashvibhute | 0:c3db0798d9aa | 193 | struct RF24NetworkHeader |
akashvibhute | 0:c3db0798d9aa | 194 | { |
akashvibhute | 0:c3db0798d9aa | 195 | uint16_t from_node; /**< Logical address where the message was generated */ |
akashvibhute | 0:c3db0798d9aa | 196 | uint16_t to_node; /**< Logical address where the message is going */ |
akashvibhute | 2:a5f8e04bd02b | 197 | uint16_t id; /**< Sequential message ID, incremented every time a new frame is constructed */ |
akashvibhute | 2:a5f8e04bd02b | 198 | /** |
akashvibhute | 2:a5f8e04bd02b | 199 | * Message Types: |
akashvibhute | 2:a5f8e04bd02b | 200 | * User message types 1 through 64 will NOT be acknowledged by the network, while message types 65 through 127 will receive a network ACK. |
akashvibhute | 2:a5f8e04bd02b | 201 | * System message types 192 through 255 will NOT be acknowledged by the network. Message types 128 through 192 will receive a network ACK. <br> |
akashvibhute | 2:a5f8e04bd02b | 202 | * <br><br> |
akashvibhute | 2:a5f8e04bd02b | 203 | */ |
akashvibhute | 2:a5f8e04bd02b | 204 | unsigned char type; /**< <b>Type of the packet. </b> 0-127 are user-defined types, 128-255 are reserved for system */ |
akashvibhute | 2:a5f8e04bd02b | 205 | |
akashvibhute | 2:a5f8e04bd02b | 206 | /** |
akashvibhute | 2:a5f8e04bd02b | 207 | * During fragmentation, it carries the fragment_id, and on the last fragment |
akashvibhute | 2:a5f8e04bd02b | 208 | * it carries the header_type.<br> |
akashvibhute | 2:a5f8e04bd02b | 209 | */ |
akashvibhute | 2:a5f8e04bd02b | 210 | unsigned char reserved; /**< *Reserved for system use* */ |
akashvibhute | 0:c3db0798d9aa | 211 | |
akashvibhute | 2:a5f8e04bd02b | 212 | static uint16_t next_id; /**< The message ID of the next message to be sent (unused)*/ |
akashvibhute | 0:c3db0798d9aa | 213 | |
akashvibhute | 0:c3db0798d9aa | 214 | /** |
akashvibhute | 0:c3db0798d9aa | 215 | * Default constructor |
akashvibhute | 0:c3db0798d9aa | 216 | * |
akashvibhute | 2:a5f8e04bd02b | 217 | |
akashvibhute | 0:c3db0798d9aa | 218 | * Simply constructs a blank header |
akashvibhute | 0:c3db0798d9aa | 219 | */ |
akashvibhute | 0:c3db0798d9aa | 220 | RF24NetworkHeader() {} |
akashvibhute | 0:c3db0798d9aa | 221 | |
akashvibhute | 0:c3db0798d9aa | 222 | /** |
akashvibhute | 2:a5f8e04bd02b | 223 | * Send constructor |
akashvibhute | 2:a5f8e04bd02b | 224 | * |
akashvibhute | 2:a5f8e04bd02b | 225 | * @note Now supports automatic fragmentation for very long messages, which can be sent as usual if fragmentation is enabled. |
akashvibhute | 0:c3db0798d9aa | 226 | * |
akashvibhute | 2:a5f8e04bd02b | 227 | * Fragmentation is enabled by default for all devices except ATTiny <br> |
akashvibhute | 2:a5f8e04bd02b | 228 | * Configure fragmentation and max payload size in RF24Network_config.h |
akashvibhute | 2:a5f8e04bd02b | 229 | * |
akashvibhute | 2:a5f8e04bd02b | 230 | * Use this constructor to create a header and then send a message |
akashvibhute | 2:a5f8e04bd02b | 231 | * |
akashvibhute | 0:c3db0798d9aa | 232 | * @code |
akashvibhute | 2:a5f8e04bd02b | 233 | * uint16_t recipient_address = 011; |
akashvibhute | 2:a5f8e04bd02b | 234 | * |
akashvibhute | 0:c3db0798d9aa | 235 | * RF24NetworkHeader header(recipient_address,'t'); |
akashvibhute | 2:a5f8e04bd02b | 236 | * |
akashvibhute | 0:c3db0798d9aa | 237 | * network.write(header,&message,sizeof(message)); |
akashvibhute | 0:c3db0798d9aa | 238 | * @endcode |
akashvibhute | 0:c3db0798d9aa | 239 | * |
akashvibhute | 2:a5f8e04bd02b | 240 | * @param _to The Octal format, logical node address where the message is going |
akashvibhute | 0:c3db0798d9aa | 241 | * @param _type The type of message which follows. Only 0-127 are allowed for |
akashvibhute | 2:a5f8e04bd02b | 242 | * user messages. Types 1-64 will not receive a network acknowledgement. |
akashvibhute | 0:c3db0798d9aa | 243 | */ |
akashvibhute | 0:c3db0798d9aa | 244 | |
akashvibhute | 2:a5f8e04bd02b | 245 | RF24NetworkHeader(uint16_t _to, unsigned char _type = 0): to_node(_to), id(next_id++), type(_type) {} |
akashvibhute | 0:c3db0798d9aa | 246 | /** |
akashvibhute | 0:c3db0798d9aa | 247 | * Create debugging string |
akashvibhute | 0:c3db0798d9aa | 248 | * |
akashvibhute | 0:c3db0798d9aa | 249 | * Useful for debugging. Dumps all members into a single string, using |
akashvibhute | 0:c3db0798d9aa | 250 | * internal static memory. This memory will get overridden next time |
akashvibhute | 0:c3db0798d9aa | 251 | * you call the method. |
akashvibhute | 0:c3db0798d9aa | 252 | * |
akashvibhute | 0:c3db0798d9aa | 253 | * @return String representation of this object |
akashvibhute | 0:c3db0798d9aa | 254 | */ |
akashvibhute | 0:c3db0798d9aa | 255 | const char* toString(void) const; |
akashvibhute | 0:c3db0798d9aa | 256 | }; |
akashvibhute | 0:c3db0798d9aa | 257 | |
akashvibhute | 2:a5f8e04bd02b | 258 | |
akashvibhute | 0:c3db0798d9aa | 259 | /** |
akashvibhute | 2:a5f8e04bd02b | 260 | * Frame structure for internal message handling, and for use by external applications |
akashvibhute | 2:a5f8e04bd02b | 261 | * |
akashvibhute | 2:a5f8e04bd02b | 262 | * The actual frame put over the air consists of a header (8-bytes) and a message payload (Up to 24-bytes)<br> |
akashvibhute | 2:a5f8e04bd02b | 263 | * When data is received, it is stored using the RF24NetworkFrame structure, which includes: |
akashvibhute | 2:a5f8e04bd02b | 264 | * 1. The header |
akashvibhute | 2:a5f8e04bd02b | 265 | * 2. The size of the included message |
akashvibhute | 2:a5f8e04bd02b | 266 | * 3. The 'message' or data being received |
akashvibhute | 2:a5f8e04bd02b | 267 | * |
akashvibhute | 2:a5f8e04bd02b | 268 | * |
akashvibhute | 2:a5f8e04bd02b | 269 | */ |
akashvibhute | 2:a5f8e04bd02b | 270 | |
akashvibhute | 2:a5f8e04bd02b | 271 | |
akashvibhute | 2:a5f8e04bd02b | 272 | struct RF24NetworkFrame |
akashvibhute | 2:a5f8e04bd02b | 273 | { |
akashvibhute | 2:a5f8e04bd02b | 274 | RF24NetworkHeader header; /**< Header which is sent with each message */ |
akashvibhute | 2:a5f8e04bd02b | 275 | uint16_t message_size; /**< The size in bytes of the payload length */ |
akashvibhute | 2:a5f8e04bd02b | 276 | |
akashvibhute | 2:a5f8e04bd02b | 277 | /** |
akashvibhute | 2:a5f8e04bd02b | 278 | * On Arduino, the message buffer is just a pointer, and can be pointed to any memory location. |
akashvibhute | 2:a5f8e04bd02b | 279 | * On Linux the message buffer is a standard byte array, equal in size to the defined MAX_PAYLOAD_SIZE |
akashvibhute | 2:a5f8e04bd02b | 280 | */ |
akashvibhute | 2:a5f8e04bd02b | 281 | |
akashvibhute | 2:a5f8e04bd02b | 282 | |
akashvibhute | 2:a5f8e04bd02b | 283 | |
akashvibhute | 2:a5f8e04bd02b | 284 | uint8_t *message_buffer; //< Pointer to the buffer storing the actual message |
akashvibhute | 2:a5f8e04bd02b | 285 | |
akashvibhute | 2:a5f8e04bd02b | 286 | /** |
akashvibhute | 2:a5f8e04bd02b | 287 | * Default constructor |
akashvibhute | 2:a5f8e04bd02b | 288 | * |
akashvibhute | 2:a5f8e04bd02b | 289 | * Simply constructs a blank frame. Frames are generally used internally. See RF24NetworkHeader. |
akashvibhute | 2:a5f8e04bd02b | 290 | */ |
akashvibhute | 2:a5f8e04bd02b | 291 | //RF24NetworkFrame() {} |
akashvibhute | 2:a5f8e04bd02b | 292 | |
akashvibhute | 2:a5f8e04bd02b | 293 | RF24NetworkFrame() {} |
akashvibhute | 2:a5f8e04bd02b | 294 | /** |
akashvibhute | 2:a5f8e04bd02b | 295 | * Constructor - create a network frame with data |
akashvibhute | 2:a5f8e04bd02b | 296 | * Frames are constructed and handled differently on Arduino/AVR and Linux devices (defined RF24_LINUX) |
akashvibhute | 2:a5f8e04bd02b | 297 | * |
akashvibhute | 2:a5f8e04bd02b | 298 | * <br> |
akashvibhute | 2:a5f8e04bd02b | 299 | * **Linux:** |
akashvibhute | 2:a5f8e04bd02b | 300 | * @param _header The RF24Network header to be stored in the frame |
akashvibhute | 2:a5f8e04bd02b | 301 | * @param _message The 'message' or data. |
akashvibhute | 2:a5f8e04bd02b | 302 | * @param _len The size of the 'message' or data. |
akashvibhute | 2:a5f8e04bd02b | 303 | * |
akashvibhute | 2:a5f8e04bd02b | 304 | * <br> |
akashvibhute | 2:a5f8e04bd02b | 305 | * **Arduino/AVR/Etc.** |
akashvibhute | 2:a5f8e04bd02b | 306 | * @see RF24Network.frag_ptr |
akashvibhute | 2:a5f8e04bd02b | 307 | * @param _header The RF24Network header to be stored in the frame |
akashvibhute | 2:a5f8e04bd02b | 308 | * @param _message_size The size of the 'message' or data |
akashvibhute | 2:a5f8e04bd02b | 309 | * |
akashvibhute | 2:a5f8e04bd02b | 310 | * |
akashvibhute | 2:a5f8e04bd02b | 311 | * Frames are used internally and by external systems. See RF24NetworkHeader. |
akashvibhute | 2:a5f8e04bd02b | 312 | */ |
akashvibhute | 2:a5f8e04bd02b | 313 | |
akashvibhute | 2:a5f8e04bd02b | 314 | |
akashvibhute | 2:a5f8e04bd02b | 315 | |
akashvibhute | 2:a5f8e04bd02b | 316 | |
akashvibhute | 2:a5f8e04bd02b | 317 | |
akashvibhute | 2:a5f8e04bd02b | 318 | |
akashvibhute | 2:a5f8e04bd02b | 319 | |
akashvibhute | 2:a5f8e04bd02b | 320 | |
akashvibhute | 2:a5f8e04bd02b | 321 | RF24NetworkFrame(RF24NetworkHeader &_header, uint16_t _message_size): |
akashvibhute | 2:a5f8e04bd02b | 322 | header(_header), message_size(_message_size){ |
akashvibhute | 2:a5f8e04bd02b | 323 | } |
akashvibhute | 2:a5f8e04bd02b | 324 | |
akashvibhute | 2:a5f8e04bd02b | 325 | |
akashvibhute | 2:a5f8e04bd02b | 326 | |
akashvibhute | 2:a5f8e04bd02b | 327 | /** |
akashvibhute | 2:a5f8e04bd02b | 328 | * Create debugging string |
akashvibhute | 2:a5f8e04bd02b | 329 | * |
akashvibhute | 2:a5f8e04bd02b | 330 | * Useful for debugging. Dumps all members into a single string, using |
akashvibhute | 2:a5f8e04bd02b | 331 | * internal static memory. This memory will get overridden next time |
akashvibhute | 2:a5f8e04bd02b | 332 | * you call the method. |
akashvibhute | 2:a5f8e04bd02b | 333 | * |
akashvibhute | 2:a5f8e04bd02b | 334 | * @return String representation of this object |
akashvibhute | 2:a5f8e04bd02b | 335 | */ |
akashvibhute | 2:a5f8e04bd02b | 336 | const char* toString(void) const; |
akashvibhute | 2:a5f8e04bd02b | 337 | |
akashvibhute | 2:a5f8e04bd02b | 338 | }; |
akashvibhute | 2:a5f8e04bd02b | 339 | |
akashvibhute | 2:a5f8e04bd02b | 340 | |
akashvibhute | 2:a5f8e04bd02b | 341 | |
akashvibhute | 2:a5f8e04bd02b | 342 | /** |
akashvibhute | 2:a5f8e04bd02b | 343 | * 2014-2015 - Optimized Network Layer for RF24 Radios |
akashvibhute | 0:c3db0798d9aa | 344 | * |
akashvibhute | 0:c3db0798d9aa | 345 | * This class implements an OSI Network Layer using nRF24L01(+) radios driven |
akashvibhute | 0:c3db0798d9aa | 346 | * by RF24 library. |
akashvibhute | 0:c3db0798d9aa | 347 | */ |
akashvibhute | 0:c3db0798d9aa | 348 | |
akashvibhute | 0:c3db0798d9aa | 349 | class RF24Network |
akashvibhute | 0:c3db0798d9aa | 350 | { |
akashvibhute | 2:a5f8e04bd02b | 351 | private: |
akashvibhute | 2:a5f8e04bd02b | 352 | Timer rf24netTimer; |
akashvibhute | 2:a5f8e04bd02b | 353 | /**@}*/ |
akashvibhute | 2:a5f8e04bd02b | 354 | /** |
akashvibhute | 2:a5f8e04bd02b | 355 | * @name Primary Interface |
akashvibhute | 2:a5f8e04bd02b | 356 | * |
akashvibhute | 2:a5f8e04bd02b | 357 | * These are the main methods you need to operate the network |
akashvibhute | 2:a5f8e04bd02b | 358 | */ |
akashvibhute | 2:a5f8e04bd02b | 359 | /**@{*/ |
akashvibhute | 0:c3db0798d9aa | 360 | public: |
akashvibhute | 0:c3db0798d9aa | 361 | /** |
akashvibhute | 0:c3db0798d9aa | 362 | * Construct the network |
akashvibhute | 0:c3db0798d9aa | 363 | * |
akashvibhute | 0:c3db0798d9aa | 364 | * @param _radio The underlying radio driver instance |
akashvibhute | 0:c3db0798d9aa | 365 | * |
akashvibhute | 0:c3db0798d9aa | 366 | */ |
akashvibhute | 2:a5f8e04bd02b | 367 | |
akashvibhute | 0:c3db0798d9aa | 368 | RF24Network( RF24& _radio ); |
akashvibhute | 0:c3db0798d9aa | 369 | |
akashvibhute | 0:c3db0798d9aa | 370 | /** |
akashvibhute | 2:a5f8e04bd02b | 371 | * Bring up the network using the current radio frequency/channel. |
akashvibhute | 2:a5f8e04bd02b | 372 | * Calling begin brings up the network, and configures the address, which designates the location of the node within RF24Network topology. |
akashvibhute | 2:a5f8e04bd02b | 373 | * @note Node addresses are specified in Octal format, see <a href=Addressing.html>RF24Network Addressing</a> for more information. |
akashvibhute | 0:c3db0798d9aa | 374 | * @warning Be sure to 'begin' the radio first. |
akashvibhute | 0:c3db0798d9aa | 375 | * |
akashvibhute | 2:a5f8e04bd02b | 376 | * **Example 1:** Begin on current radio channel with address 0 (master node) |
akashvibhute | 2:a5f8e04bd02b | 377 | * @code |
akashvibhute | 2:a5f8e04bd02b | 378 | * network.begin(00); |
akashvibhute | 2:a5f8e04bd02b | 379 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 380 | * **Example 2:** Begin with address 01 (child of master) |
akashvibhute | 2:a5f8e04bd02b | 381 | * @code |
akashvibhute | 2:a5f8e04bd02b | 382 | * network.begin(01); |
akashvibhute | 2:a5f8e04bd02b | 383 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 384 | * **Example 3:** Begin with address 011 (child of 01, grandchild of master) |
akashvibhute | 2:a5f8e04bd02b | 385 | * @code |
akashvibhute | 2:a5f8e04bd02b | 386 | * network.begin(011); |
akashvibhute | 2:a5f8e04bd02b | 387 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 388 | * |
akashvibhute | 2:a5f8e04bd02b | 389 | * @see begin(uint8_t _channel, uint16_t _node_address ) |
akashvibhute | 0:c3db0798d9aa | 390 | * @param _node_address The logical address of this node |
akashvibhute | 2:a5f8e04bd02b | 391 | * |
akashvibhute | 0:c3db0798d9aa | 392 | */ |
akashvibhute | 2:a5f8e04bd02b | 393 | |
akashvibhute | 2:a5f8e04bd02b | 394 | inline void begin(uint16_t _node_address){ |
akashvibhute | 2:a5f8e04bd02b | 395 | begin(USE_CURRENT_CHANNEL,_node_address); |
akashvibhute | 2:a5f8e04bd02b | 396 | } |
akashvibhute | 2:a5f8e04bd02b | 397 | |
akashvibhute | 0:c3db0798d9aa | 398 | /** |
akashvibhute | 0:c3db0798d9aa | 399 | * Main layer loop |
akashvibhute | 0:c3db0798d9aa | 400 | * |
akashvibhute | 2:a5f8e04bd02b | 401 | * This function must be called regularly to keep the layer going. This is where payloads are |
akashvibhute | 2:a5f8e04bd02b | 402 | * re-routed, received, and all the action happens. |
akashvibhute | 2:a5f8e04bd02b | 403 | * |
akashvibhute | 2:a5f8e04bd02b | 404 | * @see |
akashvibhute | 2:a5f8e04bd02b | 405 | * |
akashvibhute | 2:a5f8e04bd02b | 406 | * @return Returns the type of the last received payload. |
akashvibhute | 0:c3db0798d9aa | 407 | */ |
akashvibhute | 2:a5f8e04bd02b | 408 | uint8_t update(void); |
akashvibhute | 0:c3db0798d9aa | 409 | |
akashvibhute | 0:c3db0798d9aa | 410 | /** |
akashvibhute | 0:c3db0798d9aa | 411 | * Test whether there is a message available for this node |
akashvibhute | 2:a5f8e04bd02b | 412 | * |
akashvibhute | 0:c3db0798d9aa | 413 | * @return Whether there is a message available for this node |
akashvibhute | 0:c3db0798d9aa | 414 | */ |
akashvibhute | 0:c3db0798d9aa | 415 | bool available(void); |
akashvibhute | 2:a5f8e04bd02b | 416 | |
akashvibhute | 0:c3db0798d9aa | 417 | /** |
akashvibhute | 0:c3db0798d9aa | 418 | * Read the next available header |
akashvibhute | 0:c3db0798d9aa | 419 | * |
akashvibhute | 0:c3db0798d9aa | 420 | * Reads the next available header without advancing to the next |
akashvibhute | 0:c3db0798d9aa | 421 | * incoming message. Useful for doing a switch on the message type |
akashvibhute | 0:c3db0798d9aa | 422 | * |
akashvibhute | 0:c3db0798d9aa | 423 | * If there is no message available, the header is not touched |
akashvibhute | 0:c3db0798d9aa | 424 | * |
akashvibhute | 0:c3db0798d9aa | 425 | * @param[out] header The header (envelope) of the next message |
akashvibhute | 0:c3db0798d9aa | 426 | */ |
akashvibhute | 2:a5f8e04bd02b | 427 | uint16_t peek(RF24NetworkHeader& header); |
akashvibhute | 0:c3db0798d9aa | 428 | |
akashvibhute | 0:c3db0798d9aa | 429 | /** |
akashvibhute | 0:c3db0798d9aa | 430 | * Read a message |
akashvibhute | 0:c3db0798d9aa | 431 | * |
akashvibhute | 2:a5f8e04bd02b | 432 | * @code |
akashvibhute | 2:a5f8e04bd02b | 433 | * while ( network.available() ) { |
akashvibhute | 2:a5f8e04bd02b | 434 | * RF24NetworkHeader header; |
akashvibhute | 2:a5f8e04bd02b | 435 | * uint32_t time; |
akashvibhute | 2:a5f8e04bd02b | 436 | * network.peek(header); |
akashvibhute | 2:a5f8e04bd02b | 437 | * if(header.type == 'T'){ |
akashvibhute | 2:a5f8e04bd02b | 438 | * network.read(header,&time,sizeof(time)); |
akashvibhute | 2:a5f8e04bd02b | 439 | * Serial.print("Got time: "); |
akashvibhute | 2:a5f8e04bd02b | 440 | * Serial.println(time); |
akashvibhute | 2:a5f8e04bd02b | 441 | * } |
akashvibhute | 2:a5f8e04bd02b | 442 | * } |
akashvibhute | 2:a5f8e04bd02b | 443 | * @endcode |
akashvibhute | 0:c3db0798d9aa | 444 | * @param[out] header The header (envelope) of this message |
akashvibhute | 0:c3db0798d9aa | 445 | * @param[out] message Pointer to memory where the message should be placed |
akashvibhute | 0:c3db0798d9aa | 446 | * @param maxlen The largest message size which can be held in @p message |
akashvibhute | 0:c3db0798d9aa | 447 | * @return The total number of bytes copied into @p message |
akashvibhute | 0:c3db0798d9aa | 448 | */ |
akashvibhute | 2:a5f8e04bd02b | 449 | uint16_t read(RF24NetworkHeader& header, void* message, uint16_t maxlen); |
akashvibhute | 2:a5f8e04bd02b | 450 | |
akashvibhute | 0:c3db0798d9aa | 451 | /** |
akashvibhute | 0:c3db0798d9aa | 452 | * Send a message |
akashvibhute | 0:c3db0798d9aa | 453 | * |
akashvibhute | 2:a5f8e04bd02b | 454 | * @note RF24Network now supports fragmentation for very long messages, send as normal. Fragmentation |
akashvibhute | 2:a5f8e04bd02b | 455 | * may need to be enabled or configured by editing the RF24Network_config.h file. Default max payload size is 120 bytes. |
akashvibhute | 2:a5f8e04bd02b | 456 | * |
akashvibhute | 2:a5f8e04bd02b | 457 | * @code |
akashvibhute | 2:a5f8e04bd02b | 458 | * uint32_t time = millis(); |
akashvibhute | 2:a5f8e04bd02b | 459 | * uint16_t to = 00; // Send to master |
akashvibhute | 2:a5f8e04bd02b | 460 | * RF24NetworkHeader header(to, 'T'); // Send header type 'T' |
akashvibhute | 2:a5f8e04bd02b | 461 | * network.write(header,&time,sizeof(time)); |
akashvibhute | 2:a5f8e04bd02b | 462 | * @endcode |
akashvibhute | 0:c3db0798d9aa | 463 | * @param[in,out] header The header (envelope) of this message. The critical |
akashvibhute | 0:c3db0798d9aa | 464 | * thing to fill in is the @p to_node field so we know where to send the |
akashvibhute | 0:c3db0798d9aa | 465 | * message. It is then updated with the details of the actual header sent. |
akashvibhute | 2:a5f8e04bd02b | 466 | * @param message Pointer to memory where the message is located |
akashvibhute | 2:a5f8e04bd02b | 467 | * @param len The size of the message |
akashvibhute | 2:a5f8e04bd02b | 468 | * @return Whether the message was successfully received |
akashvibhute | 2:a5f8e04bd02b | 469 | */ |
akashvibhute | 2:a5f8e04bd02b | 470 | bool write(RF24NetworkHeader& header,const void* message, uint16_t len); |
akashvibhute | 2:a5f8e04bd02b | 471 | |
akashvibhute | 2:a5f8e04bd02b | 472 | /**@}*/ |
akashvibhute | 2:a5f8e04bd02b | 473 | /** |
akashvibhute | 2:a5f8e04bd02b | 474 | * @name Advanced Configuration |
akashvibhute | 2:a5f8e04bd02b | 475 | * |
akashvibhute | 2:a5f8e04bd02b | 476 | * For advanced configuration of the network |
akashvibhute | 2:a5f8e04bd02b | 477 | */ |
akashvibhute | 2:a5f8e04bd02b | 478 | /**@{*/ |
akashvibhute | 2:a5f8e04bd02b | 479 | |
akashvibhute | 2:a5f8e04bd02b | 480 | |
akashvibhute | 2:a5f8e04bd02b | 481 | /** |
akashvibhute | 2:a5f8e04bd02b | 482 | * Construct the network in dual head mode using two radio modules. |
akashvibhute | 2:a5f8e04bd02b | 483 | * @note Not working on RPi. Radios will share MISO, MOSI and SCK pins, but require separate CE,CS pins. |
akashvibhute | 2:a5f8e04bd02b | 484 | * @code |
akashvibhute | 2:a5f8e04bd02b | 485 | * RF24 radio(7,8); |
akashvibhute | 2:a5f8e04bd02b | 486 | * RF24 radio1(4,5); |
akashvibhute | 2:a5f8e04bd02b | 487 | * RF24Network(radio.radio1); |
akashvibhute | 2:a5f8e04bd02b | 488 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 489 | * @param _radio The underlying radio driver instance |
akashvibhute | 2:a5f8e04bd02b | 490 | * @param _radio1 The second underlying radio driver instance |
akashvibhute | 2:a5f8e04bd02b | 491 | */ |
akashvibhute | 2:a5f8e04bd02b | 492 | |
akashvibhute | 2:a5f8e04bd02b | 493 | RF24Network( RF24& _radio, RF24& _radio1); |
akashvibhute | 2:a5f8e04bd02b | 494 | |
akashvibhute | 2:a5f8e04bd02b | 495 | /** |
akashvibhute | 2:a5f8e04bd02b | 496 | * By default, multicast addresses are divided into levels. |
akashvibhute | 2:a5f8e04bd02b | 497 | * |
akashvibhute | 2:a5f8e04bd02b | 498 | * Nodes 1-5 share a multicast address, nodes n1-n5 share a multicast address, and nodes n11-n55 share a multicast address.<br> |
akashvibhute | 2:a5f8e04bd02b | 499 | * |
akashvibhute | 2:a5f8e04bd02b | 500 | * This option is used to override the defaults, and create custom multicast groups that all share a single |
akashvibhute | 2:a5f8e04bd02b | 501 | * address. <br> |
akashvibhute | 2:a5f8e04bd02b | 502 | * The level should be specified in decimal format 1-6 <br> |
akashvibhute | 2:a5f8e04bd02b | 503 | * @see multicastRelay |
akashvibhute | 2:a5f8e04bd02b | 504 | * @param level Levels 1 to 6 are available. All nodes at the same level will receive the same |
akashvibhute | 2:a5f8e04bd02b | 505 | * messages if in range. Messages will be routed in order of level, low to high by default, with the |
akashvibhute | 2:a5f8e04bd02b | 506 | * master node (00) at multicast Level 0 |
akashvibhute | 2:a5f8e04bd02b | 507 | */ |
akashvibhute | 2:a5f8e04bd02b | 508 | |
akashvibhute | 2:a5f8e04bd02b | 509 | void multicastLevel(uint8_t level); |
akashvibhute | 2:a5f8e04bd02b | 510 | |
akashvibhute | 2:a5f8e04bd02b | 511 | /** |
akashvibhute | 2:a5f8e04bd02b | 512 | * Enabling this will allow this node to automatically forward received multicast frames to the next highest |
akashvibhute | 2:a5f8e04bd02b | 513 | * multicast level. Duplicate frames are filtered out, so multiple forwarding nodes at the same level should |
akashvibhute | 2:a5f8e04bd02b | 514 | * not interfere. Forwarded payloads will also be received. |
akashvibhute | 2:a5f8e04bd02b | 515 | * @see multicastLevel |
akashvibhute | 2:a5f8e04bd02b | 516 | */ |
akashvibhute | 2:a5f8e04bd02b | 517 | |
akashvibhute | 2:a5f8e04bd02b | 518 | bool multicastRelay; |
akashvibhute | 2:a5f8e04bd02b | 519 | |
akashvibhute | 2:a5f8e04bd02b | 520 | /** |
akashvibhute | 2:a5f8e04bd02b | 521 | * Set up the watchdog timer for sleep mode using the number 0 through 10 to represent the following time periods:<br> |
akashvibhute | 2:a5f8e04bd02b | 522 | * wdt_16ms = 0, wdt_32ms, wdt_64ms, wdt_128ms, wdt_250ms, wdt_500ms, wdt_1s, wdt_2s, wdt_4s, wdt_8s |
akashvibhute | 2:a5f8e04bd02b | 523 | * @code |
akashvibhute | 2:a5f8e04bd02b | 524 | * setup_watchdog(7); // Sets the WDT to trigger every second |
akashvibhute | 2:a5f8e04bd02b | 525 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 526 | * @param prescalar The WDT prescaler to define how often the node will wake up. When defining sleep mode cycles, this time period is 1 cycle. |
akashvibhute | 0:c3db0798d9aa | 527 | */ |
akashvibhute | 2:a5f8e04bd02b | 528 | void setup_watchdog(uint8_t prescalar); |
akashvibhute | 2:a5f8e04bd02b | 529 | |
akashvibhute | 2:a5f8e04bd02b | 530 | /** |
akashvibhute | 2:a5f8e04bd02b | 531 | * @note: This value is automatically assigned based on the node address |
akashvibhute | 2:a5f8e04bd02b | 532 | * to reduce errors and increase throughput of the network. |
akashvibhute | 2:a5f8e04bd02b | 533 | * |
akashvibhute | 2:a5f8e04bd02b | 534 | * Sets the timeout period for individual payloads in milliseconds at staggered intervals. |
akashvibhute | 2:a5f8e04bd02b | 535 | * Payloads will be retried automatically until success or timeout |
akashvibhute | 2:a5f8e04bd02b | 536 | * Set to 0 to use the normal auto retry period defined by radio.setRetries() |
akashvibhute | 2:a5f8e04bd02b | 537 | * |
akashvibhute | 2:a5f8e04bd02b | 538 | */ |
akashvibhute | 2:a5f8e04bd02b | 539 | |
akashvibhute | 2:a5f8e04bd02b | 540 | uint32_t txTimeout; /**< Network timeout value */ |
akashvibhute | 2:a5f8e04bd02b | 541 | |
akashvibhute | 2:a5f8e04bd02b | 542 | /** |
akashvibhute | 2:a5f8e04bd02b | 543 | * This only affects payloads that are routed by one or more nodes. |
akashvibhute | 2:a5f8e04bd02b | 544 | * This specifies how long to wait for an ack from across the network. |
akashvibhute | 2:a5f8e04bd02b | 545 | * Radios sending directly to their parent or children nodes do not |
akashvibhute | 2:a5f8e04bd02b | 546 | * utilize this value. |
akashvibhute | 2:a5f8e04bd02b | 547 | */ |
akashvibhute | 2:a5f8e04bd02b | 548 | |
akashvibhute | 2:a5f8e04bd02b | 549 | uint16_t routeTimeout; /**< Timeout for routed payloads */ |
akashvibhute | 2:a5f8e04bd02b | 550 | |
akashvibhute | 2:a5f8e04bd02b | 551 | |
akashvibhute | 2:a5f8e04bd02b | 552 | /**@}*/ |
akashvibhute | 2:a5f8e04bd02b | 553 | /** |
akashvibhute | 2:a5f8e04bd02b | 554 | * @name Advanced Operation |
akashvibhute | 2:a5f8e04bd02b | 555 | * |
akashvibhute | 2:a5f8e04bd02b | 556 | * For advanced operation of the network |
akashvibhute | 2:a5f8e04bd02b | 557 | */ |
akashvibhute | 2:a5f8e04bd02b | 558 | /**@{*/ |
akashvibhute | 2:a5f8e04bd02b | 559 | |
akashvibhute | 2:a5f8e04bd02b | 560 | /** |
akashvibhute | 2:a5f8e04bd02b | 561 | * Return the number of failures and successes for all transmitted payloads, routed or sent directly |
akashvibhute | 2:a5f8e04bd02b | 562 | * @note This needs to be enabled via #define ENABLE_NETWORK_STATS in RF24Network_config.h |
akashvibhute | 2:a5f8e04bd02b | 563 | * |
akashvibhute | 2:a5f8e04bd02b | 564 | * @code |
akashvibhute | 2:a5f8e04bd02b | 565 | * bool fails, success; |
akashvibhute | 2:a5f8e04bd02b | 566 | * network.failures(&fails,&success); |
akashvibhute | 2:a5f8e04bd02b | 567 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 568 | * |
akashvibhute | 2:a5f8e04bd02b | 569 | */ |
akashvibhute | 2:a5f8e04bd02b | 570 | void failures(uint32_t *_fails, uint32_t *_ok); |
akashvibhute | 2:a5f8e04bd02b | 571 | |
akashvibhute | 2:a5f8e04bd02b | 572 | #if defined (RF24NetworkMulticast) |
akashvibhute | 2:a5f8e04bd02b | 573 | |
akashvibhute | 2:a5f8e04bd02b | 574 | /** |
akashvibhute | 2:a5f8e04bd02b | 575 | * Send a multicast message to multiple nodes at once |
akashvibhute | 2:a5f8e04bd02b | 576 | * Allows messages to be rapidly broadcast through the network |
akashvibhute | 2:a5f8e04bd02b | 577 | * |
akashvibhute | 2:a5f8e04bd02b | 578 | * Multicasting is arranged in levels, with all nodes on the same level listening to the same address |
akashvibhute | 2:a5f8e04bd02b | 579 | * Levels are assigned by network level ie: nodes 01-05: Level 1, nodes 011-055: Level 2 |
akashvibhute | 2:a5f8e04bd02b | 580 | * @see multicastLevel |
akashvibhute | 2:a5f8e04bd02b | 581 | * @see multicastRelay |
akashvibhute | 2:a5f8e04bd02b | 582 | * @param message Pointer to memory where the message is located |
akashvibhute | 2:a5f8e04bd02b | 583 | * @param len The size of the message |
akashvibhute | 2:a5f8e04bd02b | 584 | * @param level Multicast level to broadcast to |
akashvibhute | 2:a5f8e04bd02b | 585 | * @return Whether the message was successfully sent |
akashvibhute | 2:a5f8e04bd02b | 586 | */ |
akashvibhute | 2:a5f8e04bd02b | 587 | |
akashvibhute | 2:a5f8e04bd02b | 588 | bool multicast(RF24NetworkHeader& header,const void* message, uint16_t len, uint8_t level); |
akashvibhute | 2:a5f8e04bd02b | 589 | |
akashvibhute | 2:a5f8e04bd02b | 590 | |
akashvibhute | 2:a5f8e04bd02b | 591 | #endif |
akashvibhute | 2:a5f8e04bd02b | 592 | |
akashvibhute | 2:a5f8e04bd02b | 593 | /** |
akashvibhute | 2:a5f8e04bd02b | 594 | * Writes a direct (unicast) payload. This allows routing or sending messages outside of the usual routing paths. |
akashvibhute | 2:a5f8e04bd02b | 595 | * The same as write, but a physical address is specified as the last option. |
akashvibhute | 2:a5f8e04bd02b | 596 | * The payload will be written to the physical address, and routed as necessary by the recipient |
akashvibhute | 2:a5f8e04bd02b | 597 | */ |
akashvibhute | 2:a5f8e04bd02b | 598 | bool write(RF24NetworkHeader& header,const void* message, uint16_t len, uint16_t writeDirect); |
akashvibhute | 0:c3db0798d9aa | 599 | |
akashvibhute | 2:a5f8e04bd02b | 600 | /** |
akashvibhute | 2:a5f8e04bd02b | 601 | * Sleep this node - For AVR devices only |
akashvibhute | 2:a5f8e04bd02b | 602 | * @note NEW - Nodes can now be slept while the radio is not actively transmitting. This must be manually enabled by uncommenting |
akashvibhute | 2:a5f8e04bd02b | 603 | * the #define ENABLE_SLEEP_MODE in RF24Network_config.h |
akashvibhute | 2:a5f8e04bd02b | 604 | * @note Setting the interruptPin to 255 will disable interrupt wake-ups |
akashvibhute | 2:a5f8e04bd02b | 605 | * @note The watchdog timer should be configured in setup() if using sleep mode. |
akashvibhute | 2:a5f8e04bd02b | 606 | * This function will sleep the node, with the radio still active in receive mode. |
akashvibhute | 2:a5f8e04bd02b | 607 | * |
akashvibhute | 2:a5f8e04bd02b | 608 | * The node can be awoken in two ways, both of which can be enabled simultaneously: |
akashvibhute | 2:a5f8e04bd02b | 609 | * 1. An interrupt - usually triggered by the radio receiving a payload. Must use pin 2 (interrupt 0) or 3 (interrupt 1) on Uno, Nano, etc. |
akashvibhute | 2:a5f8e04bd02b | 610 | * 2. The watchdog timer waking the MCU after a designated period of time, can also be used instead of delays to control transmission intervals. |
akashvibhute | 2:a5f8e04bd02b | 611 | * @code |
akashvibhute | 2:a5f8e04bd02b | 612 | * if(!network.available()){ network.sleepNode(1,0); } //Sleeps the node for 1 second or a payload is received |
akashvibhute | 2:a5f8e04bd02b | 613 | * |
akashvibhute | 2:a5f8e04bd02b | 614 | * Other options: |
akashvibhute | 2:a5f8e04bd02b | 615 | * network.sleepNode(0,0); // Sleep this node for the designated time period, or a payload is received. |
akashvibhute | 2:a5f8e04bd02b | 616 | * network.sleepNode(1,255); // Sleep this node for 1 cycle. Do not wake up until then, even if a payload is received ( no interrupt ) |
akashvibhute | 2:a5f8e04bd02b | 617 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 618 | * @see setup_watchdog() |
akashvibhute | 2:a5f8e04bd02b | 619 | * @param cycles: The node will sleep in cycles of 1s. Using 2 will sleep 2 WDT cycles, 3 sleeps 3WDT cycles... |
akashvibhute | 2:a5f8e04bd02b | 620 | * @param interruptPin: The interrupt number to use (0,1) for pins two and three on Uno,Nano. More available on Mega etc. |
akashvibhute | 2:a5f8e04bd02b | 621 | * @return True if sleepNode completed normally, after the specified number of cycles. False if sleep was interrupted |
akashvibhute | 2:a5f8e04bd02b | 622 | */ |
akashvibhute | 2:a5f8e04bd02b | 623 | bool sleepNode( unsigned int cycles, int interruptPin ); |
akashvibhute | 2:a5f8e04bd02b | 624 | |
akashvibhute | 2:a5f8e04bd02b | 625 | |
akashvibhute | 2:a5f8e04bd02b | 626 | /** |
akashvibhute | 2:a5f8e04bd02b | 627 | * This node's parent address |
akashvibhute | 2:a5f8e04bd02b | 628 | * |
akashvibhute | 2:a5f8e04bd02b | 629 | * @return This node's parent address, or -1 if this is the base |
akashvibhute | 2:a5f8e04bd02b | 630 | */ |
akashvibhute | 2:a5f8e04bd02b | 631 | uint16_t parent() const; |
akashvibhute | 2:a5f8e04bd02b | 632 | |
akashvibhute | 2:a5f8e04bd02b | 633 | /** |
akashvibhute | 2:a5f8e04bd02b | 634 | * Provided a node address and a pipe number, will return the RF24Network address of that child pipe for that node |
akashvibhute | 2:a5f8e04bd02b | 635 | */ |
akashvibhute | 2:a5f8e04bd02b | 636 | uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo ); |
akashvibhute | 2:a5f8e04bd02b | 637 | |
akashvibhute | 2:a5f8e04bd02b | 638 | /** |
akashvibhute | 2:a5f8e04bd02b | 639 | * @note Addresses are specified in octal: 011, 034 |
akashvibhute | 2:a5f8e04bd02b | 640 | * @return True if a supplied address is valid |
akashvibhute | 2:a5f8e04bd02b | 641 | */ |
akashvibhute | 2:a5f8e04bd02b | 642 | bool is_valid_address( uint16_t node ); |
akashvibhute | 2:a5f8e04bd02b | 643 | |
akashvibhute | 2:a5f8e04bd02b | 644 | /**@}*/ |
akashvibhute | 2:a5f8e04bd02b | 645 | /** |
akashvibhute | 2:a5f8e04bd02b | 646 | * @name Deprecated |
akashvibhute | 2:a5f8e04bd02b | 647 | * |
akashvibhute | 2:a5f8e04bd02b | 648 | * Maintained for backwards compatibility |
akashvibhute | 2:a5f8e04bd02b | 649 | */ |
akashvibhute | 2:a5f8e04bd02b | 650 | /**@{*/ |
akashvibhute | 2:a5f8e04bd02b | 651 | |
akashvibhute | 2:a5f8e04bd02b | 652 | /** |
akashvibhute | 2:a5f8e04bd02b | 653 | * Bring up the network on a specific radio frequency/channel. |
akashvibhute | 2:a5f8e04bd02b | 654 | * @note Use radio.setChannel() to configure the radio channel |
akashvibhute | 2:a5f8e04bd02b | 655 | * |
akashvibhute | 2:a5f8e04bd02b | 656 | * **Example 1:** Begin on channel 90 with address 0 (master node) |
akashvibhute | 2:a5f8e04bd02b | 657 | * @code |
akashvibhute | 2:a5f8e04bd02b | 658 | * network.begin(90,0); |
akashvibhute | 2:a5f8e04bd02b | 659 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 660 | * **Example 2:** Begin on channel 90 with address 01 (child of master) |
akashvibhute | 2:a5f8e04bd02b | 661 | * @code |
akashvibhute | 2:a5f8e04bd02b | 662 | * network.begin(90,01); |
akashvibhute | 2:a5f8e04bd02b | 663 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 664 | * **Example 3:** Begin on channel 90 with address 011 (child of 01, grandchild of master) |
akashvibhute | 2:a5f8e04bd02b | 665 | * @code |
akashvibhute | 2:a5f8e04bd02b | 666 | * network.begin(90,011); |
akashvibhute | 2:a5f8e04bd02b | 667 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 668 | * |
akashvibhute | 2:a5f8e04bd02b | 669 | * @param _channel The RF channel to operate on |
akashvibhute | 2:a5f8e04bd02b | 670 | * @param _node_address The logical address of this node |
akashvibhute | 2:a5f8e04bd02b | 671 | * |
akashvibhute | 2:a5f8e04bd02b | 672 | */ |
akashvibhute | 2:a5f8e04bd02b | 673 | void begin(uint8_t _channel, uint16_t _node_address ); |
akashvibhute | 2:a5f8e04bd02b | 674 | |
akashvibhute | 2:a5f8e04bd02b | 675 | /**@}*/ |
akashvibhute | 2:a5f8e04bd02b | 676 | /** |
akashvibhute | 2:a5f8e04bd02b | 677 | * @name External Applications/Systems |
akashvibhute | 2:a5f8e04bd02b | 678 | * |
akashvibhute | 2:a5f8e04bd02b | 679 | * Interface for External Applications and Systems ( RF24Mesh, RF24Ethernet ) |
akashvibhute | 2:a5f8e04bd02b | 680 | */ |
akashvibhute | 2:a5f8e04bd02b | 681 | /**@{*/ |
akashvibhute | 2:a5f8e04bd02b | 682 | |
akashvibhute | 2:a5f8e04bd02b | 683 | /** The raw system frame buffer of received data. */ |
akashvibhute | 2:a5f8e04bd02b | 684 | |
akashvibhute | 2:a5f8e04bd02b | 685 | uint8_t frame_buffer[MAX_FRAME_SIZE]; |
akashvibhute | 2:a5f8e04bd02b | 686 | |
akashvibhute | 2:a5f8e04bd02b | 687 | /** |
akashvibhute | 2:a5f8e04bd02b | 688 | * **Linux** <br> |
akashvibhute | 2:a5f8e04bd02b | 689 | * Data with a header type of EXTERNAL_DATA_TYPE will be loaded into a separate queue. |
akashvibhute | 2:a5f8e04bd02b | 690 | * The data can be accessed as follows: |
akashvibhute | 2:a5f8e04bd02b | 691 | * @code |
akashvibhute | 2:a5f8e04bd02b | 692 | * RF24NetworkFrame f; |
akashvibhute | 2:a5f8e04bd02b | 693 | * while(network.external_queue.size() > 0){ |
akashvibhute | 2:a5f8e04bd02b | 694 | * f = network.external_queue.front(); |
akashvibhute | 2:a5f8e04bd02b | 695 | * uint16_t dataSize = f.message_size; |
akashvibhute | 2:a5f8e04bd02b | 696 | * //read the frame message buffer |
akashvibhute | 2:a5f8e04bd02b | 697 | * memcpy(&myBuffer,&f.message_buffer,dataSize); |
akashvibhute | 2:a5f8e04bd02b | 698 | * network.external_queue.pop(); |
akashvibhute | 2:a5f8e04bd02b | 699 | * } |
akashvibhute | 2:a5f8e04bd02b | 700 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 701 | */ |
akashvibhute | 2:a5f8e04bd02b | 702 | |
akashvibhute | 2:a5f8e04bd02b | 703 | |
akashvibhute | 2:a5f8e04bd02b | 704 | |
akashvibhute | 2:a5f8e04bd02b | 705 | |
akashvibhute | 2:a5f8e04bd02b | 706 | #if !defined ( DISABLE_FRAGMENTATION ) |
akashvibhute | 2:a5f8e04bd02b | 707 | /** |
akashvibhute | 2:a5f8e04bd02b | 708 | * **ARDUINO** <br> |
akashvibhute | 2:a5f8e04bd02b | 709 | * The frag_ptr is only used with Arduino (not RPi/Linux) and is mainly used for external data systems like RF24Ethernet. When |
akashvibhute | 2:a5f8e04bd02b | 710 | * an EXTERNAL_DATA payload type is received, and returned from network.update(), the frag_ptr will always point to the starting |
akashvibhute | 2:a5f8e04bd02b | 711 | * memory location of the received frame. <br>This is used by external data systems (RF24Ethernet) to immediately copy the received |
akashvibhute | 2:a5f8e04bd02b | 712 | * data to a buffer, without using the user-cache. |
akashvibhute | 2:a5f8e04bd02b | 713 | * |
akashvibhute | 2:a5f8e04bd02b | 714 | * @see RF24NetworkFrame |
akashvibhute | 2:a5f8e04bd02b | 715 | * |
akashvibhute | 2:a5f8e04bd02b | 716 | * @code |
akashvibhute | 2:a5f8e04bd02b | 717 | * uint8_t return_type = network.update(); |
akashvibhute | 2:a5f8e04bd02b | 718 | * if(return_type == EXTERNAL_DATA_TYPE){ |
akashvibhute | 2:a5f8e04bd02b | 719 | * uint16_t size = network.frag_ptr->message_size; |
akashvibhute | 2:a5f8e04bd02b | 720 | * memcpy(&myDataBuffer,network.frag_ptr->message_buffer,network.frag_ptr->message_size); |
akashvibhute | 2:a5f8e04bd02b | 721 | * } |
akashvibhute | 2:a5f8e04bd02b | 722 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 723 | * Linux devices (defined as RF24_LINUX) currently cache all payload types, and do not utilize frag_ptr. |
akashvibhute | 2:a5f8e04bd02b | 724 | */ |
akashvibhute | 2:a5f8e04bd02b | 725 | RF24NetworkFrame* frag_ptr; |
akashvibhute | 2:a5f8e04bd02b | 726 | #endif |
akashvibhute | 2:a5f8e04bd02b | 727 | |
akashvibhute | 2:a5f8e04bd02b | 728 | /** |
akashvibhute | 2:a5f8e04bd02b | 729 | * Variable to determine whether update() will return after the radio buffers have been emptied (DEFAULT), or |
akashvibhute | 2:a5f8e04bd02b | 730 | * whether to return immediately when (most) system types are received. |
akashvibhute | 2:a5f8e04bd02b | 731 | * |
akashvibhute | 2:a5f8e04bd02b | 732 | * As an example, this is used with RF24Mesh to catch and handle system messages without loading them into the user cache. |
akashvibhute | 2:a5f8e04bd02b | 733 | * |
akashvibhute | 2:a5f8e04bd02b | 734 | * The following reserved/system message types are handled automatically, and not returned. |
akashvibhute | 2:a5f8e04bd02b | 735 | * |
akashvibhute | 2:a5f8e04bd02b | 736 | * | System Message Types <br> (Not Returned) | |
akashvibhute | 2:a5f8e04bd02b | 737 | * |-----------------------| |
akashvibhute | 2:a5f8e04bd02b | 738 | * | NETWORK_ADDR_RESPONSE | |
akashvibhute | 2:a5f8e04bd02b | 739 | * | NETWORK_ACK | |
akashvibhute | 2:a5f8e04bd02b | 740 | * | NETWORK_PING | |
akashvibhute | 2:a5f8e04bd02b | 741 | * | NETWORK_POLL <br>(With multicast enabled) | |
akashvibhute | 2:a5f8e04bd02b | 742 | * | NETWORK_REQ_ADDRESS | |
akashvibhute | 2:a5f8e04bd02b | 743 | * |
akashvibhute | 2:a5f8e04bd02b | 744 | */ |
akashvibhute | 2:a5f8e04bd02b | 745 | bool returnSysMsgs; |
akashvibhute | 2:a5f8e04bd02b | 746 | |
akashvibhute | 2:a5f8e04bd02b | 747 | /** |
akashvibhute | 2:a5f8e04bd02b | 748 | * Network Flags allow control of data flow |
akashvibhute | 2:a5f8e04bd02b | 749 | * |
akashvibhute | 2:a5f8e04bd02b | 750 | * Incoming Blocking: If the network user-cache is full, lets radio cache fill up. Radio ACKs are not sent when radio internal cache is full.<br> |
akashvibhute | 2:a5f8e04bd02b | 751 | * This behaviour may seem to result in more failed sends, but the payloads would have otherwise been dropped due to the cache being full.<br> |
akashvibhute | 2:a5f8e04bd02b | 752 | * |
akashvibhute | 2:a5f8e04bd02b | 753 | * | FLAGS | Value | Description | |
akashvibhute | 2:a5f8e04bd02b | 754 | * |-------|-------|-------------| |
akashvibhute | 2:a5f8e04bd02b | 755 | * |FLAG_HOLD_INCOMING| 1(bit_1) | INTERNAL: Set automatically when a fragmented payload will exceed the available cache | |
akashvibhute | 2:a5f8e04bd02b | 756 | * |FLAG_BYPASS_HOLDS| 2(bit_2) | EXTERNAL: Can be used to prevent holds from blocking. Note: Holds are disabled & re-enabled by RF24Mesh when renewing addresses. This will cause data loss if incoming data exceeds the available cache space| |
akashvibhute | 2:a5f8e04bd02b | 757 | * |FLAG_FAST_FRAG| 4(bit_3) | INTERNAL: Replaces the fastFragTransfer variable, and allows for faster transfers between directly connected nodes. | |
akashvibhute | 2:a5f8e04bd02b | 758 | * |
akashvibhute | 2:a5f8e04bd02b | 759 | */ |
akashvibhute | 2:a5f8e04bd02b | 760 | uint8_t networkFlags; |
akashvibhute | 2:a5f8e04bd02b | 761 | |
akashvibhute | 2:a5f8e04bd02b | 762 | private: |
akashvibhute | 2:a5f8e04bd02b | 763 | |
akashvibhute | 2:a5f8e04bd02b | 764 | uint32_t txTime; |
akashvibhute | 2:a5f8e04bd02b | 765 | |
akashvibhute | 2:a5f8e04bd02b | 766 | bool write(uint16_t, uint8_t directTo); |
akashvibhute | 2:a5f8e04bd02b | 767 | bool write_to_pipe( uint16_t node, uint8_t pipe, bool multicast ); |
akashvibhute | 2:a5f8e04bd02b | 768 | uint8_t enqueue(RF24NetworkHeader *header); |
akashvibhute | 0:c3db0798d9aa | 769 | |
akashvibhute | 0:c3db0798d9aa | 770 | bool is_direct_child( uint16_t node ); |
akashvibhute | 0:c3db0798d9aa | 771 | bool is_descendant( uint16_t node ); |
akashvibhute | 2:a5f8e04bd02b | 772 | |
akashvibhute | 0:c3db0798d9aa | 773 | uint16_t direct_child_route_to( uint16_t node ); |
akashvibhute | 2:a5f8e04bd02b | 774 | //uint8_t pipe_to_descendant( uint16_t node ); |
akashvibhute | 0:c3db0798d9aa | 775 | void setup_address(void); |
akashvibhute | 2:a5f8e04bd02b | 776 | bool _write(RF24NetworkHeader& header,const void* message, uint16_t len, uint16_t writeDirect); |
akashvibhute | 2:a5f8e04bd02b | 777 | |
akashvibhute | 2:a5f8e04bd02b | 778 | struct logicalToPhysicalStruct{ |
akashvibhute | 2:a5f8e04bd02b | 779 | uint16_t send_node; |
akashvibhute | 2:a5f8e04bd02b | 780 | uint8_t send_pipe; |
akashvibhute | 2:a5f8e04bd02b | 781 | bool multicast; |
akashvibhute | 2:a5f8e04bd02b | 782 | }; |
akashvibhute | 2:a5f8e04bd02b | 783 | |
akashvibhute | 2:a5f8e04bd02b | 784 | bool logicalToPhysicalAddress(logicalToPhysicalStruct *conversionInfo); |
akashvibhute | 2:a5f8e04bd02b | 785 | |
akashvibhute | 2:a5f8e04bd02b | 786 | |
akashvibhute | 2:a5f8e04bd02b | 787 | RF24& radio; /**< Underlying radio driver, provides link/physical layers */ |
akashvibhute | 2:a5f8e04bd02b | 788 | #if defined (DUAL_HEAD_RADIO) |
akashvibhute | 2:a5f8e04bd02b | 789 | RF24& radio1; |
akashvibhute | 2:a5f8e04bd02b | 790 | #endif |
akashvibhute | 2:a5f8e04bd02b | 791 | #if defined (RF24NetworkMulticast) |
akashvibhute | 2:a5f8e04bd02b | 792 | uint8_t multicast_level; |
akashvibhute | 2:a5f8e04bd02b | 793 | #endif |
akashvibhute | 2:a5f8e04bd02b | 794 | uint16_t node_address; /**< Logical node address of this unit, 1 .. UINT_MAX */ |
akashvibhute | 2:a5f8e04bd02b | 795 | //const static int frame_size = 32; /**< How large is each frame over the air */ |
akashvibhute | 2:a5f8e04bd02b | 796 | uint8_t frame_size; |
akashvibhute | 2:a5f8e04bd02b | 797 | const static unsigned int max_frame_payload_size = MAX_FRAME_SIZE-sizeof(RF24NetworkHeader); |
akashvibhute | 2:a5f8e04bd02b | 798 | |
akashvibhute | 0:c3db0798d9aa | 799 | |
akashvibhute | 2:a5f8e04bd02b | 800 | |
akashvibhute | 2:a5f8e04bd02b | 801 | |
akashvibhute | 2:a5f8e04bd02b | 802 | |
akashvibhute | 2:a5f8e04bd02b | 803 | |
akashvibhute | 2:a5f8e04bd02b | 804 | |
akashvibhute | 2:a5f8e04bd02b | 805 | |
akashvibhute | 2:a5f8e04bd02b | 806 | |
akashvibhute | 2:a5f8e04bd02b | 807 | |
akashvibhute | 2:a5f8e04bd02b | 808 | |
akashvibhute | 2:a5f8e04bd02b | 809 | |
akashvibhute | 2:a5f8e04bd02b | 810 | #if !defined (NUM_USER_PAYLOADS) |
akashvibhute | 2:a5f8e04bd02b | 811 | #define NUM_USER_PAYLOADS 5 |
akashvibhute | 2:a5f8e04bd02b | 812 | #endif |
akashvibhute | 2:a5f8e04bd02b | 813 | |
akashvibhute | 2:a5f8e04bd02b | 814 | #if defined (DISABLE_USER_PAYLOADS) |
akashvibhute | 2:a5f8e04bd02b | 815 | uint8_t frame_queue[1]; /**< Space for a small set of frames that need to be delivered to the app layer */ |
akashvibhute | 2:a5f8e04bd02b | 816 | #else |
akashvibhute | 2:a5f8e04bd02b | 817 | uint8_t frame_queue[MAIN_BUFFER_SIZE]; /**< Space for a small set of frames that need to be delivered to the app layer */ |
akashvibhute | 2:a5f8e04bd02b | 818 | #endif |
akashvibhute | 2:a5f8e04bd02b | 819 | |
akashvibhute | 2:a5f8e04bd02b | 820 | uint8_t* next_frame; /**< Pointer into the @p frame_queue where we should place the next received frame */ |
akashvibhute | 2:a5f8e04bd02b | 821 | |
akashvibhute | 2:a5f8e04bd02b | 822 | #if !defined ( DISABLE_FRAGMENTATION ) |
akashvibhute | 2:a5f8e04bd02b | 823 | RF24NetworkFrame frag_queue; |
akashvibhute | 2:a5f8e04bd02b | 824 | uint8_t frag_queue_message_buffer[MAX_PAYLOAD_SIZE]; //frame size + 1 |
akashvibhute | 2:a5f8e04bd02b | 825 | #endif |
akashvibhute | 2:a5f8e04bd02b | 826 | |
akashvibhute | 0:c3db0798d9aa | 827 | |
akashvibhute | 2:a5f8e04bd02b | 828 | |
akashvibhute | 2:a5f8e04bd02b | 829 | //uint8_t frag_queue[MAX_PAYLOAD_SIZE + 11]; |
akashvibhute | 2:a5f8e04bd02b | 830 | //RF24NetworkFrame frag_queue; |
akashvibhute | 2:a5f8e04bd02b | 831 | |
akashvibhute | 0:c3db0798d9aa | 832 | uint16_t parent_node; /**< Our parent's node address */ |
akashvibhute | 0:c3db0798d9aa | 833 | uint8_t parent_pipe; /**< The pipe our parent uses to listen to us */ |
akashvibhute | 0:c3db0798d9aa | 834 | uint16_t node_mask; /**< The bits which contain signfificant node address information */ |
akashvibhute | 2:a5f8e04bd02b | 835 | |
akashvibhute | 2:a5f8e04bd02b | 836 | #if defined ENABLE_NETWORK_STATS |
akashvibhute | 2:a5f8e04bd02b | 837 | static uint32_t nFails; |
akashvibhute | 2:a5f8e04bd02b | 838 | static uint32_t nOK; |
akashvibhute | 2:a5f8e04bd02b | 839 | #endif |
akashvibhute | 2:a5f8e04bd02b | 840 | |
akashvibhute | 2:a5f8e04bd02b | 841 | public: |
akashvibhute | 2:a5f8e04bd02b | 842 | |
akashvibhute | 2:a5f8e04bd02b | 843 | |
akashvibhute | 2:a5f8e04bd02b | 844 | |
akashvibhute | 0:c3db0798d9aa | 845 | }; |
akashvibhute | 0:c3db0798d9aa | 846 | |
akashvibhute | 0:c3db0798d9aa | 847 | /** |
akashvibhute | 2:a5f8e04bd02b | 848 | * @example helloworld_tx.ino |
akashvibhute | 0:c3db0798d9aa | 849 | * |
akashvibhute | 0:c3db0798d9aa | 850 | * Simplest possible example of using RF24Network. Put this sketch |
akashvibhute | 0:c3db0798d9aa | 851 | * on one node, and helloworld_rx.pde on the other. Tx will send |
akashvibhute | 0:c3db0798d9aa | 852 | * Rx a nice message every 2 seconds which rx will print out for us. |
akashvibhute | 0:c3db0798d9aa | 853 | */ |
akashvibhute | 0:c3db0798d9aa | 854 | |
akashvibhute | 0:c3db0798d9aa | 855 | /** |
akashvibhute | 2:a5f8e04bd02b | 856 | * @example helloworld_rx.ino |
akashvibhute | 0:c3db0798d9aa | 857 | * |
akashvibhute | 0:c3db0798d9aa | 858 | * Simplest possible example of using RF24Network. Put this sketch |
akashvibhute | 0:c3db0798d9aa | 859 | * on one node, and helloworld_tx.pde on the other. Tx will send |
akashvibhute | 0:c3db0798d9aa | 860 | * Rx a nice message every 2 seconds which rx will print out for us. |
akashvibhute | 0:c3db0798d9aa | 861 | */ |
akashvibhute | 0:c3db0798d9aa | 862 | |
akashvibhute | 0:c3db0798d9aa | 863 | /** |
akashvibhute | 2:a5f8e04bd02b | 864 | * @example Network_Ping.ino |
akashvibhute | 0:c3db0798d9aa | 865 | * |
akashvibhute | 2:a5f8e04bd02b | 866 | * Example to give users an understanding of addressing and topology in the mesh network |
akashvibhute | 0:c3db0798d9aa | 867 | * Using this sketch, each node will send a ping to the base every |
akashvibhute | 0:c3db0798d9aa | 868 | * few seconds. The RF24Network library will route the message across |
akashvibhute | 0:c3db0798d9aa | 869 | * the mesh to the correct node. |
akashvibhute | 2:a5f8e04bd02b | 870 | * |
akashvibhute | 2:a5f8e04bd02b | 871 | */ |
akashvibhute | 2:a5f8e04bd02b | 872 | |
akashvibhute | 2:a5f8e04bd02b | 873 | /** |
akashvibhute | 2:a5f8e04bd02b | 874 | * @example Network_Ping_Sleep.ino |
akashvibhute | 2:a5f8e04bd02b | 875 | * |
akashvibhute | 2:a5f8e04bd02b | 876 | * Example: This is almost exactly the same as the Network_Ping example, but with use |
akashvibhute | 2:a5f8e04bd02b | 877 | * of the integrated sleep mode. |
akashvibhute | 2:a5f8e04bd02b | 878 | * |
akashvibhute | 2:a5f8e04bd02b | 879 | * This example demonstrates how nodes on the network utilize sleep mode to conserve power. For example, |
akashvibhute | 2:a5f8e04bd02b | 880 | * the radio itself will draw about 13.5mA in receive mode. In sleep mode, it will use as little as 22ua (.000022mA) |
akashvibhute | 2:a5f8e04bd02b | 881 | * of power when not actively transmitting or receiving data. In addition, the Arduino is powered down as well, |
akashvibhute | 2:a5f8e04bd02b | 882 | * dropping network power consumption dramatically compared to previous capabilities. <br> |
akashvibhute | 2:a5f8e04bd02b | 883 | * Note: Sleeping nodes generate traffic that will wake other nodes up. This may be mitigated with further modifications. Sleep |
akashvibhute | 2:a5f8e04bd02b | 884 | * payloads are currently always routed to the master node, which will wake up intermediary nodes. Routing nodes can be configured |
akashvibhute | 2:a5f8e04bd02b | 885 | * to go back to sleep immediately. |
akashvibhute | 2:a5f8e04bd02b | 886 | * The displayed millis() count will give an indication of how much a node has been sleeping compared to the others, as millis() will |
akashvibhute | 2:a5f8e04bd02b | 887 | * not increment while a node sleeps. |
akashvibhute | 2:a5f8e04bd02b | 888 | *<br> |
akashvibhute | 2:a5f8e04bd02b | 889 | * - Using this sketch, each node will send a ping to every other node in the network every few seconds.<br> |
akashvibhute | 2:a5f8e04bd02b | 890 | * - The RF24Network library will route the message across the mesh to the correct node.<br> |
akashvibhute | 2:a5f8e04bd02b | 891 | * |
akashvibhute | 0:c3db0798d9aa | 892 | */ |
akashvibhute | 0:c3db0798d9aa | 893 | |
akashvibhute | 0:c3db0798d9aa | 894 | /** |
akashvibhute | 0:c3db0798d9aa | 895 | * @example sensornet.pde |
akashvibhute | 0:c3db0798d9aa | 896 | * |
akashvibhute | 0:c3db0798d9aa | 897 | * Example of a sensor network. |
akashvibhute | 0:c3db0798d9aa | 898 | * This sketch demonstrates how to use the RF24Network library to |
akashvibhute | 0:c3db0798d9aa | 899 | * manage a set of low-power sensor nodes which mostly sleep but |
akashvibhute | 0:c3db0798d9aa | 900 | * awake regularly to send readings to the base. |
akashvibhute | 0:c3db0798d9aa | 901 | */ |
akashvibhute | 0:c3db0798d9aa | 902 | /** |
akashvibhute | 0:c3db0798d9aa | 903 | * @mainpage Network Layer for RF24 Radios |
akashvibhute | 0:c3db0798d9aa | 904 | * |
akashvibhute | 0:c3db0798d9aa | 905 | * This class implements an <a href="http://en.wikipedia.org/wiki/Network_layer">OSI Network Layer</a> using nRF24L01(+) radios driven |
akashvibhute | 2:a5f8e04bd02b | 906 | * by the newly optimized <a href="http://tmrh20.github.com/RF24/">RF24</a> library fork. |
akashvibhute | 0:c3db0798d9aa | 907 | * |
akashvibhute | 0:c3db0798d9aa | 908 | * @section Purpose Purpose/Goal |
akashvibhute | 0:c3db0798d9aa | 909 | * |
akashvibhute | 2:a5f8e04bd02b | 910 | * Original: Create an alternative to ZigBee radios for Arduino communication. |
akashvibhute | 2:a5f8e04bd02b | 911 | * |
akashvibhute | 2:a5f8e04bd02b | 912 | * New: Enhance the current functionality for maximum efficiency, reliability, and speed |
akashvibhute | 0:c3db0798d9aa | 913 | * |
akashvibhute | 2:a5f8e04bd02b | 914 | * Xbees are excellent little radios, backed up by a mature and robust standard |
akashvibhute | 0:c3db0798d9aa | 915 | * protocol stack. They are also expensive. |
akashvibhute | 0:c3db0798d9aa | 916 | * |
akashvibhute | 2:a5f8e04bd02b | 917 | * For many Arduino uses, they seem like overkill. So I am working to improve the current |
akashvibhute | 2:a5f8e04bd02b | 918 | * standard for nRF24L01 radios. The best RF24 modules are available for less than |
akashvibhute | 0:c3db0798d9aa | 919 | * $6 from many sources. With the RF24Network layer, I hope to cover many |
akashvibhute | 0:c3db0798d9aa | 920 | * common communication scenarios. |
akashvibhute | 0:c3db0798d9aa | 921 | * |
akashvibhute | 0:c3db0798d9aa | 922 | * Please see the @ref Zigbee page for a comparison against the ZigBee protocols |
akashvibhute | 0:c3db0798d9aa | 923 | * |
akashvibhute | 0:c3db0798d9aa | 924 | * @section Features Features |
akashvibhute | 0:c3db0798d9aa | 925 | * |
akashvibhute | 2:a5f8e04bd02b | 926 | * <b>Whats new? </b><br> |
akashvibhute | 2:a5f8e04bd02b | 927 | * @li New: (Dec 8) Merge of RPi and Arduino code. Finally moving closer to a stable release. Report issues at https://github.com/TMRh20/RF24Network/issues |
akashvibhute | 2:a5f8e04bd02b | 928 | * @li New functionality: (Dec 8) Support for fragmented multicast payloads on both RPi and Arduino |
akashvibhute | 2:a5f8e04bd02b | 929 | * @li New functionality: (Nov 24) Fragmentation & reassembly supported on both RPi and Arduino |
akashvibhute | 2:a5f8e04bd02b | 930 | * @li Note: structure of network frames is changed, these are only used by external applications like RF24Ethernet and RF24toTUN, and for fragmentation |
akashvibhute | 2:a5f8e04bd02b | 931 | * @li New functionality: User message types 1 through 64 will not receive a network ack |
akashvibhute | 2:a5f8e04bd02b | 932 | * |
akashvibhute | 0:c3db0798d9aa | 933 | * The layer provides: |
akashvibhute | 2:a5f8e04bd02b | 934 | * @li <b>New</b> (2014): Network ACKs: Efficient acknowledgement of network-wide transmissions, via dynamic radio acks and network protocol acks. |
akashvibhute | 2:a5f8e04bd02b | 935 | * @li <b>New</b> (2014): Updated addressing standard for optimal radio transmission. |
akashvibhute | 2:a5f8e04bd02b | 936 | * @li <b>New</b> (2014): Extended timeouts and staggered timeout intervals. The new txTimeout variable allows fully automated extended timeout periods via auto-retry/auto-reUse of payloads. |
akashvibhute | 2:a5f8e04bd02b | 937 | * @li <b>New</b> (2014): Optimization to the core library provides improvements to reliability, speed and efficiency. See https://tmrh20.github.io/RF24 for more info. |
akashvibhute | 2:a5f8e04bd02b | 938 | * @li <b>New</b> (2014): Built in sleep mode using interrupts. (Still under development. (Enable via RF24Network_config.h)) |
akashvibhute | 2:a5f8e04bd02b | 939 | * @li <b>New</b> (2014): Dual headed operation: The use of dual radios for busy routing nodes or the master node enhances throughput and decreases errors. See the <a href="Tuning.html">Tuning</a> section. |
akashvibhute | 0:c3db0798d9aa | 940 | * @li Host Addressing. Each node has a logical address on the local network. |
akashvibhute | 0:c3db0798d9aa | 941 | * @li Message Forwarding. Messages can be sent from one node to any other, and |
akashvibhute | 0:c3db0798d9aa | 942 | * this layer will get them there no matter how many hops it takes. |
akashvibhute | 0:c3db0798d9aa | 943 | * @li Ad-hoc Joining. A node can join a network without any changes to any |
akashvibhute | 0:c3db0798d9aa | 944 | * existing nodes. |
akashvibhute | 0:c3db0798d9aa | 945 | * |
akashvibhute | 2:a5f8e04bd02b | 946 | * The layer does not provide: |
akashvibhute | 2:a5f8e04bd02b | 947 | * @li Dynamic address assignment. (See RF24Mesh) |
akashvibhute | 2:a5f8e04bd02b | 948 | * @li Layer 4 protocols (TCP/IP - See RF24Ethernet and RF24toTUN) |
akashvibhute | 0:c3db0798d9aa | 949 | * |
akashvibhute | 0:c3db0798d9aa | 950 | * @section More How to learn more |
akashvibhute | 0:c3db0798d9aa | 951 | * |
akashvibhute | 0:c3db0798d9aa | 952 | * @li <a href="classRF24Network.html">RF24Network Class Documentation</a> |
akashvibhute | 2:a5f8e04bd02b | 953 | * @li <a href="AdvancedConfig.html"> Advanced Configuration Options</a> |
akashvibhute | 2:a5f8e04bd02b | 954 | * @li <a href="Addressing.html"> Addressing format</a> |
akashvibhute | 2:a5f8e04bd02b | 955 | * @li <a href="Tuning.html"> Topology and Overview</a> |
akashvibhute | 2:a5f8e04bd02b | 956 | * @li <a href="https://github.com/TMRh20/RF24Network/archive/Development.zip">Download Current Development Package</a> |
akashvibhute | 2:a5f8e04bd02b | 957 | * @li <a href="examples.html">Examples Page</a>. Start with <a href="helloworld_rx_8ino-example.html">helloworld_rx</a> and <a href="helloworld_tx_8ino-example.html">helloworld_tx</a>. |
akashvibhute | 0:c3db0798d9aa | 958 | * |
akashvibhute | 2:a5f8e04bd02b | 959 | * <b> Additional Information & Add-ons </b> |
akashvibhute | 2:a5f8e04bd02b | 960 | * @li <a href="https://github.com/TMRh20/RF24Mesh">RF24Mesh: Dynamic Mesh Layer for RF24Network Dev</a> |
akashvibhute | 2:a5f8e04bd02b | 961 | * @li <a href="https://github.com/TMRh20/RF24Ethernet">RF24Ethernet: TCP/IP over RF24Network</a> |
akashvibhute | 2:a5f8e04bd02b | 962 | * @li <a href="http://tmrh20.blogspot.com/2014/03/high-speed-data-transfers-and-wireless.html">My Blog: RF24 Optimization Overview</a> |
akashvibhute | 2:a5f8e04bd02b | 963 | * @li <a href="http://tmrh20.blogspot.com/2014/03/arduino-radiointercomwireless-audio.html">My Blog: RF24 Wireless Audio</a> |
akashvibhute | 2:a5f8e04bd02b | 964 | * @li <a href="http://maniacbug.github.com/RF24/">RF24: Original Author</a> |
akashvibhute | 0:c3db0798d9aa | 965 | * @section Topology Topology for Mesh Networks using nRF24L01(+) |
akashvibhute | 0:c3db0798d9aa | 966 | * |
akashvibhute | 0:c3db0798d9aa | 967 | * This network layer takes advantage of the fundamental capability of the nRF24L01(+) radio to |
akashvibhute | 2:a5f8e04bd02b | 968 | * listen actively to up to 6 other radios at once. The network is arranged in a |
akashvibhute | 0:c3db0798d9aa | 969 | * <a href="http://en.wikipedia.org/wiki/Network_Topology#Tree">Tree Topology</a>, where |
akashvibhute | 0:c3db0798d9aa | 970 | * one node is the base, and all other nodes are children either of that node, or of another. |
akashvibhute | 0:c3db0798d9aa | 971 | * Unlike a true mesh network, multiple nodes are not connected together, so there is only one |
akashvibhute | 0:c3db0798d9aa | 972 | * path to any given node. |
akashvibhute | 0:c3db0798d9aa | 973 | * |
akashvibhute | 2:a5f8e04bd02b | 974 | * @section Octal Octal Addressing and Topology |
akashvibhute | 0:c3db0798d9aa | 975 | * |
akashvibhute | 0:c3db0798d9aa | 976 | * Each node must be assigned an 15-bit address by the administrator. This address exactly |
akashvibhute | 0:c3db0798d9aa | 977 | * describes the position of the node within the tree. The address is an octal number. Each |
akashvibhute | 0:c3db0798d9aa | 978 | * digit in the address represents a position in the tree further from the base. |
akashvibhute | 0:c3db0798d9aa | 979 | * |
akashvibhute | 0:c3db0798d9aa | 980 | * @li Node 00 is the base node. |
akashvibhute | 0:c3db0798d9aa | 981 | * @li Nodes 01-05 are nodes whose parent is the base. |
akashvibhute | 0:c3db0798d9aa | 982 | * @li Node 021 is the second child of node 01. |
akashvibhute | 0:c3db0798d9aa | 983 | * @li Node 0321 is the third child of node 021, an so on. |
akashvibhute | 0:c3db0798d9aa | 984 | * @li The largest node address is 05555, so 3,125 nodes are allowed on a single channel. |
akashvibhute | 2:a5f8e04bd02b | 985 | * An example topology is shown below, with 5 nodes in direct communication with the master node, |
akashvibhute | 2:a5f8e04bd02b | 986 | * and multiple leaf nodes spread out at a distance, using intermediate nodes to reach other nodes. |
akashvibhute | 2:a5f8e04bd02b | 987 | * |
akashvibhute | 2:a5f8e04bd02b | 988 | *| | | 00 | | | 00 | | | | Master Node (00) | |
akashvibhute | 2:a5f8e04bd02b | 989 | *|---|----|----|----|----|----|----|----|----|-----------------------------------------------------| |
akashvibhute | 2:a5f8e04bd02b | 990 | *| | | 01 | | | 04 | | | | 1st level children of master (00) | |
akashvibhute | 2:a5f8e04bd02b | 991 | *| | 011| | 021| | |014 | | | 2nd level children of master. Children of 1st level.| |
akashvibhute | 2:a5f8e04bd02b | 992 | *|111| | | 121| 221| | | 114| | 3rd level children of master. Children of 2nd level.| |
akashvibhute | 2:a5f8e04bd02b | 993 | *| | | | |1221| |1114|2114|3114| 4th level children of master. Children of 3rd level.| |
akashvibhute | 0:c3db0798d9aa | 994 | * |
akashvibhute | 0:c3db0798d9aa | 995 | * @section Routing How routing is handled |
akashvibhute | 0:c3db0798d9aa | 996 | * |
akashvibhute | 0:c3db0798d9aa | 997 | * When sending a message using RF24Network::write(), you fill in the header with the logical |
akashvibhute | 0:c3db0798d9aa | 998 | * node address. The network layer figures out the right path to find that node, and sends |
akashvibhute | 0:c3db0798d9aa | 999 | * it through the system until it gets to the right place. This works even if the two nodes |
akashvibhute | 0:c3db0798d9aa | 1000 | * are far separated, as it will send the message down to the base node, and then back out |
akashvibhute | 0:c3db0798d9aa | 1001 | * to the final destination. |
akashvibhute | 0:c3db0798d9aa | 1002 | * |
akashvibhute | 0:c3db0798d9aa | 1003 | * All of this work is handled by the RF24Network::update() method, so be sure to call it |
akashvibhute | 0:c3db0798d9aa | 1004 | * regularly or your network will miss packets. |
akashvibhute | 0:c3db0798d9aa | 1005 | * |
akashvibhute | 0:c3db0798d9aa | 1006 | * @section Startup Starting up a node |
akashvibhute | 0:c3db0798d9aa | 1007 | * |
akashvibhute | 0:c3db0798d9aa | 1008 | * When a node starts up, it only has to contact its parent to establish communication. |
akashvibhute | 0:c3db0798d9aa | 1009 | * No direct connection to the Base node is needed. This is useful in situations where |
akashvibhute | 0:c3db0798d9aa | 1010 | * relay nodes are being used to bridge the distance to the base, so leaf nodes are out |
akashvibhute | 0:c3db0798d9aa | 1011 | * of range of the base. |
akashvibhute | 0:c3db0798d9aa | 1012 | * |
akashvibhute | 2:a5f8e04bd02b | 1013 | * @section Directionality Directionality |
akashvibhute | 0:c3db0798d9aa | 1014 | * |
akashvibhute | 0:c3db0798d9aa | 1015 | * By default all nodes are always listening, so messages will quickly reach |
akashvibhute | 2:a5f8e04bd02b | 1016 | * their destination. |
akashvibhute | 2:a5f8e04bd02b | 1017 | * |
akashvibhute | 2:a5f8e04bd02b | 1018 | * You may choose to sleep any nodes on the network if using interrupts. This is useful in a |
akashvibhute | 2:a5f8e04bd02b | 1019 | * case where the nodes are operating on batteries and need to sleep. This greatly decreases |
akashvibhute | 2:a5f8e04bd02b | 1020 | * the power requirements for a sensor network. The leaf nodes can sleep most of the time, |
akashvibhute | 2:a5f8e04bd02b | 1021 | * and wake every few minutes to send in a reading. Routing nodes can be triggered to wake up |
akashvibhute | 2:a5f8e04bd02b | 1022 | * whenever a payload is received See sleepNode() in the class documentation, and RFNetwork_config.h |
akashvibhute | 2:a5f8e04bd02b | 1023 | * to enable sleep mode. |
akashvibhute | 2:a5f8e04bd02b | 1024 | * |
akashvibhute | 2:a5f8e04bd02b | 1025 | * |
akashvibhute | 2:a5f8e04bd02b | 1026 | * @page Addressing Addressing Format: Understanding Addressing and Topology |
akashvibhute | 2:a5f8e04bd02b | 1027 | * An overview of addressing in RF24Network |
akashvibhute | 2:a5f8e04bd02b | 1028 | * |
akashvibhute | 2:a5f8e04bd02b | 1029 | * @section Overview Overview |
akashvibhute | 2:a5f8e04bd02b | 1030 | * The nrf24 radio modules typically use a 40-bit address format, requiring 5-bytes of storage space per address, and allowing a wide |
akashvibhute | 2:a5f8e04bd02b | 1031 | * array of addresses to be utilized. In addition, the radios are limited to direct communication with 6 other nodes while using the |
akashvibhute | 2:a5f8e04bd02b | 1032 | * Enhanced-Shock-Burst (ESB) functionality of the radios. |
akashvibhute | 2:a5f8e04bd02b | 1033 | * |
akashvibhute | 2:a5f8e04bd02b | 1034 | * RF24Network uses a simple method of data compression to store the addresses using only 2 bytes, in a format designed to represent the |
akashvibhute | 2:a5f8e04bd02b | 1035 | * network topology in an intuitive way. |
akashvibhute | 2:a5f8e04bd02b | 1036 | * See the <a href="Tuning.html"> Topology and Overview</a> page for more info regarding topology. |
akashvibhute | 2:a5f8e04bd02b | 1037 | * |
akashvibhute | 2:a5f8e04bd02b | 1038 | * @section Octal_Binary Decimal, Octal and Binary formats |
akashvibhute | 2:a5f8e04bd02b | 1039 | * |
akashvibhute | 2:a5f8e04bd02b | 1040 | * Say we want to designate a logical address to a node, using a tree topology as defined by the manufacturer. |
akashvibhute | 2:a5f8e04bd02b | 1041 | * In the simplest format, we could assign the first node the address of 1, the second 2 and so on. |
akashvibhute | 2:a5f8e04bd02b | 1042 | * Since a single node can only connect to 6 other nodes (1 parent and 5 children) subnets need to be created if using more than 6 nodes.<br> |
akashvibhute | 2:a5f8e04bd02b | 1043 | * In this case the children of node 1 could simply be designated as 11,21,31,41, and 51<br> |
akashvibhute | 2:a5f8e04bd02b | 1044 | * Children of node 2 could be designated as 12,22,32,42, and 52 |
akashvibhute | 2:a5f8e04bd02b | 1045 | * |
akashvibhute | 2:a5f8e04bd02b | 1046 | * The above example is exactly how RF24Network manages the addresses, but they are represented in Octal format. |
akashvibhute | 2:a5f8e04bd02b | 1047 | * |
akashvibhute | 2:a5f8e04bd02b | 1048 | * <b>Decimal, Octal and Binary</b> |
akashvibhute | 2:a5f8e04bd02b | 1049 | * <table> |
akashvibhute | 2:a5f8e04bd02b | 1050 | * <tr bgcolor="#a3b4d7" > |
akashvibhute | 2:a5f8e04bd02b | 1051 | * <td> Decimal </td> <td> Binary </td><td> Decimal </td> <td> Binary </td><td> Decimal </td> <td> Binary </td> |
akashvibhute | 2:a5f8e04bd02b | 1052 | * </tr><tr> |
akashvibhute | 2:a5f8e04bd02b | 1053 | * <td> 1 </td> <td> 00000001 </td><td> 11 </td> <td> 00001011 </td><td> 111 </td> <td> 01101111 </td> |
akashvibhute | 2:a5f8e04bd02b | 1054 | * </tr><tr bgcolor="#a3b4d7" > |
akashvibhute | 2:a5f8e04bd02b | 1055 | * <td> Octal </td> <td> Binary </td><td> Octal </td> <td> Binary </td><td> Octal </td> <td> Binary </td> |
akashvibhute | 2:a5f8e04bd02b | 1056 | * </tr><tr> |
akashvibhute | 2:a5f8e04bd02b | 1057 | * <td> 1 </td> <td> 00000001 </td><td> 011 </td> <td> 00001001 </td><td> 0111 </td> <td> 1001001 </td> |
akashvibhute | 2:a5f8e04bd02b | 1058 | * </tr> |
akashvibhute | 2:a5f8e04bd02b | 1059 | * </table> |
akashvibhute | 2:a5f8e04bd02b | 1060 | * |
akashvibhute | 2:a5f8e04bd02b | 1061 | * |
akashvibhute | 2:a5f8e04bd02b | 1062 | * Since the numbers 0-7 can be represented in exactly three bits, each digit is represented by exactly 3 bits when viewed in octal format. |
akashvibhute | 2:a5f8e04bd02b | 1063 | * This allows a very simple method of managing addresses via masking and bit shifting. |
akashvibhute | 2:a5f8e04bd02b | 1064 | * |
akashvibhute | 2:a5f8e04bd02b | 1065 | * @section DisplayAddresses Displaying Addresses |
akashvibhute | 2:a5f8e04bd02b | 1066 | * |
akashvibhute | 2:a5f8e04bd02b | 1067 | * When using Arduino devices, octal addresses can be printed in the following manner: |
akashvibhute | 2:a5f8e04bd02b | 1068 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1069 | * uint16_t address = 0111; |
akashvibhute | 2:a5f8e04bd02b | 1070 | * Serial.println(address,OCT); |
akashvibhute | 2:a5f8e04bd02b | 1071 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1072 | * |
akashvibhute | 2:a5f8e04bd02b | 1073 | * Printf can also be used, if enabled, or if using linux/RPi |
akashvibhute | 2:a5f8e04bd02b | 1074 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1075 | * uint16_t address = 0111; |
akashvibhute | 2:a5f8e04bd02b | 1076 | * printf("0%o\n",address); |
akashvibhute | 2:a5f8e04bd02b | 1077 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1078 | * |
akashvibhute | 2:a5f8e04bd02b | 1079 | * See http://www.cplusplus.com/doc/hex/ for more information<br> |
akashvibhute | 2:a5f8e04bd02b | 1080 | * See the <a href="Tuning.html"> Topology and Overview</a> page for more info regarding topology. |
akashvibhute | 2:a5f8e04bd02b | 1081 | * |
akashvibhute | 2:a5f8e04bd02b | 1082 | * @page AdvancedConfig Advanced Configuration |
akashvibhute | 2:a5f8e04bd02b | 1083 | * |
akashvibhute | 2:a5f8e04bd02b | 1084 | * RF24Network offers many features, some of which can be configured by editing the RF24Network_config.h file |
akashvibhute | 2:a5f8e04bd02b | 1085 | * |
akashvibhute | 2:a5f8e04bd02b | 1086 | * | Configuration Option | Description | |
akashvibhute | 2:a5f8e04bd02b | 1087 | * |----------------------|-------------| |
akashvibhute | 2:a5f8e04bd02b | 1088 | * |<b> #define RF24NetworkMulticast </b> | This option allows nodes to send and receive multicast payloads. Nodes with multicast enabled can also be configured to relay multicast payloads on to further multicast levels. See multicastRelay | |
akashvibhute | 2:a5f8e04bd02b | 1089 | * | <b> #define DISABLE_FRAGMENTATION </b> | Fragmentation is enabled by default, and uses an additional 144 bytes of memory. | |
akashvibhute | 2:a5f8e04bd02b | 1090 | * | <b> #define MAX_PAYLOAD_SIZE 144 </b> | The maximum size of payloads defaults to 144 bytes. If used with RF24toTUN and two Raspberry Pi, set this to 1514 (TAP) or 1500 (TUN) | |
akashvibhute | 2:a5f8e04bd02b | 1091 | * | <b> #define NUM_USER_PAYLOADS 5 </b> | This is the number of 24-byte payloads the network layer will cache for the user. If using fragmentation, this number * 24 must be larger than MAX_PAYLOAD_SIZE | |
akashvibhute | 2:a5f8e04bd02b | 1092 | * | <b> #define DISABLE_USER_PAYLOADS </b> | This option will disable user-caching of payloads entirely. Use with RF24Ethernet to reduce memory usage. (TCP/IP is an external data type, and not cached) | |
akashvibhute | 2:a5f8e04bd02b | 1093 | * | <b> #define ENABLE_SLEEP_MODE </b> | Uncomment this option to enable sleep mode for AVR devices. (ATTiny,Uno, etc) | |
akashvibhute | 2:a5f8e04bd02b | 1094 | * | <b> #define DUAL_HEAD_RADIO </b> | Uncomment this option to enable use of dual radios | |
akashvibhute | 2:a5f8e04bd02b | 1095 | * | **#define ENABLE_NETWORK_STATS** | Enable counting of all successful or failed transmissions, routed or sent directly | |
akashvibhute | 2:a5f8e04bd02b | 1096 | * |
akashvibhute | 2:a5f8e04bd02b | 1097 | ** @page Tuning Performance and Data Loss: Tuning the Network |
akashvibhute | 2:a5f8e04bd02b | 1098 | * Tips and examples for tuning the network and general operation. |
akashvibhute | 2:a5f8e04bd02b | 1099 | * |
akashvibhute | 2:a5f8e04bd02b | 1100 | * <img src="tmrh20/topologyImage.jpg" alt="Topology" height="75%" width="75%"> |
akashvibhute | 2:a5f8e04bd02b | 1101 | * |
akashvibhute | 2:a5f8e04bd02b | 1102 | * @section General Understanding Radio Communication and Topology |
akashvibhute | 2:a5f8e04bd02b | 1103 | * When a transmission takes place from one radio module to another, the receiving radio will communicate |
akashvibhute | 2:a5f8e04bd02b | 1104 | * back to the sender with an acknowledgement (ACK) packet, to indicate success. If the sender does not |
akashvibhute | 2:a5f8e04bd02b | 1105 | * receive an ACK, the radio automatically engages in a series of timed retries, at set intervals. The |
akashvibhute | 2:a5f8e04bd02b | 1106 | * radios use techniques like addressing and numbering of payloads to manage this, but it is all done |
akashvibhute | 2:a5f8e04bd02b | 1107 | * automatically by the nrf chip, out of sight from the user. |
akashvibhute | 2:a5f8e04bd02b | 1108 | * |
akashvibhute | 2:a5f8e04bd02b | 1109 | * When working over a radio network, some of these automated techniques can actually hinder data transmission to a degree. |
akashvibhute | 2:a5f8e04bd02b | 1110 | * Retrying failed payloads over and over on a radio network can hinder communication for nearby nodes, or |
akashvibhute | 2:a5f8e04bd02b | 1111 | * reduce throughput and errors on routing nodes. |
akashvibhute | 2:a5f8e04bd02b | 1112 | * |
akashvibhute | 2:a5f8e04bd02b | 1113 | * Radios in this network are linked by <b>addresses</b> assigned to <b>pipes</b>. Each radio can listen |
akashvibhute | 2:a5f8e04bd02b | 1114 | * to 6 addresses on 6 pipes, therefore each radio has a parent pipe and 5 child pipes, which are used |
akashvibhute | 2:a5f8e04bd02b | 1115 | * to form a tree structure. Nodes communicate directly with their parent and children nodes. Any other |
akashvibhute | 2:a5f8e04bd02b | 1116 | * traffic to or from a node must be routed through the network. |
akashvibhute | 2:a5f8e04bd02b | 1117 | * |
akashvibhute | 2:a5f8e04bd02b | 1118 | * @section Topology Topology of RF24Network |
akashvibhute | 2:a5f8e04bd02b | 1119 | * |
akashvibhute | 2:a5f8e04bd02b | 1120 | * Anybody who is familiar at all with IP networking should be able to easily understand RF24Network topology. The |
akashvibhute | 2:a5f8e04bd02b | 1121 | * master node can be seen as the gateway, with up to 4 directly connected nodes. Each of those nodes creates a |
akashvibhute | 2:a5f8e04bd02b | 1122 | * subnet below it, with up to 4 additional child nodes. The numbering scheme can also be related to IP addresses, |
akashvibhute | 2:a5f8e04bd02b | 1123 | * for purposes of understanding the topology via subnetting. Nodes can have 5 children if multicast is disabled. |
akashvibhute | 2:a5f8e04bd02b | 1124 | * |
akashvibhute | 2:a5f8e04bd02b | 1125 | * Expressing RF24Network addresses in IP format: |
akashvibhute | 2:a5f8e04bd02b | 1126 | * |
akashvibhute | 2:a5f8e04bd02b | 1127 | * As an example, we could designate the master node in theory, as Address 10.10.10.10 <br> |
akashvibhute | 2:a5f8e04bd02b | 1128 | * The children nodes of the master would be 10.10.10.1, 10.10.10.2, 10.10.10.3, 10.10.10.4 and 10.10.10.5 <br> |
akashvibhute | 2:a5f8e04bd02b | 1129 | * The children nodes of 10.10.10.1 would be 10.10.1.1, 10.10.2.1, 10.10.3.1, 10.10.4.1 and 10.10.5.1 <br> |
akashvibhute | 2:a5f8e04bd02b | 1130 | * |
akashvibhute | 2:a5f8e04bd02b | 1131 | * In RF24Network, the master is just 00 <br> |
akashvibhute | 2:a5f8e04bd02b | 1132 | * Children of master are 01,02,03,04,05 <br> |
akashvibhute | 2:a5f8e04bd02b | 1133 | * Children of 01 are 011,021,031,041,051 <br> |
akashvibhute | 0:c3db0798d9aa | 1134 | * |
akashvibhute | 2:a5f8e04bd02b | 1135 | * @section Network Routing |
akashvibhute | 2:a5f8e04bd02b | 1136 | * |
akashvibhute | 2:a5f8e04bd02b | 1137 | * Routing of traffic is handled invisibly to the user, by the network layer. If the network addresses are |
akashvibhute | 2:a5f8e04bd02b | 1138 | * assigned in accordance with the physical layout of the network, nodes will route traffic automatically |
akashvibhute | 2:a5f8e04bd02b | 1139 | * as required. Users simply constuct a header containing the appropriate destination address, and the network |
akashvibhute | 2:a5f8e04bd02b | 1140 | * will forward it through to the correct node. Individual nodes only route individual fragments, so if using |
akashvibhute | 2:a5f8e04bd02b | 1141 | * fragmentation, routing nodes do not need it enabled, unless sending or receiving fragmented payloads themselves. |
akashvibhute | 2:a5f8e04bd02b | 1142 | * |
akashvibhute | 2:a5f8e04bd02b | 1143 | * If routing data between parent and child nodes (marked by direct links on the topology image above) the network |
akashvibhute | 2:a5f8e04bd02b | 1144 | * uses built-in acknowledgement and retry functions of the chip to prevent data loss. When payloads are sent to |
akashvibhute | 2:a5f8e04bd02b | 1145 | * other nodes, they need to be routed. Routing is managed using a combination of built in ACK requests, and |
akashvibhute | 2:a5f8e04bd02b | 1146 | * software driven network ACKs. This allows all routing nodes to forward data very quickly, with only the final |
akashvibhute | 2:a5f8e04bd02b | 1147 | * routing node confirming delivery and sending back an |
akashvibhute | 2:a5f8e04bd02b | 1148 | * acknowledgement. |
akashvibhute | 2:a5f8e04bd02b | 1149 | * |
akashvibhute | 2:a5f8e04bd02b | 1150 | * Example: Node 00 sends to node 01. The nodes will use the built in auto-retry and auto-ack functions.<br> |
akashvibhute | 2:a5f8e04bd02b | 1151 | * Example: Node 00 sends to node 011. Node 00 will send to node 01 as before. Node 01 will forward the message to |
akashvibhute | 2:a5f8e04bd02b | 1152 | * 011. If delivery was successful, node 01 will also forward a message back to node 00, indicating success. |
akashvibhute | 2:a5f8e04bd02b | 1153 | * |
akashvibhute | 2:a5f8e04bd02b | 1154 | * Old Functionality: Node 00 sends to node 011 using auto-ack. Node 00 first sends to 01, 01 acknowledges. |
akashvibhute | 2:a5f8e04bd02b | 1155 | * Node 01 forwards the payload to 011 using auto-ack. If the payload fails between 01 and 011, node 00 has |
akashvibhute | 2:a5f8e04bd02b | 1156 | * no way of knowing. |
akashvibhute | 2:a5f8e04bd02b | 1157 | * |
akashvibhute | 2:a5f8e04bd02b | 1158 | * @note When retrying failed payloads that have been routed, there is a chance of duplicate payloads if the network-ack |
akashvibhute | 2:a5f8e04bd02b | 1159 | * is not successful. In this case, it is left up to the user to manage retries and filtering of duplicate payloads. |
akashvibhute | 2:a5f8e04bd02b | 1160 | * |
akashvibhute | 2:a5f8e04bd02b | 1161 | * Acknowledgements can and should be managed by the application or user. If requesting a response from another node, |
akashvibhute | 2:a5f8e04bd02b | 1162 | * an acknowledgement is not required, so a user defined type of 0-64 should be used, to prevent the network from |
akashvibhute | 2:a5f8e04bd02b | 1163 | * responding with an acknowledgement. If not requesting a response, and wanting to know if the payload was successful |
akashvibhute | 2:a5f8e04bd02b | 1164 | * or not, users can utilize header types 65-127. |
akashvibhute | 2:a5f8e04bd02b | 1165 | * |
akashvibhute | 2:a5f8e04bd02b | 1166 | * @section TuningOverview Tuning Overview |
akashvibhute | 2:a5f8e04bd02b | 1167 | * The RF24 radio modules are generally only capable of either sending or receiving data at any given |
akashvibhute | 2:a5f8e04bd02b | 1168 | * time, but have built-in auto-retry mechanisms to prevent the loss of data. These values are adjusted |
akashvibhute | 2:a5f8e04bd02b | 1169 | * automatically by the library on startup, but can be further adjusted to reduce data loss, and |
akashvibhute | 2:a5f8e04bd02b | 1170 | * thus increase throughput of the network. This page is intended to provide a general overview of its |
akashvibhute | 2:a5f8e04bd02b | 1171 | * operation within the context of the network library, and provide guidance for adjusting these values. |
akashvibhute | 2:a5f8e04bd02b | 1172 | * |
akashvibhute | 2:a5f8e04bd02b | 1173 | * @section RetryTiming Auto-Retry Timing |
akashvibhute | 2:a5f8e04bd02b | 1174 | * |
akashvibhute | 2:a5f8e04bd02b | 1175 | * The core radio library provides the functionality of adjusting the internal auto-retry interval of the |
akashvibhute | 2:a5f8e04bd02b | 1176 | * radio modules. In the network configuration, the radios can be set to automatically retry failed |
akashvibhute | 2:a5f8e04bd02b | 1177 | * transmissions at intervals ranging anywhere from 500us (.5ms) up to 4000us (4ms). When operating any |
akashvibhute | 2:a5f8e04bd02b | 1178 | * number of radios larger than two, it is important to stagger the assigned intervals, to prevent the |
akashvibhute | 2:a5f8e04bd02b | 1179 | * radios from interfering with each other at the radio frequency (RF) layer. |
akashvibhute | 2:a5f8e04bd02b | 1180 | * |
akashvibhute | 2:a5f8e04bd02b | 1181 | * The library should provide fairly good working values, as it simply staggers the assigned values within |
akashvibhute | 2:a5f8e04bd02b | 1182 | * groups of radios in direct communication. This value can be set manually by calling radio.setRetries(X,15); |
akashvibhute | 2:a5f8e04bd02b | 1183 | * and adjusting the value of X from 1 to 15 (steps of 250us). |
akashvibhute | 2:a5f8e04bd02b | 1184 | * |
akashvibhute | 2:a5f8e04bd02b | 1185 | * @section AutoRetry Auto-Retry Count and Extended Timeouts |
akashvibhute | 2:a5f8e04bd02b | 1186 | * |
akashvibhute | 2:a5f8e04bd02b | 1187 | * The core radio library also provides the ability to adjust the internal auto-retry count of the radio |
akashvibhute | 2:a5f8e04bd02b | 1188 | * modules. The default setting is 15 automatic retries per payload, and can be extended by configuring |
akashvibhute | 2:a5f8e04bd02b | 1189 | * the network.txTimeout variable. This default retry count should generally be left at 15, as per the |
akashvibhute | 2:a5f8e04bd02b | 1190 | * example in the above section. An interval/retry setting of (15,15) will provide 15 retrys at intervals of |
akashvibhute | 2:a5f8e04bd02b | 1191 | * 4ms, taking up to 60ms per payload. The library now provides staggered timeout periods by default, but |
akashvibhute | 2:a5f8e04bd02b | 1192 | * they can also be adjusted on a per-node basis. |
akashvibhute | 0:c3db0798d9aa | 1193 | * |
akashvibhute | 2:a5f8e04bd02b | 1194 | * The txTimeout variable is used to extend the retry count to a defined duration in milliseconds. See the |
akashvibhute | 2:a5f8e04bd02b | 1195 | * network.txTimeout variable. Timeout periods of extended duration (500+) will generally not help when payloads |
akashvibhute | 2:a5f8e04bd02b | 1196 | * are failing due to data collisions, it will only extend the duration of the errors. Extended duration timeouts |
akashvibhute | 2:a5f8e04bd02b | 1197 | * should generally only be configured on leaf nodes that do not receive data, or on a dual-headed node. |
akashvibhute | 2:a5f8e04bd02b | 1198 | * |
akashvibhute | 2:a5f8e04bd02b | 1199 | * @section Examples |
akashvibhute | 2:a5f8e04bd02b | 1200 | * |
akashvibhute | 2:a5f8e04bd02b | 1201 | * <b>Example 1:</b> Network with master node and three leaf nodes that send data to the master node. None of the leaf |
akashvibhute | 2:a5f8e04bd02b | 1202 | * nodes need to receive data. |
akashvibhute | 2:a5f8e04bd02b | 1203 | * |
akashvibhute | 2:a5f8e04bd02b | 1204 | * a: Master node uses default configuration<br> |
akashvibhute | 2:a5f8e04bd02b | 1205 | * b: Leaf nodes can be configured with extended timeout periods to ensure reception by the master.<br> |
akashvibhute | 2:a5f8e04bd02b | 1206 | * c: |
akashvibhute | 2:a5f8e04bd02b | 1207 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1208 | * Leaf 01: network.txTimeout = 500; Leaf 02: network.txTimeout = 573; Leaf 03: network.txTimeout = 653; |
akashvibhute | 2:a5f8e04bd02b | 1209 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1210 | * This configuration will provide a reduction in errors, as the timeouts have been extended, and are staggered |
akashvibhute | 2:a5f8e04bd02b | 1211 | * between devices. |
akashvibhute | 2:a5f8e04bd02b | 1212 | * |
akashvibhute | 2:a5f8e04bd02b | 1213 | * |
akashvibhute | 2:a5f8e04bd02b | 1214 | * <b>Example 2:</b> Network with master node and three leaf nodes that send data to the master node. The second leaf |
akashvibhute | 2:a5f8e04bd02b | 1215 | * node needs to receive configuration data from the master at set intervals of 1 second, and send data back to the |
akashvibhute | 2:a5f8e04bd02b | 1216 | * master node. The other leaf nodes will send basic sensor information every few seconds, and a few dropped payloads |
akashvibhute | 2:a5f8e04bd02b | 1217 | * will not affect the operation greatly. |
akashvibhute | 2:a5f8e04bd02b | 1218 | * |
akashvibhute | 2:a5f8e04bd02b | 1219 | * a: Master node configured with extended timeouts of .5 seconds, and increased retry delay: |
akashvibhute | 2:a5f8e04bd02b | 1220 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1221 | * radio.setRetries(11,15); |
akashvibhute | 2:a5f8e04bd02b | 1222 | * network.txTimeout = 500; |
akashvibhute | 2:a5f8e04bd02b | 1223 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1224 | * b: Second leaf node configured with a similar timeout period and retry delay: |
akashvibhute | 2:a5f8e04bd02b | 1225 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1226 | * radio.setRetries(8,15); |
akashvibhute | 2:a5f8e04bd02b | 1227 | * network.txTimeout = 553; |
akashvibhute | 2:a5f8e04bd02b | 1228 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1229 | * c: First and third leaf nodes configured with default timeout periods or slightly increased timout periods. |
akashvibhute | 2:a5f8e04bd02b | 1230 | * |
akashvibhute | 2:a5f8e04bd02b | 1231 | * @section DualHead Dual Headed Operation |
akashvibhute | 2:a5f8e04bd02b | 1232 | * |
akashvibhute | 2:a5f8e04bd02b | 1233 | * The library now supports a dual radio configuration to further enhance network performance, while reducing errors on |
akashvibhute | 2:a5f8e04bd02b | 1234 | * busy networks. Master nodes or relay nodes with a large number of child nodes can benefit somewhat from a dual headed |
akashvibhute | 2:a5f8e04bd02b | 1235 | * configuration, since one radio is used for receiving, and the other entirely for transmission. |
akashvibhute | 2:a5f8e04bd02b | 1236 | * |
akashvibhute | 2:a5f8e04bd02b | 1237 | * To configure a dual headed node: |
akashvibhute | 2:a5f8e04bd02b | 1238 | * 1. Edit the RF24Network_config.h file, and uncomment #define DUAL_HEAD_RADIO |
akashvibhute | 2:a5f8e04bd02b | 1239 | * 2. Connect another radio, using the same MOSI, MISO, and SCK lines. |
akashvibhute | 2:a5f8e04bd02b | 1240 | * 3. Choose another two pins to use for CE and CS on the second radio. Connect them. |
akashvibhute | 2:a5f8e04bd02b | 1241 | * 4. Setup the radio and network like so: |
akashvibhute | 2:a5f8e04bd02b | 1242 | * |
akashvibhute | 2:a5f8e04bd02b | 1243 | * @code |
akashvibhute | 2:a5f8e04bd02b | 1244 | * RF24 radio(7,8); // Using CE (7) and CS (8) for first radio |
akashvibhute | 2:a5f8e04bd02b | 1245 | * RF24 radio1(4,5); // Using CE (4) and CS (5) for second radio |
akashvibhute | 2:a5f8e04bd02b | 1246 | * RF24Network network(radio,radio1); // Set up the network using both radios |
akashvibhute | 2:a5f8e04bd02b | 1247 | * |
akashvibhute | 2:a5f8e04bd02b | 1248 | * Then in setup(), call radio.begin(); and radio1.begin(); before network.begin(); |
akashvibhute | 2:a5f8e04bd02b | 1249 | * @endcode |
akashvibhute | 2:a5f8e04bd02b | 1250 | * |
akashvibhute | 2:a5f8e04bd02b | 1251 | * 5. Upload to MCU. The node will now use the first radio to receive data, and radio1 to transmit, preventing data loss on a busy network. |
akashvibhute | 2:a5f8e04bd02b | 1252 | * 6. Re-comment the #define in the config file as required if configuring other single-headed radios. |
akashvibhute | 2:a5f8e04bd02b | 1253 | * |
akashvibhute | 2:a5f8e04bd02b | 1254 | * |
akashvibhute | 2:a5f8e04bd02b | 1255 | * Any node can be configured in dual-head mode. |
akashvibhute | 2:a5f8e04bd02b | 1256 | * |
akashvibhute | 2:a5f8e04bd02b | 1257 | * |
akashvibhute | 2:a5f8e04bd02b | 1258 | * |
akashvibhute | 0:c3db0798d9aa | 1259 | * |
akashvibhute | 0:c3db0798d9aa | 1260 | * @page Zigbee Comparison to ZigBee |
akashvibhute | 0:c3db0798d9aa | 1261 | * |
akashvibhute | 0:c3db0798d9aa | 1262 | * This network layer is influenced by the design of ZigBee, but does not implement it |
akashvibhute | 2:a5f8e04bd02b | 1263 | * directly. |
akashvibhute | 0:c3db0798d9aa | 1264 | * |
akashvibhute | 0:c3db0798d9aa | 1265 | * @section Advantage Which is better? |
akashvibhute | 0:c3db0798d9aa | 1266 | * |
akashvibhute | 0:c3db0798d9aa | 1267 | * ZigBee is a much more robust, feature-rich set of protocols, with many different vendors |
akashvibhute | 0:c3db0798d9aa | 1268 | * providing compatible chips. |
akashvibhute | 0:c3db0798d9aa | 1269 | * |
akashvibhute | 0:c3db0798d9aa | 1270 | * RF24Network is cheap. While ZigBee radios are well over $20, nRF24L01 modules can be found |
akashvibhute | 2:a5f8e04bd02b | 1271 | * for under $2. My personal favorite is |
akashvibhute | 0:c3db0798d9aa | 1272 | * <a href="http://www.mdfly.com/index.php?main_page=product_info&products_id=82">MDFly RF-IS2401</a>. |
akashvibhute | 0:c3db0798d9aa | 1273 | * |
akashvibhute | 0:c3db0798d9aa | 1274 | * @section Contrast Similiarities & Differences |
akashvibhute | 0:c3db0798d9aa | 1275 | * |
akashvibhute | 0:c3db0798d9aa | 1276 | * Here are some comparisons between RF24Network and ZigBee. |
akashvibhute | 0:c3db0798d9aa | 1277 | * |
akashvibhute | 0:c3db0798d9aa | 1278 | * @li Both networks support Star and Tree topologies. Only Zigbee supports a true mesh. |
akashvibhute | 2:a5f8e04bd02b | 1279 | * @li In ZigBee networks, only leaf nodes can sleep |
akashvibhute | 2:a5f8e04bd02b | 1280 | * @li ZigBee nodes are configured using AT commands, or a separate Windows application. |
akashvibhute | 0:c3db0798d9aa | 1281 | * RF24 nodes are configured by recompiliing the firmware or writing to EEPROM. |
akashvibhute | 0:c3db0798d9aa | 1282 | * |
akashvibhute | 0:c3db0798d9aa | 1283 | * @section NodeNames Node Naming |
akashvibhute | 0:c3db0798d9aa | 1284 | * |
akashvibhute | 0:c3db0798d9aa | 1285 | * @li Leaf node: A node at the outer edge of the network with no children. ZigBee calls it |
akashvibhute | 0:c3db0798d9aa | 1286 | * an End Device node. |
akashvibhute | 0:c3db0798d9aa | 1287 | * @li Relay node: A node which has both parents and children, and relays messages from one |
akashvibhute | 0:c3db0798d9aa | 1288 | * to the other. ZigBee calls it a Router. |
akashvibhute | 0:c3db0798d9aa | 1289 | * @li Base node. The top of the tree node with no parents, only children. Typically this node |
akashvibhute | 0:c3db0798d9aa | 1290 | * will bridge to another kind of network like Ethernet. ZigBee calls it a Co-ordinator node. |
akashvibhute | 2:a5f8e04bd02b | 1291 | * |
akashvibhute | 2:a5f8e04bd02b | 1292 | * |
akashvibhute | 2:a5f8e04bd02b | 1293 | * |
akashvibhute | 2:a5f8e04bd02b | 1294 | * |
akashvibhute | 0:c3db0798d9aa | 1295 | */ |
akashvibhute | 0:c3db0798d9aa | 1296 | |
akashvibhute | 0:c3db0798d9aa | 1297 | #endif // __RF24NETWORK_H__ |
akashvibhute | 2:a5f8e04bd02b | 1298 |