-
Notifications
You must be signed in to change notification settings - Fork 0
/
VirtualWire.h
292 lines (263 loc) · 11.8 KB
/
VirtualWire.h
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
// VirtualWire.h
//
// Virtual Wire implementation for Arduino
// See the README file in this directory fdor documentation
//
// Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
// Copyright (C) 2008 Mike McCauley
// $Id: VirtualWire.h,v 1.6 2013/02/14 22:02:11 mikem Exp mikem $
/// \mainpage VirtualWire library for Arduino
///
/// This is the Arduino VirtualWire library.
///
/// VirtualWire is an Arduino library that provides features to send short
/// messages, without addressing, retransmit or acknowledgment, a bit like UDP
/// over wireless, using ASK (amplitude shift keying). Supports a number of
/// inexpensive radio transmitters and receivers. All that is required is
/// transmit data, receive data and (for transmitters, optionally) a PTT
/// transmitter enable.
///
/// It is intended to be compatible with the RF Monolithics (www.rfm.com)
/// Virtual Wire protocol, but this has not been tested.
///
/// Does not use the Arduino UART. Messages are sent with a training preamble,
/// message length and checksum. Messages are sent with 4-to-6 bit encoding
/// for good DC balance, and a CRC checksum for message integrity.
///
/// Why not just use the Arduino UART connected directly to the
/// transmitter/receiver? As discussed in the RFM documentation, ASK receivers
/// require a burst of training pulses to synchronize the transmitter and
/// receiver, and also requires good balance between 0s and 1s in the message
/// stream in order to maintain the DC balance of the message. UARTs do not
/// provide these. They work a bit with ASK wireless, but not as well as this
/// code.
///
/// This library provides classes for
/// - VirtualWire: unaddressed, unreliable messages
///
/// Example Arduino programs are included to show the main modes of use.
///
/// The version of the package that this documentation refers to can be downloaded
/// from http://www.airspayce.com/mikem/arduino/VirtualWire/VirtualWire-1.15.zip
/// You can find the latest version at http://www.airspayce.com/mikem/arduino/VirtualWire
///
/// You can also find online help and disussion at http://groups.google.com/group/virtualwire
/// Please use that group for all questions and discussions on this topic.
/// Do not contact the author directly, unless it is to discuss commercial licensing.
///
/// \par Supported Hardware
/// A range of communications hardware is supported. The ones listed blow are
/// available in common retail outlets in Australian and other countries for
/// under $10 per unit. Many other modules may also work with this software.
/// Runs on ATmega8/168 (Arduino Diecimila, Uno etc) and ATmega328 and possibly
/// others. Also runs on on Energia with MSP430G2553 / G2452 and Arduino with
/// ATMega328 (courtesy Yannick DEVOS - XV4Y).
/// Also compiles and runs on ATtiny85 in Arduino environment, courtesy r4z0r7o3.
///
/// - Receivers
/// - RX-B1 (433.92MHz) (also known as ST-RX04-ASK)
/// - Transmitters:
/// - TX-C1 (433.92MHz)
/// - Transceivers
/// - DR3100 (433.92MHz)
///
/// \par Installation
/// To install, unzip the library into the libraries sub-directory of your
/// Arduino application directory. Then launch the Arduino environment; you
/// should see the library in the Sketch->Import Library menu, and example
/// code in
/// File->Sketchbook->Examples->VirtualWire menu.
///
/// \par Open Source Licensing GPL V2
///
/// This is the appropriate option if you want to share the source code of your
/// application with everyone you distribute it to, and you also want to give them
/// the right to share who uses it. If you wish to use this software under Open
/// Source Licensing, you must contribute all your source code to the open source
/// community in accordance with the GPL Version 2 when your application is
/// distributed. See http://www.gnu.org/copyleft/gpl.html
///
/// \par Commercial Licensing
///
/// This is the appropriate option if you are creating proprietary applications
/// and you are not prepared to distribute and share the source code of your
/// application. Contact info@airspayce.com for details.
///
/// \par Revision History
/// \version 1.0 Original release
///
/// \version 1.1 2008-06-24
/// Now can compile for atmega8
/// Reported by creatrope
/// \version 1.2 2009-03-30
/// Fixed a problem that prevented compiling with arduino-0015
/// Reported by Jaime Castro
/// \version 1.3 2009-04-01
/// Fixed a compatibility problem with ATMEGA328 of the new arduino
/// Now use SIGNAL(TIMER1_COMPA_vect) instead of ISR(SIG_OUTPUT_COMPARE1A)
/// as discussed in
/// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237714550/11
/// and reported by Jaime Castro.
/// \version 1.4 2010-01-29
/// Added vx_tx_active(), suggested by Alan Burlison.
/// \version 1.5 2011-09-09
/// Added vx_tx_active() function.
/// \version 1.6 2012-01-10
/// Fixed a problem where the receiver was always reenabled after
/// transmission. Reported by David Bath
/// \version 1.9 2012-02-07 Documentation updates
/// Documentation updates
/// \version 1.10 Updated CHANGES file with changes since 1.4.
/// \version 1.11 Converted documentation to Doxygen. Moved CHANGES log to this version history.
/// Ensure vw_rx_pin is not accessed unless receiver is enabled
/// \version 1.12 Compiles and runs on on Energia with MSP430G2553 / G2452 and Arduino with ATMega328.
/// Patches contributed by Yannick DEVOS - XV4Y
/// \version 1.13 util/crc16.h needed for compiling on Energia with MSP430G2553 / G2452 was accidentally
/// left out of the distribution
/// \version 1.14 Added support ATtiny85 on Arduino, patch provided by r4z0r7o3.
/// \version 1.15 Updated author and distribution location details to airspayce.com
///
/// \par Implementation Details
/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
///
/// \par Performance
/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
///
/// \par Connections
/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
///
/// \file VirtualWire.h
/// \brief VirtualWire API
///
/// To use the VirtualWire library, you must have
/// \code
/// #include <VirtualWire.h>
/// \endcode
/// At the top of your sketch.
///
#ifndef VirtualWire_h
#define VirtualWire_h
#include <stdlib.h>
#if defined(ARDUINO)
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <wiring.h>
#endif
#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) // LaunchPad specific
#include "legacymsp430.h"
#include "Energia.h"
#else // error
#error Platform not defined
#endif
// These defs cause trouble on some versions of Arduino
#undef abs
#undef double
#undef round
/// Maximum number of bytes in a message, counting the byte count and FCS
#define VW_MAX_MESSAGE_LEN 30
/// The maximum payload length
#define VW_MAX_PAYLOAD VW_MAX_MESSAGE_LEN-3
/// The size of the receiver ramp. Ramp wraps modulu this number
#define VW_RX_RAMP_LEN 160
/// Number of samples per bit
#define VW_RX_SAMPLES_PER_BIT 8
// Ramp adjustment parameters
// Standard is if a transition occurs before VW_RAMP_TRANSITION (80) in the ramp,
// the ramp is retarded by adding VW_RAMP_INC_RETARD (11)
// else by adding VW_RAMP_INC_ADVANCE (29)
// If there is no transition it is adjusted by VW_RAMP_INC (20)
/// Internal ramp adjustment parameter
#define VW_RAMP_INC (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
/// Internal ramp adjustment parameter
#define VW_RAMP_TRANSITION VW_RX_RAMP_LEN/2
/// Internal ramp adjustment parameter
#define VW_RAMP_ADJUST 9
/// Internal ramp adjustment parameter
#define VW_RAMP_INC_RETARD (VW_RAMP_INC-VW_RAMP_ADJUST)
/// Internal ramp adjustment parameter
#define VW_RAMP_INC_ADVANCE (VW_RAMP_INC+VW_RAMP_ADJUST)
/// Outgoing message bits grouped as 6-bit words
/// 36 alternating 1/0 bits, followed by 12 bits of start symbol
/// Followed immediately by the 4-6 bit encoded byte count,
/// message buffer and 2 byte FCS
/// Each byte from the byte count on is translated into 2x6-bit words
/// Caution, each symbol is transmitted LSBit first,
/// but each byte is transmitted high nybble first
#define VW_HEADER_LEN 8
// Cant really do this as a real C++ class, since we need to have
// an ISR
extern "C"
{
/// Set the digital IO pin to be for transmit data.
/// This pin will only be accessed if
/// the transmitter is enabled
/// \param[in] pin The Arduino pin number for transmitting data. Defaults to 12.
extern void vw_set_tx_pin(uint8_t pin);
/// Set the digital IO pin to be for receive data.
/// This pin will only be accessed if
/// the receiver is enabled
/// \param[in] pin The Arduino pin number for receiving data. Defaults to 11.
extern void vw_set_rx_pin(uint8_t pin);
// Set the digital IO pin to enable the transmitter (press to talk, PTT)'
/// This pin will only be accessed if
/// the transmitter is enabled
/// \param[in] pin The Arduino pin number to enable the transmitter. Defaults to 10.
extern void vw_set_ptt_pin(uint8_t pin);
/// By default the PTT pin goes high when the transmitter is enabled.
/// This flag forces it low when the transmitter is enabled.
/// \param[in] inverted True to invert PTT
extern void vw_set_ptt_inverted(uint8_t inverted);
/// Initialise the VirtualWire software, to operate at speed bits per second
/// Call this one in your setup() after any vw_set_* calls
/// Must call vw_rx_start() before you will get any messages
/// \param[in] speed Desired speed in bits per second
extern void vw_setup(uint16_t speed);
/// Start the Phase Locked Loop listening to the receiver
/// Must do this before you can receive any messages
/// When a message is available (good checksum or not), vw_have_message();
/// will return true.
extern void vw_rx_start();
/// Stop the Phase Locked Loop listening to the receiver
/// No messages will be received until vw_rx_start() is called again
/// Saves interrupt processing cycles
extern void vw_rx_stop();
/// Returns the state of the
/// transmitter
/// \return true if the transmitter is active else false
extern uint8_t vx_tx_active();
/// Block until the transmitter is idle
/// then returns
extern void vw_wait_tx();
/// Block until a message is available
/// then returns
extern void vw_wait_rx();
/// Block until a message is available or for a max time
/// \param[in] milliseconds Maximum time to wait in milliseconds.
/// \return true if a message is available, false if the wait timed out.
extern uint8_t vw_wait_rx_max(unsigned long milliseconds);
/// Send a message with the given length. Returns almost immediately,
/// and message will be sent at the right timing by interrupts
/// \param[in] buf Pointer to the data to transmit
/// \param[in] len Number of octetes to transmit
/// \return true if the message was accepted for transmission, false if the message is too long (>VW_MAX_MESSAGE_LEN - 3)
extern uint8_t vw_send(uint8_t* buf, uint8_t len);
// Returns true if an unread message is available
/// \return true if a message is available to read
extern uint8_t vw_have_message();
// If a message is available (good checksum or not), copies
// up to *len octets to buf.
/// \param[in] buf Pointer to location to save the read data (must be at least *len bytes.
/// \param[in,out] len Available space in buf. Will be set to the actual number of octets read
/// \return true if there was a message and the checksum was good
extern uint8_t vw_get_message(uint8_t* buf, uint8_t* len);
}
/// @example client.pde
/// Client side of simple client/server pair using VirtualWire
/// @example server.pde
/// Server side of simple client/server pair using VirtualWire
/// @example transmitter.pde
/// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
/// @example receiver.pde
/// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
#endif