VirtualWire
VirtualWire.h
Go to the documentation of this file.
1 // VirtualWire.h
2 //
3 // Virtual Wire implementation for Arduino and other boards
4 // See the README file in this directory for documentation
5 //
6 // Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
7 // Copyright (C) 2008 Mike McCauley
8 // $Id: VirtualWire.h,v 1.14 2014/03/26 01:09:36 mikem Exp mikem $
9 
10 /// \mainpage VirtualWire library for Arduino and other boards
11 ///
12 /// This is the VirtualWire library.
13 ///
14 /// \par END OF LIFE NOTICE
15 ///
16 /// This VirtualWire library has now been superceded by the RadioHead
17 /// library http://www.airspayce.com/mikem/arduino/RadioHead
18 /// RadioHead and its RH_ASK driver provides all the features supported by VirtualWire, and much more
19 /// besides, including Reliable Datagrams, Addressing, Routing and Meshes. All the platforms that
20 /// VirtualWire supported are also supported by RadioHead.
21 ///
22 /// This library will no longer be maintained or updated, but we will continue to publish
23 /// it for the benefit of the the community. Nevertheless we recommend upgrading to RadioHead where
24 /// possible.
25 ///
26 /// VirtualWire is a library for Arduino, Maple and others that provides features to send short
27 /// messages, without addressing, retransmit or acknowledgment, a bit like UDP
28 /// over wireless, using ASK (amplitude shift keying). Supports a number of
29 /// inexpensive radio transmitters and receivers. All that is required is
30 /// transmit data, receive data and (for transmitters, optionally) a PTT
31 /// transmitter enable. Can also be used over various analog connections (not just a data radio),
32 /// such as the audio channel of an A/V sender
33 ///
34 /// It is intended to be compatible with the RF Monolithics (www.rfm.com)
35 /// Virtual Wire protocol, but this has not been tested.
36 ///
37 /// Does not use the Arduino UART. Messages are sent with a training preamble,
38 /// message length and checksum. Messages are sent with 4-to-6 bit encoding
39 /// for good DC balance, and a CRC checksum for message integrity.
40 ///
41 /// But why not just use a UART connected directly to the
42 /// transmitter/receiver? As discussed in the RFM documentation, ASK receivers
43 /// require a burst of training pulses to synchronize the transmitter and
44 /// receiver, and also requires good balance between 0s and 1s in the message
45 /// stream in order to maintain the DC balance of the message. UARTs do not
46 /// provide these. They work a bit with ASK wireless, but not as well as this
47 /// code.
48 ///
49 /// This library provides classes for
50 /// - VirtualWire: unaddressed, unreliable messages
51 ///
52 /// Example Arduino programs are included to show the main modes of use.
53 ///
54 /// The version of the package that this documentation refers to can be downloaded
55 /// from http://www.airspayce.com/mikem/arduino/VirtualWire/VirtualWire-1.27.zip
56 /// You can find the latest version at http://www.airspayce.com/mikem/arduino/VirtualWire
57 ///
58 /// You can also find online help and disussion at
59 /// http://groups.google.com/group/virtualwire
60 /// Please use that group for all questions and discussions on this topic.
61 /// Do not contact the author directly, unless it is to discuss commercial licensing.
62 /// Before asking a question or reporting a bug, please read http://www.catb.org/esr/faqs/smart-questions.html
63 ///
64 /// \par Theory of operation
65 ///
66 /// See ASH Transceiver Software Designer's Guide of 2002.08.07
67 /// http://www.rfm.com/products/apnotes/tr_swg05.pdf
68 ///
69 /// \par Supported Hardware
70 ///
71 /// A range of communications
72 /// hardware is supported. The ones listed below are available in common retail
73 /// outlets in Australia and other countries for under $10 per unit. Many
74 /// other modules may also work with this software.
75 ///
76 /// Runs on a wide range of Arduino processors using Arduino IDE 1.0 or later.
77 /// Also runs on on Energia
78 /// with MSP430G2553 / G2452 and Arduino with ATMega328 (courtesy Yannick DEVOS - XV4Y),
79 /// but untested by us. It also runs on Teensy 3.0 and 3.1 (courtesy of Paul
80 /// Stoffregen) using the Arduino IDE 1.0.5 and the Teensyduino addon 1.18.
81 /// Also compiles and runs on ATtiny85 in
82 /// Arduino environment, courtesy r4z0r7o3. Also compiles on maple-ide-v0.0.12,
83 /// and runs on Maple, flymaple 1.1 etc. Runs on ATmega8/168 (Arduino Diecimila,
84 /// Uno etc), ATmega328 and can run on almost any other AVR8 platform,
85 /// without relying on the Arduino framework, by properly configuring the
86 /// library using 'VirtualWire_Config.h' header file for describing the access
87 /// to IO pins and for setting up the timer. From version 1.22 the library can
88 /// be compiled by a C compiler (by renaming VirtualWire.cpp into
89 /// VirtualWire.c) and can be easily integrated with other IDEs like 'Atmel
90 /// Studio' for example (courtesy of Alexandru Mircescu).
91 ///
92 /// - Receivers
93 /// - RX-B1 (433.92MHz) (also known as ST-RX04-ASK)
94 /// - Transmitters:
95 /// - TX-C1 (433.92MHz)
96 /// - Transceivers
97 /// - DR3100 (433.92MHz)
98 ///
99 /// For testing purposes you can connect 2 VirtualWire instances directly, by
100 /// connecting pin 12 of one to 11 of the other and vice versa, like this for a duplex connection:
101 ///
102 /// <code>
103 /// <pre>
104 /// Arduino 1 wires Arduino 1
105 /// D11-----------------------------D12
106 /// D12-----------------------------D11
107 /// GND-----------------------------GND
108 /// </pre>
109 /// </code>
110 ///
111 /// You can also connect 2 VirtualWire instances over a suitable analog
112 /// transmitter/receiver, such as the audio channel of an A/V transmitter/receiver. You may need
113 /// buffers at each end of the connection to convert the 0-5V digital output to a suitable analog voltage.
114 ///
115 /// Caution: ATTiny85 has only 2 timers, one (timer 0) usually used for
116 /// millis() and one (timer 1) for PWM analog outputs. The VirtualWire
117 /// library, when built for ATTiny85, takes over timer 0, which prevents use
118 /// of millis() etc but does permit analog outputs.
119 ///
120 /// \par Installation
121 ///
122 /// To install, unzip the library into the libraries sub-directory of your
123 /// Arduino application directory. Then launch the Arduino environment; you
124 /// should see the library in the Sketch->Import Library menu, and example
125 /// code in
126 /// File->Sketchbook->Examples->VirtualWire menu.
127 ///
128 /// \par Donations
129 ///
130 /// This library is offered under a free GPL license for those who want to use it that way.
131 /// We try hard to keep it up to date, fix bugs
132 /// and to provide free support. If this library has helped you save time or money, please consider donating at
133 /// http://www.airspayce.com or here:
134 ///
135 /// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="VirtualWire" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
136 ///
137 /// \par Trademarks
138 ///
139 /// VirtualWire is a trademark of AirSpayce Pty Ltd. The VirtualWire mark was first used on April 20 2008 for
140 /// international trade, and is used only in relation to data communications hardware and software and related services.
141 /// It is not to be confused with any other similar marks covering other goods and services.
142 ///
143 /// \par Copyright
144 ///
145 /// This software is Copyright (C) 2011-2014 Mike McCauley. Use is subject to license
146 /// conditions. The main licensing options available are GPL V2 or Commercial:
147 ///
148 /// \par Open Source Licensing GPL V2
149 ///
150 /// This is the appropriate option if you want to share the source code of your
151 /// application with everyone you distribute it to, and you also want to give them
152 /// the right to share who uses it. If you wish to use this software under Open
153 /// Source Licensing, you must contribute all your source code to the open source
154 /// community in accordance with the GPL Version 2 when your application is
155 /// distributed. See http://www.gnu.org/copyleft/gpl.html
156 ///
157 /// \par Commercial Licensing
158 ///
159 /// This is the appropriate option if you are creating proprietary applications
160 /// and you are not prepared to distribute and share the source code of your
161 /// application. Contact info@airspayce.com for details.
162 ///
163 /// \par Revision History
164 /// \version 1.0 Original release
165 ///
166 /// \version 1.1 2008-06-24
167 /// Now can compile for atmega8
168 /// Reported by creatrope
169 /// \version 1.2 2009-03-30
170 /// Fixed a problem that prevented compiling with arduino-0015
171 /// Reported by Jaime Castro
172 /// \version 1.3 2009-04-01
173 /// Fixed a compatibility problem with ATMEGA328 of the new arduino
174 /// Now use SIGNAL(TIMER1_COMPA_vect) instead of ISR(SIG_OUTPUT_COMPARE1A)
175 /// as discussed in
176 /// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237714550/11
177 /// and reported by Jaime Castro.
178 /// \version 1.4 2010-01-29
179 /// Added vx_tx_active(), suggested by Alan Burlison.
180 /// \version 1.5 2011-09-09
181 /// Added vx_tx_active() function.
182 /// \version 1.6 2012-01-10
183 /// Fixed a problem where the receiver was always reenabled after
184 /// transmission. Reported by David Bath
185 /// \version 1.9 2012-02-07 Documentation updates
186 /// Documentation updates
187 /// \version 1.10 Updated CHANGES file with changes since 1.4.
188 /// \version 1.11 Converted documentation to Doxygen. Moved CHANGES log to this version history.
189 /// Ensure vw_rx_pin is not accessed unless receiver is enabled
190 /// \version 1.12 Compiles and runs on on Energia with MSP430G2553 / G2452 and Arduino with ATMega328.
191 /// Patches contributed by Yannick DEVOS - XV4Y
192 /// \version 1.13 util/crc16.h needed for compiling on Energia with MSP430G2553 / G2452 was accidentally
193 /// left out of the distribution
194 /// \version 1.14 Added support ATtiny85 on Arduino, patch provided by r4z0r7o3.
195 /// \version 1.15 Updated author and distribution location details to airspayce.com
196 /// \version 1.16 Added support for Teensy 3.0, contributed by Paul Stoffregen.
197 /// \version 1.17 Increase default MAX_MESSAGE_LENGTH to 80. Added vw_get_rx_good() and vw_get_rx_bad()
198 /// functions.
199 /// \version 1.18 Added support for Maple, Flymaple etc with STM32F103RE processor using timer 1.
200 /// Tested with Flymaple 1.1 and maple-ide-v0.0.12
201 /// \version 1.19 Added new function vw_rx_inverted(), to allow the incoming RX to be inverted (normally high).
202 /// Minor improvements to timer setup for Maple. Name vw_tx_active() changed from incorrect
203 /// vx_tx_active()
204 /// \version 1.20 Added support for ATtiny84, patched by Chuck Benedict.
205 /// \version 1.21 Added support for most AVR8 platforms with proper configuration, without depending
206 /// on Arduino environment, such as Atmega32u2, Atmega32U4, At90USB162 etc,
207 /// contributed by Alexandru Daniel Mircescu.
208 /// \version 1.22 Alexandru Daniel Mircescu fixed some problems with the recently added AtMega32U2 support.
209 /// \version 1.23 Fixed some errors and inaccuracies in documentation, with the kind assistance of Alexandru
210 /// Mircescu.
211 /// \version 1.24 Minor performance improvement to vw_symbol_6to4() courtesy Ralph Doncaster.
212 /// \version 1.25 Removed all use of floating point code, with assistance of a patch from Jim Remington.
213 /// Result is smaller code size.
214 /// \version 1.26 Removed util/crc16.h from distribution, since it is now included in arduino IDE
215 /// since version 1.0. Support for arduino IDE prior to 1.0 is now abandoned.
216 /// \version 1.27 Reinstated VWutil/crc16.h for the benefit of other platforms such as Teensy.
217 /// Testing on Teensy 3.1. Added End Of Life notice. This library will no longer be maintained
218 /// and updated: use RadioHead instead.
219 ///
220 /// \par Implementation Details
221 /// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
222 ///
223 /// \par Performance
224 /// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
225 ///
226 /// \par Connections
227 /// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
228 ///
229 /// \file VirtualWire.h
230 /// \brief VirtualWire API
231 ///
232 /// To use the VirtualWire library, you must have
233 /// \code
234 /// #include <VirtualWire.h>
235 /// \endcode
236 /// At the top of your sketch.
237 ///
238 
239 #ifndef VirtualWire_h
240 #define VirtualWire_h
241 
242 #include <stdint.h>
243 #include "VirtualWire_Config.h"
244 
245 // Currently supported platforms
246 #define VW_PLATFORM_ARDUINO 1
247 #define VW_PLATFORM_MSP430 2
248 #define VW_PLATFORM_STM32 3
249 #define VW_PLATFORM_GENERIC_AVR8 4
250 #define VW_PLATFORM_UNO32 5
251 
252 // Select platform automatically, if possible
253 #ifndef VW_PLATFORM
254  #if defined(ARDUINO)
255  #define VW_PLATFORM VW_PLATFORM_ARDUINO
256  #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)
257  #define VW_PLATFORM VW_PLATFORM_MSP430
258  #elif defined(MCU_STM32F103RE)
259  #define VW_PLATFORM VW_PLATFORM_STM32
260  #elif defined MPIDE
261  #define VW_PLATFORM VW_PLATFORM_UNO32
262  #else
263  #error Platform not defined!
264  #endif
265 #endif
266 
267 #if (VW_PLATFORM == VW_PLATFORM_ARDUINO)
268  #if (ARDUINO >= 100)
269  #include <Arduino.h>
270  #else
271  #include <wiring.h>
272 #endif
273 #elif (VW_PLATFORM == VW_PLATFORM_MSP430)// LaunchPad specific
274  #include "legacymsp430.h"
275  #include "Energia.h"
276 #elif (VW_PLATFORM == VW_PLATFORM_STM32) // Maple etc
277  #include <stdint.h>
278  // Defines which timer to use on Maple
279  #define MAPLE_TIMER 1
280 #elif (VW_PLATFORM == VW_PLATFORM_UNO32)
281 #elif (VW_PLATFORM != VW_PLATFORM_GENERIC_AVR8)
282  #error Platform unknown!
283 #endif
284 
285 // These defs cause trouble on some versions of Arduino
286 #undef abs
287 #undef double
288 #undef round
289 
290 #ifndef VW_MAX_MESSAGE_LEN
291 /// Maximum number of bytes in a message, counting the byte count and FCS
292  #define VW_MAX_MESSAGE_LEN 80
293 #endif //VW_MAX_MESSAGE_LEN
294 
295 #if !defined(VW_RX_SAMPLES_PER_BIT)
296 /// Number of samples per bit
297  #define VW_RX_SAMPLES_PER_BIT 8
298 #endif //VW_RX_SAMPLES_PER_BIT
299 
300 /// The maximum payload length
301 #define VW_MAX_PAYLOAD VW_MAX_MESSAGE_LEN-3
302 
303 /// The size of the receiver ramp. Ramp wraps modulo this number
304 #define VW_RX_RAMP_LEN 160
305 
306 // Ramp adjustment parameters
307 // Standard is if a transition occurs before VW_RAMP_TRANSITION (80) in the ramp,
308 // the ramp is retarded by adding VW_RAMP_INC_RETARD (11)
309 // else by adding VW_RAMP_INC_ADVANCE (29)
310 // If there is no transition it is adjusted by VW_RAMP_INC (20)
311 /// Internal ramp adjustment parameter
312 #define VW_RAMP_INC (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
313 /// Internal ramp adjustment parameter
314 #define VW_RAMP_TRANSITION VW_RX_RAMP_LEN/2
315 /// Internal ramp adjustment parameter
316 #define VW_RAMP_ADJUST 9
317 /// Internal ramp adjustment parameter
318 #define VW_RAMP_INC_RETARD (VW_RAMP_INC-VW_RAMP_ADJUST)
319 /// Internal ramp adjustment parameter
320 #define VW_RAMP_INC_ADVANCE (VW_RAMP_INC+VW_RAMP_ADJUST)
321 
322 /// Outgoing message bits grouped as 6-bit words
323 /// 36 alternating 1/0 bits, followed by 12 bits of start symbol
324 /// Followed immediately by the 4-6 bit encoded byte count,
325 /// message buffer and 2 byte FCS
326 /// Each byte from the byte count on is translated into 2x6-bit words
327 /// Caution, each symbol is transmitted LSBit first,
328 /// but each byte is transmitted high nybble first
329 #define VW_HEADER_LEN 8
330 
331 // Cant really do this as a real C++ class, since we need to have
332 // an ISR
333 #ifdef __cplusplus
334 extern "C"
335 {
336 #endif //__cplusplus
337 
338 #if (VW_PLATFORM != VW_PLATFORM_GENERIC_AVR8 )
339  // Set the digital IO pin which will be used to enable the transmitter (press to talk, PTT)'
340  /// This pin will only be accessed if
341  /// the transmitter is enabled
342  /// \param[in] pin The Arduino pin number to enable the transmitter. Defaults to 10.
343  extern void vw_set_ptt_pin(uint8_t pin);
344 
345  /// Set the digital IO pin to be for transmit data.
346  /// This pin will only be accessed if
347  /// the transmitter is enabled
348  /// \param[in] pin The Arduino pin number for transmitting data. Defaults to 12.
349  extern void vw_set_tx_pin(uint8_t pin);
350 
351  /// Set the digital IO pin to be for receive data.
352  /// This pin will only be accessed if
353  /// the receiver is enabled
354  /// \param[in] pin The Arduino pin number for receiving data. Defaults to 11.
355  extern void vw_set_rx_pin(uint8_t pin);
356 #endif
357 
358  /// By default the RX pin is expected to be low when idle, and to pulse high
359  /// for each data pulse.
360  /// This flag forces it to be inverted. This may be necessary if your transport medium
361  /// inverts the logic of your signal, such as happens with some types of A/V tramsmitter.
362  /// \param[in] inverted True to invert sense of receiver input
363  extern void vw_set_rx_inverted(uint8_t inverted);
364 
365  /// By default the PTT pin goes high when the transmitter is enabled.
366  /// This flag forces it low when the transmitter is enabled.
367  /// \param[in] inverted True to invert PTT
368  extern void vw_set_ptt_inverted(uint8_t inverted);
369 
370  /// Initialise the VirtualWire software, to operate at speed bits per second
371  /// Call this one in your setup() after any vw_set_* calls
372  /// Must call vw_rx_start() before you will get any messages
373  /// \param[in] speed Desired speed in bits per second
374  extern void vw_setup(uint16_t speed);
375 
376  /// Start the Phase Locked Loop listening to the receiver
377  /// Must do this before you can receive any messages
378  /// When a message is available (good checksum or not), vw_have_message();
379  /// will return true.
380  extern void vw_rx_start();
381 
382  /// Stop the Phase Locked Loop listening to the receiver
383  /// No messages will be received until vw_rx_start() is called again
384  /// Saves interrupt processing cycles
385  extern void vw_rx_stop();
386 
387  /// Returns the state of the
388  /// transmitter
389  /// \return true if the transmitter is active else false
390  extern uint8_t vw_tx_active();
391 
392  /// Block until the transmitter is idle
393  /// then returns
394  extern void vw_wait_tx();
395 
396  /// Block until a message is available
397  /// then returns
398  extern void vw_wait_rx();
399 
400  /// Block until a message is available or for a max time
401  /// \param[in] milliseconds Maximum time to wait in milliseconds.
402  /// \return true if a message is available, false if the wait timed out.
403  extern uint8_t vw_wait_rx_max(unsigned long milliseconds);
404 
405  /// Send a message with the given length. Returns almost immediately,
406  /// and message will be sent at the right timing by interrupts
407  /// \param[in] buf Pointer to the data to transmit
408  /// \param[in] len Number of octetes to transmit
409  /// \return true if the message was accepted for transmission, false if the message is too long (>VW_MAX_MESSAGE_LEN - 3)
410  extern uint8_t vw_send(uint8_t* buf, uint8_t len);
411 
412  /// Returns true if an unread message is available
413  /// \return true if a message is available to read
414  extern uint8_t vw_have_message();
415 
416  /// If a message is available (good checksum or not), copies
417  /// up to *len octets to buf.
418  /// \param[in] buf Pointer to location to save the read data (must be at least *len bytes.
419  /// \param[in,out] len Available space in buf. Will be set to the actual number of octets read
420  /// \return true if there was a message and the checksum was good
421  extern uint8_t vw_get_message(uint8_t* buf, uint8_t* len);
422 
423  /// Returns the count of good messages received
424  /// Caution,: this is an 8 bit count and can easily overflow
425  /// \return Count of good messages received
426  extern uint8_t vw_get_rx_good();
427 
428  /// Returns the count of bad messages received, ie
429  /// messages with bogus lengths, indicating corruption
430  /// or lost octets.
431  /// Caution,: this is an 8 bit count and can easily overflow
432  /// \return Count of bad messages received
433  extern uint8_t vw_get_rx_bad();
434 
435 #ifdef __cplusplus
436 } // extern "C"
437 #endif //__cplusplus
438 
439 /// @example client.pde
440 /// Client side of simple client/server pair using VirtualWire
441 
442 /// @example server.pde
443 /// Server side of simple client/server pair using VirtualWire
444 
445 /// @example transmitter.pde
446 /// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
447 
448 /// @example receiver.pde
449 /// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
450 
451 #endif /* VirtualWire_h */
void vw_set_ptt_pin(uint8_t pin)
Definition: VirtualWire.cpp:287
uint8_t vw_wait_rx_max(unsigned long milliseconds)
Definition: VirtualWire.cpp:652
uint8_t vw_have_message()
Definition: VirtualWire.cpp:731
void vw_wait_tx()
Definition: VirtualWire.cpp:633
void vw_wait_rx()
Definition: VirtualWire.cpp:642
void vw_rx_start()
Definition: VirtualWire.cpp:610
uint8_t vw_tx_active()
Definition: VirtualWire.cpp:626
uint8_t vw_get_message(uint8_t *buf, uint8_t *len)
Definition: VirtualWire.cpp:739
void vw_set_rx_pin(uint8_t pin)
Definition: VirtualWire.cpp:281
uint8_t vw_get_rx_bad()
Definition: VirtualWire.cpp:767
uint8_t vw_send(uint8_t *buf, uint8_t len)
Definition: VirtualWire.cpp:684
void vw_set_rx_inverted(uint8_t inverted)
Definition: VirtualWire.cpp:261
void vw_set_tx_pin(uint8_t pin)
Definition: VirtualWire.cpp:275
void vw_set_ptt_inverted(uint8_t inverted)
Definition: VirtualWire.cpp:267
void vw_rx_stop()
Definition: VirtualWire.cpp:620
void vw_setup(uint16_t speed)
uint8_t vw_get_rx_good()
Definition: VirtualWire.cpp:762