forked from maniacbug/RF24
/
pingpair_sleepy_8pde-example.html
354 lines (293 loc) · 16.1 KB
/
pingpair_sleepy_8pde-example.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>RF24: pingpair_sleepy.pde</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen-custom.css" rel="stylesheet" type="text/css"/>
</head>
<body onload='searchBox.OnSelectItem(0);'>
<!-- Generated by Doxygen 1.7.4 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div id="top">
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">RF24 <span id="projectnumber">v1</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
<li id="searchli">
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
</div>
<div class="header">
<div class="headertitle">
<div class="title">pingpair_sleepy.pde</div> </div>
</div>
<div class="contents">
<p>This is an example of how to use the <a class="el" href="classRF24.html" title="Driver for nRF24L01(+) 2.4GHz Wireless Transceiver.">RF24</a> class to create a battery- efficient system. It is just like the pingpair.pde example, but the ping node powers down the radio and sleeps the MCU after every ping/pong cycle.</p>
<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
<span class="comment"> Copyright (C) 2011 J. Coliz <maniacbug@ymail.com></span>
<span class="comment"></span>
<span class="comment"> This program is free software; you can redistribute it and/or</span>
<span class="comment"> modify it under the terms of the GNU General Public License</span>
<span class="comment"> version 2 as published by the Free Software Foundation.</span>
<span class="comment"> */</span>
<span class="preprocessor">#include <SPI.h></span>
<span class="preprocessor">#include <avr/sleep.h></span>
<span class="preprocessor">#include <avr/power.h></span>
<span class="preprocessor">#include "nRF24L01.h"</span>
<span class="preprocessor">#include "<a class="code" href="RF24_8h.html" title="Class declaration for RF24 and helper enums.">RF24.h</a>"</span>
<span class="preprocessor">#include "printf.h"</span>
<span class="comment">//</span>
<span class="comment">// Hardware configuration</span>
<span class="comment">//</span>
<span class="comment">// Set up nRF24L01 radio on SPI bus plus pins 9 & 10</span>
<a name="_a0"></a><a class="code" href="classRF24.html" title="Driver for nRF24L01(+) 2.4GHz Wireless Transceiver.">RF24</a> radio(9,10);
<span class="comment">// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver</span>
<span class="comment">// Leave open to be the 'ping' transmitter</span>
<span class="keyword">const</span> <span class="keywordtype">int</span> role_pin = 7;
<span class="comment">//</span>
<span class="comment">// Topology</span>
<span class="comment">//</span>
<span class="comment">// Radio pipe addresses for the 2 nodes to communicate.</span>
<span class="keyword">const</span> uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
<span class="comment">//</span>
<span class="comment">// Role management</span>
<span class="comment">//</span>
<span class="comment">// Set up role. This sketch uses the same software for all the nodes</span>
<span class="comment">// in this system. Doing so greatly simplifies testing. The hardware itself specifies</span>
<span class="comment">// which node it is.</span>
<span class="comment">//</span>
<span class="comment">// This is done through the role_pin</span>
<span class="comment">//</span>
<span class="comment">// The various roles supported by this sketch</span>
<span class="keyword">typedef</span> <span class="keyword">enum</span> { role_ping_out = 1, role_pong_back } role_e;
<span class="comment">// The debug-friendly names of those roles</span>
<span class="keyword">const</span> <span class="keywordtype">char</span>* role_friendly_name[] = { <span class="stringliteral">"invalid"</span>, <span class="stringliteral">"Ping out"</span>, <span class="stringliteral">"Pong back"</span>};
<span class="comment">// The role of the current running sketch</span>
role_e role;
<span class="comment">//</span>
<span class="comment">// Sleep declarations</span>
<span class="comment">//</span>
<span class="keyword">typedef</span> <span class="keyword">enum</span> { wdt_16ms = 0, wdt_32ms, wdt_64ms, wdt_128ms, wdt_250ms, wdt_500ms, wdt_1s, wdt_2s, wdt_4s, wdt_8s } wdt_prescalar_e;
<span class="keywordtype">void</span> setup_watchdog(uint8_t prescalar);
<span class="keywordtype">void</span> do_sleep(<span class="keywordtype">void</span>);
<span class="keyword">const</span> <span class="keywordtype">short</span> sleep_cycles_per_transmission = 4;
<span class="keyword">volatile</span> <span class="keywordtype">short</span> sleep_cycles_remaining = sleep_cycles_per_transmission;
<span class="comment">//</span>
<span class="comment">// Normal operation</span>
<span class="comment">//</span>
<span class="keywordtype">void</span> setup(<span class="keywordtype">void</span>)
{
<span class="comment">//</span>
<span class="comment">// Role</span>
<span class="comment">//</span>
<span class="comment">// set up the role pin</span>
pinMode(role_pin, INPUT);
digitalWrite(role_pin,HIGH);
delay(20); <span class="comment">// Just to get a solid reading on the role pin</span>
<span class="comment">// read the address pin, establish our role</span>
<span class="keywordflow">if</span> ( digitalRead(role_pin) )
role = role_ping_out;
<span class="keywordflow">else</span>
role = role_pong_back;
<span class="comment">//</span>
<span class="comment">// Print preamble</span>
<span class="comment">//</span>
Serial.begin(57600);
printf_begin();
printf(<span class="stringliteral">"\n\rRF24/examples/pingpair_sleepy/\n\r"</span>);
printf(<span class="stringliteral">"ROLE: %s\n\r"</span>,role_friendly_name[role]);
<span class="comment">//</span>
<span class="comment">// Prepare sleep parameters</span>
<span class="comment">//</span>
<span class="comment">// Only the ping out role sleeps. Wake up every 4s to send a ping</span>
<span class="keywordflow">if</span> ( role == role_ping_out )
setup_watchdog(wdt_1s);
<span class="comment">//</span>
<span class="comment">// Setup and configure rf radio</span>
<span class="comment">//</span>
radio.begin();
<span class="comment">//</span>
<span class="comment">// Open pipes to other nodes for communication</span>
<span class="comment">//</span>
<span class="comment">// This simple sketch opens two pipes for these two nodes to communicate</span>
<span class="comment">// back and forth.</span>
<span class="comment">// Open 'our' pipe for writing</span>
<span class="comment">// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)</span>
<span class="keywordflow">if</span> ( role == role_ping_out )
{
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
<span class="keywordflow">else</span>
{
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
}
<span class="comment">//</span>
<span class="comment">// Start listening</span>
<span class="comment">//</span>
radio.startListening();
<span class="comment">//</span>
<span class="comment">// Dump the configuration of the rf unit for debugging</span>
<span class="comment">//</span>
radio.printDetails();
}
<span class="keywordtype">void</span> loop(<span class="keywordtype">void</span>)
{
<span class="comment">//</span>
<span class="comment">// Ping out role. Repeatedly send the current time</span>
<span class="comment">//</span>
<span class="keywordflow">if</span> (role == role_ping_out)
{
<span class="comment">// First, stop listening so we can talk.</span>
radio.stopListening();
<span class="comment">// Take the time, and send it. This will block until complete</span>
<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> time = millis();
printf(<span class="stringliteral">"Now sending %lu..."</span>,time);
radio.write( &time, <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) );
<span class="comment">// Now, continue listening</span>
radio.startListening();
<span class="comment">// Wait here until we get a response, or timeout (250ms)</span>
<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> started_waiting_at = millis();
<span class="keywordtype">bool</span> timeout = <span class="keyword">false</span>;
<span class="keywordflow">while</span> ( ! radio.available() && ! timeout )
<span class="keywordflow">if</span> (millis() - started_waiting_at > 250 )
timeout = <span class="keyword">true</span>;
<span class="comment">// Describe the results</span>
<span class="keywordflow">if</span> ( timeout )
{
printf(<span class="stringliteral">"Failed, response timed out.\n\r"</span>);
}
<span class="keywordflow">else</span>
{
<span class="comment">// Grab the response, compare, and send to debugging spew</span>
<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> got_time;
radio.read( &got_time, <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) );
<span class="comment">// Spew it</span>
printf(<span class="stringliteral">"Got response %lu, round-trip delay: %lu\n\r"</span>,got_time,millis()-got_time);
}
<span class="comment">//</span>
<span class="comment">// Shut down the system</span>
<span class="comment">//</span>
<span class="comment">// Experiment with some delay here to see if it has an effect</span>
delay(500);
<span class="comment">// Power down the radio. Note that the radio will get powered back up</span>
<span class="comment">// on the next write() call.</span>
radio.powerDown();
<span class="comment">// Sleep the MCU. The watchdog timer will awaken in a short while, and</span>
<span class="comment">// continue execution here.</span>
<span class="keywordflow">while</span>( sleep_cycles_remaining )
do_sleep();
sleep_cycles_remaining = sleep_cycles_per_transmission;
}
<span class="comment">//</span>
<span class="comment">// Pong back role. Receive each packet, dump it out, and send it back</span>
<span class="comment">//</span>
<span class="comment">// This is untouched from the pingpair example.</span>
<span class="comment">//</span>
<span class="keywordflow">if</span> ( role == role_pong_back )
{
<span class="comment">// if there is data ready</span>
<span class="keywordflow">if</span> ( radio.available() )
{
<span class="comment">// Dump the payloads until we've gotten everything</span>
<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> got_time;
<span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
<span class="keywordflow">while</span> (!done)
{
<span class="comment">// Fetch the payload, and see if this was the last one.</span>
done = radio.read( &got_time, <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) );
<span class="comment">// Spew it. Include our time, because the ping_out millis counter is unreliable</span>
<span class="comment">// due to it sleeping</span>
printf(<span class="stringliteral">"Got payload %lu @ %lu..."</span>,got_time,millis());
}
<span class="comment">// First, stop listening so we can talk</span>
radio.stopListening();
<span class="comment">// Send the final one back.</span>
radio.write( &got_time, <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) );
printf(<span class="stringliteral">"Sent response.\n\r"</span>);
<span class="comment">// Now, resume listening so we catch the next packets.</span>
radio.startListening();
}
}
}
<span class="comment">//</span>
<span class="comment">// Sleep helpers</span>
<span class="comment">//</span>
<span class="comment">// 0=16ms, 1=32ms,2=64ms,3=125ms,4=250ms,5=500ms</span>
<span class="comment">// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec</span>
<span class="keywordtype">void</span> setup_watchdog(uint8_t prescalar)
{
prescalar = min(9,prescalar);
uint8_t wdtcsr = prescalar & 7;
<span class="keywordflow">if</span> ( prescalar & 8 )
wdtcsr |= _BV(WDP3);
MCUSR &= ~_BV(WDRF);
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = _BV(WDCE) | wdtcsr | _BV(WDIE);
}
ISR(WDT_vect)
{
--sleep_cycles_remaining;
}
<span class="keywordtype">void</span> do_sleep(<span class="keywordtype">void</span>)
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); <span class="comment">// sleep mode is set here</span>
sleep_enable();
sleep_mode(); <span class="comment">// System sleeps here</span>
sleep_disable(); <span class="comment">// System continues execution here when watchdog timed out</span>
}
<span class="comment">// vim:ai:cin:sts=2 sw=2 ft=cpp</span>
</pre></div> </div>
</div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Enumerations</a></div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Sun Jan 15 2012 22:21:58 for RF24 by 
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
</html>