The latest addition to Cosa is a set of classes to support low level wireless communication on RF315/433 devices.
Fig.1: RF433 Receiver/Transmitter
The starting point is the popular VirtualWire library, which has been ported from C to C++ and refactored to the object-oriented style of Cosa. It has also been extended to allow multiple codecs, i.e. methods of encoding/decoding messages.
Fig.2: Codec class hierarchy
- The original 4-to-6 bit symbol codec from VirtualWire
- Manchester phase encoding
- 4B5B block coding
- Fixed bit stuffing(4)
The Virtual Wire Interface (VWI) is constructed with separate Receiver, Transmitter and Codec classes to allow fine-tuning of memory footprint for ultra small devices such as the ATtiny85. For instance, it is possible to use the Transmitter without including the Receiver.
Fig.3: VWI Static Member Functions
The Interrupt Service Routine (ISR) is controlled by static member functions in the VWI container class. The VWI::begin() member function is used to setup the Virtual Wire Interface for a given communication bit rate and idle mode. The ISR is also enabled by VWI::begin(). To allow power down sleep mode and ultra low power consumption there are two static member function to enable/disable the ISR (Timer Interrupt Handler).
Fig.4: VWI::Receiver Member Functions
The VWI::Receiver and VWI::Transmitter classes handle the issuing of message send and receive. The VWI::Receiver interface is simple; begin() for setup, await() for message and recv() for receiving a message. There is a possible timeout limit on the receiving of a message.
Fig.5: VWI::Transmitter Member Functions
The Virtual Wire Interface (VWI) also has a device driver for IOStream (VWIO). This allows printouts to be easily redirected and sent over the wireless interface without changes to source code other than the Trace or other IOStream driver binding. All the printing function in IOStream will print to the wireless connection.
Fig.6: VWIO-IOSTream::Device Classes
Below is a snippet from the CosaVWIOtrace example sketch:
VWIO tx(Board::D12, &codec);
// Start virtual wire output stream and trace
trace.begin(&tx, PSTR("CosaVWIOtrace: started"));
// Monitor digital pin values
trace << RTC::millis() << PSTR(": D0..10:");
for (uint8_t i = 0; i < 11; i++)
trace << ' ' << InputPin::read(i);
trace << endl;
// Monitor analog pin values
trace << RTC::millis() << PSTR(": A0..7:");
for (uint8_t i = 0; i < 8; i++)
trace << ' ' << AnalogPin::sample(i);
trace << endl;
The blue sections are the only parts changed compared to printing to the serial output. The internal buffer in VWIO will be sent as a VWI message when either it becomes full or when carriage return is received. This is a normal buffer flush policy for buffered devices.
In the Cosa examples directory there are the following VWI sketches.
- CosaVWIsender, sends a simple message with an identity, sequence number and two analog readings. Can be modified for the different Codecs available for VWI. Can run on an ATtiny85.
- CosaVWIreceiver, receiver for CosaVWIsender. Can also be modified for the different Codecs. Sender and receiver should use the same codec.
- CosaVWIOtrace, sends trace output over the Virtual Wire Interface. Should be used together with CosaVWImonitor.
- CosaVWImonitor, receive stream of text printout over VWI.
- CosaVWItempsensor, ATtiny85 sketch that reads temperature measurements from a 1-Wire DS18B20 Digital Thermometer and sends the value using VWI. Message contains ROM identity of the 1-Wire device, sequence number and temperature reading. See Fig.7-8 below.
- CosaVWItempmonitor, receives temperature readings from CosaVWItempsensor(s) and prints to serial output.
- CosaVWIkey, simple application to demonstrate power down sleep mode and wakeup/send of a message on pressing a button.
- CosaVWIclient is an example of a simple implementation of reliable, in-order, message protocol with addressing and message sequence numbering. This sketch will retransmit messages if an acknowledgement is not received from CosaVWIserver. Collects and prints statistics on retransmissions and error rate. Allows the different Codecs to be compared with regard to throughput and package drops (noise, etc).
- CosaVWIserver receives and print messages from CosaVWIclient. Sends an acknowledgement back to the client.
Fig.7: CosaVWItempsensor on ATtiny85 with 1-Wire Digital Thermometer
To allow small ultra low-power devices, the VWI classes are fully adapted for ATtiny85/85V. There are several examples and demonstration sketches in the examples directory. The example with 1-Wire CosaVWItempsensor is without any reduction less than 6 Kbyte leaving more than 2 Kbyte for further application code.
Fig.8: CosaVWItempmonitor printout of received temperature readings
As a bonus the new object-oriented/C++ version of VirtualWire is ported back to Arduino and is available.
The next step for this sub-set of Cosa will be to introduce additional message formats to allow addressing of nodes (MAC/IP style); broadcast/point-to-point and build the next step of the protocol stack for more reliable communication links and middleware.
Please note that Cosa also has a device driver for NRF24L01+. This device is a much more powerful chip for low power communication links.
Please note that since this blog post was written the Virtual Wire interface has been refactored to implement an abstract Wireless interface in Cosa. This allows applications to move more or less seamlessly between the different implementations of the Wireless interface. Currently there are three implementation; Virtual Wire (VWI), NRF24L01P and CC1101. The example sketches above work on all three.
There are some minor changes to the VWI interface but the overall functionality is the same (See the new VWI.hh). It is still possible to use the Cosa refactored Virtual Wire class directly.
Please note that the links above are broken and this post is not up to date. The examples directory is https://github.com/mikaelpatel/Cosa/tree/master/examples/Wireless.
Hamming(8,4) and (7,4) Codec has been added. This maps 4 bit data to 8 resp 7 bit symbols. The great advantage is 1-bit error detection and correction, and possible multi-bit error detection. This reduces the frame errors with almost 90% compared to the other Codecs (at 4 Kbps, 7 byte payload, 5 second message intervals, https://github.com/mikaelpatel/Cosa/blob/master/examples/Wireless/CosaWirelessDS18B20/CosaWirelessDS18B20.ino). The Hamming Code encoders/decoders are table driven which gives excellent performance and low memory footprint (144 resp 80 byte program memory).