Library for HopeRF RFM22 / RFM22B transceiver module ported to mbed. Original Software from Mike McCauley (mikem@open.com.au) . See http://www.open.com.au/mikem/arduino/RF22/

Dependents:   RF22_MAX_test_Send Geofence_receiver Geofence_sender Geofence_sender ... more

More Info about RFM22-modules like connecting and a demo-program see RF22-Notebook

Committer:
charly
Date:
Mon Sep 02 20:32:54 2013 +0000
Revision:
9:4002a2c117cc
Parent:
5:0386600f3408
removed DEBUG-LEDs LED1 .. LED4 as they make problems on other platforms (KL25Z)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charly 0:79c6d0071c4c 1 // RF22ReliableDatagram.h
charly 0:79c6d0071c4c 2 //
charly 0:79c6d0071c4c 3 // Author: Mike McCauley (mikem@open.com.au)
charly 0:79c6d0071c4c 4 // Copyright (C) 2011 Mike McCauley
charly 5:0386600f3408 5 // $Id: RF22ReliableDatagram.h,v 1.7 2012/05/30 01:51:25 mikem Exp $
charly 0:79c6d0071c4c 6 // ported to mbed by Karl Zweimueller
charly 0:79c6d0071c4c 7
charly 0:79c6d0071c4c 8 #ifndef RF22ReliableDatagram_h
charly 0:79c6d0071c4c 9 #define RF22ReliableDatagram_h
charly 0:79c6d0071c4c 10
charly 0:79c6d0071c4c 11 #include <RF22Datagram.h>
charly 0:79c6d0071c4c 12
charly 0:79c6d0071c4c 13 // The acknowledgement bit in the FLAGS
charly 0:79c6d0071c4c 14 #define RF22_FLAGS_ACK 0x80
charly 0:79c6d0071c4c 15
charly 0:79c6d0071c4c 16 /////////////////////////////////////////////////////////////////////
charly 0:79c6d0071c4c 17 /// \class RF22ReliableDatagram RF22ReliableDatagram.h <RF22ReliableDatagram.h>
charly 0:79c6d0071c4c 18 /// \brief RF22 subclass for sending addressed, acknowledged, retransmitted datagrams.
charly 0:79c6d0071c4c 19 ///
charly 0:79c6d0071c4c 20 /// Extends RF22Datagram to define addressed, reliable datagrams with acknowledgement and retransmission.
charly 0:79c6d0071c4c 21 /// Based on RF22Datagram, adds flags and sequence numbers. RF22ReliableDatagram is reliable in the sense
charly 0:79c6d0071c4c 22 /// that messages are acknowledged, and unacknowledged messages are retransmitted until acknowledged or the
charly 0:79c6d0071c4c 23 /// retries are exhausted.
charly 0:79c6d0071c4c 24 /// When addressed messages are sent (by sendtoWait()), it will wait for an ack, and retransmit
charly 0:79c6d0071c4c 25 /// after timeout until an ack is received or retries are exhausted.
charly 0:79c6d0071c4c 26 /// When addressed messages are collected by the application (by recvfromAck()),
charly 0:79c6d0071c4c 27 /// an acknowledgement is automatically sent.
charly 0:79c6d0071c4c 28 ///
charly 0:79c6d0071c4c 29 /// The retransmit timeout is randomly varied between timeout and timeout*2 to prevent collisions on all
charly 0:79c6d0071c4c 30 /// retries when 2 nodes happen to start sending at the same time .
charly 0:79c6d0071c4c 31 ///
charly 0:79c6d0071c4c 32 /// Each new message sent by sendtoWait() has its ID incremented.
charly 0:79c6d0071c4c 33 ///
charly 0:79c6d0071c4c 34 /// An ack consists of a message with:
charly 0:79c6d0071c4c 35 /// - TO set to the from address of the original message
charly 0:79c6d0071c4c 36 /// - FROM set to this node address
charly 0:79c6d0071c4c 37 /// - ID set to the ID of the original message
charly 0:79c6d0071c4c 38 /// - FLAGS with the RF22_FLAGS_ACK bit set
charly 0:79c6d0071c4c 39 ///
charly 0:79c6d0071c4c 40 /// Part of the Arduino RF22 library for operating with HopeRF RF22 compatible transceivers
charly 0:79c6d0071c4c 41 /// (see http://www.hoperf.com)
charly 0:79c6d0071c4c 42 class RF22ReliableDatagram : public RF22Datagram
charly 0:79c6d0071c4c 43 {
charly 0:79c6d0071c4c 44 public:
charly 0:79c6d0071c4c 45 /// Constructor.
charly 0:79c6d0071c4c 46 /// \param[in] thisAddress The address to assign to this node. Defaults to 0
charly 0:79c6d0071c4c 47 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before
charly 5:0386600f3408 48 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega)
charly 0:79c6d0071c4c 49 /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2)
charly 0:79c6d0071c4c 50 RF22ReliableDatagram(uint8_t thisAddress ,PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt );
charly 0:79c6d0071c4c 51
charly 0:79c6d0071c4c 52 /// Sets the minimum retransmit timeout. If sendtoWait is waiting for an ack
charly 0:79c6d0071c4c 53 /// longer than this time (in milliseconds),
charly 0:79c6d0071c4c 54 /// it will retransmit the message. Defaults to 200ms. The timeout is measured from the end of
charly 0:79c6d0071c4c 55 /// transmission of the message. It must be at least longer than the the transmit
charly 5:0386600f3408 56 /// time of the acknowledgement (preamble+6 octets) plus the latency/poll time of the receiver.
charly 5:0386600f3408 57 /// For fast modulation schemes you can considerably shorten this time.
charly 0:79c6d0071c4c 58 /// The actual timeout is randomly varied between timeout and timeout*2.
charly 0:79c6d0071c4c 59 /// \param[in] timeout The new timeout period in milliseconds
charly 0:79c6d0071c4c 60 void setTimeout(uint16_t timeout);
charly 0:79c6d0071c4c 61
charly 0:79c6d0071c4c 62 /// Sets the max number of retries. Defaults to 3. If set to 0, the message will only be sent once.
charly 0:79c6d0071c4c 63 /// sendtoWait will give up and return false if there is no ack received after all transmissions time out.
charly 0:79c6d0071c4c 64 /// param[in] retries The maximum number a retries.
charly 0:79c6d0071c4c 65 void setRetries(uint8_t retries);
charly 0:79c6d0071c4c 66
charly 0:79c6d0071c4c 67 /// Send the message and waits for an ack. Returns true if an acknowledgement is received.
charly 0:79c6d0071c4c 68 /// Synchronous: any message other than the desired ACK received while waiting is discarded.
charly 0:79c6d0071c4c 69 /// Blocks until an ACK is received or all retries are exhausted (ie up to retries*timeout milliseconds).
charly 0:79c6d0071c4c 70 /// \param[in] address The address to send the message to.
charly 0:79c6d0071c4c 71 /// \param[in] buf Pointer to the binary message to send
charly 0:79c6d0071c4c 72 /// \param[in] len Number of octets to send
charly 0:79c6d0071c4c 73 /// \return true if the message was transmitted and an acknowledgement was received.
charly 0:79c6d0071c4c 74 boolean sendtoWait(uint8_t* buf, uint8_t len, uint8_t address);
charly 0:79c6d0071c4c 75
charly 0:79c6d0071c4c 76 /// If there is a valid message available for this node, send an acknowledgement to the SRC
charly 0:79c6d0071c4c 77 /// address (blocking until this is complete), then copy the message to buf and return true
charly 0:79c6d0071c4c 78 /// else return false.
charly 0:79c6d0071c4c 79 /// If a message is copied, *len is set to the length..
charly 0:79c6d0071c4c 80 /// If from is not NULL, the SRC address is placed in *from.
charly 0:79c6d0071c4c 81 /// If to is not NULL, the DEST address is placed in *to.
charly 0:79c6d0071c4c 82 /// This is the preferred function for getting messages addressed to this node.
charly 0:79c6d0071c4c 83 /// If the message is not a broadcast, acknowledge to the sender before returning.
charly 0:79c6d0071c4c 84 /// You should be sure to call this function frequently enough to not miss any messages
charly 0:79c6d0071c4c 85 /// It is recommended that you call it in your main loop.
charly 0:79c6d0071c4c 86 /// \param[in] buf Location to copy the received message
charly 0:79c6d0071c4c 87 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
charly 0:79c6d0071c4c 88 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
charly 0:79c6d0071c4c 89 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
charly 0:79c6d0071c4c 90 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
charly 0:79c6d0071c4c 91 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
charly 0:79c6d0071c4c 92 /// (not just those addressed to this node).
charly 0:79c6d0071c4c 93 /// \return true if a valid message was copied to buf
charly 0:79c6d0071c4c 94 boolean recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
charly 0:79c6d0071c4c 95
charly 0:79c6d0071c4c 96 /// Similar to recvfromAck(), this will block until either a valid message available for this node
charly 0:79c6d0071c4c 97 /// or the timeout expires. Starts the receiver automatically.
charly 0:79c6d0071c4c 98 /// You should be sure to call this function frequently enough to not miss any messages
charly 0:79c6d0071c4c 99 /// It is recommended that you call it in your main loop.
charly 0:79c6d0071c4c 100 /// \param[in] buf Location to copy the received message
charly 0:79c6d0071c4c 101 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
charly 0:79c6d0071c4c 102 /// \param[in] timeout Maximum time to wait in milliseconds
charly 0:79c6d0071c4c 103 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
charly 0:79c6d0071c4c 104 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
charly 0:79c6d0071c4c 105 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
charly 0:79c6d0071c4c 106 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
charly 0:79c6d0071c4c 107 /// (not just those addressed to this node).
charly 0:79c6d0071c4c 108 /// \return true if a valid message was copied to buf
charly 0:79c6d0071c4c 109 boolean recvfromAckTimeout(uint8_t* buf, uint8_t* len, uint16_t timeout, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
charly 0:79c6d0071c4c 110
charly 0:79c6d0071c4c 111 /// Returns the number of retransmissions
charly 0:79c6d0071c4c 112 /// we have had to send
charly 0:79c6d0071c4c 113 /// \return The number of retransmissions since initialisation.
charly 0:79c6d0071c4c 114 uint16_t retransmissions();
charly 0:79c6d0071c4c 115
charly 0:79c6d0071c4c 116 protected:
charly 0:79c6d0071c4c 117 /// Send an ACK for the message id to the given from address
charly 0:79c6d0071c4c 118 /// Blocks until the ACK has been sent
charly 0:79c6d0071c4c 119 void acknowledge(uint8_t id, uint8_t from);
charly 0:79c6d0071c4c 120
charly 0:79c6d0071c4c 121 /// Checks whether the message currently in the Rx buffer is a new message, not previously received
charly 0:79c6d0071c4c 122 /// based on the from address and the sequence. If it is new, it is acknowledged and returns true
charly 0:79c6d0071c4c 123 /// \return true if there is a message received and it is a new message
charly 0:79c6d0071c4c 124 boolean haveNewMessage();
charly 0:79c6d0071c4c 125
charly 0:79c6d0071c4c 126 private:
charly 0:79c6d0071c4c 127 /// Count of retransmissions we have had to send
charly 0:79c6d0071c4c 128 uint16_t _retransmissions;
charly 0:79c6d0071c4c 129
charly 0:79c6d0071c4c 130 /// The last sequence number to be used
charly 0:79c6d0071c4c 131 /// Defaults to 0
charly 0:79c6d0071c4c 132 uint8_t _lastSequenceNumber;
charly 0:79c6d0071c4c 133
charly 0:79c6d0071c4c 134 // Retransmit timeout (milliseconds)
charly 0:79c6d0071c4c 135 /// Defaults to 200
charly 0:79c6d0071c4c 136 uint16_t _timeout;
charly 0:79c6d0071c4c 137
charly 0:79c6d0071c4c 138 // Retries (0 means one try only)
charly 0:79c6d0071c4c 139 /// Defaults to 3
charly 0:79c6d0071c4c 140 uint8_t _retries;
charly 0:79c6d0071c4c 141
charly 0:79c6d0071c4c 142 /// Array of the last seen sequence number indexed by node address that sent it
charly 0:79c6d0071c4c 143 /// It is used for duplicate detection. Duplicated messages are re-acknowledged when received
charly 0:79c6d0071c4c 144 /// (this is generally due to lost ACKs, causing the sender to retransmit, even though we have already
charly 0:79c6d0071c4c 145 /// received that message)
charly 0:79c6d0071c4c 146 uint8_t _seenIds[256];
charly 0:79c6d0071c4c 147
charly 0:79c6d0071c4c 148
charly 0:79c6d0071c4c 149 };
charly 0:79c6d0071c4c 150
charly 0:79c6d0071c4c 151 #endif