Class to communicate with ELV(R) MAX! wireless devices with RFM22B-Modules. Based on Library RF22. Initial version unable to send! Only receive! See http://mbed.org/users/charly/notebook/reading-a-max-wireless-window-sensor-with-rfm22-an/
Dependents: RF22_MAX_test_Send
RF22Max.h@1:6321e6784ada, 2013-09-18 (annotated)
- Committer:
- charly
- Date:
- Wed Sep 18 20:03:26 2013 +0000
- Revision:
- 1:6321e6784ada
- Parent:
- 0:565a81d6f278
- Child:
- 2:f75e51ce001b
added documenation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
charly | 1:6321e6784ada | 1 | // RF22Max.h |
charly | 1:6321e6784ada | 2 | // |
charly | 1:6321e6784ada | 3 | // decode messages from ELV-MAX! wireless devices |
charly | 1:6321e6784ada | 4 | // based on RF22-Class (C) by Mike McCauley (mikem@open.com.au) for RFM22 transceiver-modules by HopeRF |
charly | 1:6321e6784ada | 5 | // |
charly | 1:6321e6784ada | 6 | |
charly | 1:6321e6784ada | 7 | /// \version 1.00 Working class for Receive |
charly | 1:6321e6784ada | 8 | /// \author Karl Zweimueller http://mbed.org/users/charly/ |
charly | 1:6321e6784ada | 9 | |
charly | 0:565a81d6f278 | 10 | #ifndef RF22Max_h |
charly | 0:565a81d6f278 | 11 | #define RF22Max_h |
charly | 0:565a81d6f278 | 12 | |
charly | 0:565a81d6f278 | 13 | #include "mbed.h" |
charly | 0:565a81d6f278 | 14 | #include <RF22.h> |
charly | 0:565a81d6f278 | 15 | |
charly | 0:565a81d6f278 | 16 | // define DEBUG if you want to see bufer-output on pc (defined in main) |
charly | 0:565a81d6f278 | 17 | #ifdef DEBUG |
charly | 0:565a81d6f278 | 18 | extern Serial pc; |
charly | 0:565a81d6f278 | 19 | #endif |
charly | 0:565a81d6f278 | 20 | |
charly | 0:565a81d6f278 | 21 | #define lengthof(x) (sizeof(x) / sizeof(*x)) |
charly | 1:6321e6784ada | 22 | ///////////////////////////////////////////////////////////////////// |
charly | 1:6321e6784ada | 23 | /// \class RF22Max RF22Max.h <RF22Max.h> |
charly | 1:6321e6784ada | 24 | /// \brief receive (in future also send) packets from/to MAX! Devices by ELV (http://www.elv.de/max-funk-heizungsregler-system.html) |
charly | 1:6321e6784ada | 25 | /// |
charly | 1:6321e6784ada | 26 | /// This class provides basic functions for sending and receiving MAX!-messages, |
charly | 1:6321e6784ada | 27 | /// at the moment only receiving possible |
charly | 1:6321e6784ada | 28 | /// ueses recv() from RF22 |
charly | 1:6321e6784ada | 29 | /// based on RF22-Class (C) by Mike McCauley (mikem@open.com.au) for RFM22 transceiver-modules by HopeRF |
charly | 1:6321e6784ada | 30 | /// returns decodes message and payload for further processing |
charly | 1:6321e6784ada | 31 | /// |
charly | 0:565a81d6f278 | 32 | class RF22Max : public RF22 |
charly | 0:565a81d6f278 | 33 | { |
charly | 0:565a81d6f278 | 34 | public: |
charly | 1:6321e6784ada | 35 | /// \brief a message from a max!-Device |
charly | 1:6321e6784ada | 36 | /// |
charly | 1:6321e6784ada | 37 | /// structure for a MAX!-Message |
charly | 1:6321e6784ada | 38 | /// includes decoded fields and the payload |
charly | 1:6321e6784ada | 39 | /// also has some specific field, which are only valid on some message-types |
charly | 1:6321e6784ada | 40 | /// |
charly | 1:6321e6784ada | 41 | /// Message-types: |
charly | 1:6321e6784ada | 42 | /// |
charly | 1:6321e6784ada | 43 | /// 0x00: "PairPing" |
charly | 1:6321e6784ada | 44 | /// |
charly | 1:6321e6784ada | 45 | /// 0x01: "PairPong"; |
charly | 1:6321e6784ada | 46 | /// |
charly | 1:6321e6784ada | 47 | /// 0x02: "Ack"; |
charly | 1:6321e6784ada | 48 | /// |
charly | 1:6321e6784ada | 49 | /// 0x03: "TimeInformation"; |
charly | 1:6321e6784ada | 50 | /// |
charly | 1:6321e6784ada | 51 | /// 0x10: "ConfigWeekProfile"; |
charly | 1:6321e6784ada | 52 | /// |
charly | 1:6321e6784ada | 53 | /// 0x11: "ConfigTemperatures"; |
charly | 1:6321e6784ada | 54 | /// |
charly | 1:6321e6784ada | 55 | /// 0x12: "ConfigValve"; |
charly | 1:6321e6784ada | 56 | /// |
charly | 1:6321e6784ada | 57 | /// 0x20: "AddLinkPartner"; |
charly | 1:6321e6784ada | 58 | /// |
charly | 1:6321e6784ada | 59 | /// 0x21: "RemoveLinkPartner"; |
charly | 1:6321e6784ada | 60 | /// |
charly | 1:6321e6784ada | 61 | /// 0x22: "SetGroupId"; |
charly | 1:6321e6784ada | 62 | /// |
charly | 1:6321e6784ada | 63 | /// 0x23: "RemoveGroupId"; |
charly | 1:6321e6784ada | 64 | /// |
charly | 1:6321e6784ada | 65 | /// 0x30: "ShutterContactState"; |
charly | 1:6321e6784ada | 66 | /// |
charly | 1:6321e6784ada | 67 | /// 0x40: "SetTemperature"; |
charly | 1:6321e6784ada | 68 | /// |
charly | 1:6321e6784ada | 69 | /// 0x42: "WallThermostatState"; |
charly | 1:6321e6784ada | 70 | /// |
charly | 1:6321e6784ada | 71 | /// 0x43: "SetComfortTemperature"; |
charly | 1:6321e6784ada | 72 | /// |
charly | 1:6321e6784ada | 73 | /// 0x44: "SetEcoTemperature"; |
charly | 1:6321e6784ada | 74 | /// |
charly | 1:6321e6784ada | 75 | /// 0x50: "PushButtonState"; |
charly | 1:6321e6784ada | 76 | /// |
charly | 1:6321e6784ada | 77 | /// 0x60: "ThermostatState"; |
charly | 1:6321e6784ada | 78 | /// |
charly | 1:6321e6784ada | 79 | /// 0x82: "SetDisplayActualTemperature"; |
charly | 1:6321e6784ada | 80 | /// |
charly | 1:6321e6784ada | 81 | /// 0xF1: "WakeUp"; |
charly | 1:6321e6784ada | 82 | /// |
charly | 1:6321e6784ada | 83 | /// 0xF0: "Reset"; |
charly | 1:6321e6784ada | 84 | /// |
charly | 0:565a81d6f278 | 85 | |
charly | 1:6321e6784ada | 86 | typedef struct { |
charly | 1:6321e6784ada | 87 | uint8_t len; ///< Message-length |
charly | 1:6321e6784ada | 88 | uint8_t cnt; ///< Message-counter |
charly | 1:6321e6784ada | 89 | uint8_t flags; ///< unknown |
charly | 1:6321e6784ada | 90 | uint8_t type; ///< Message-type |
charly | 1:6321e6784ada | 91 | char type_str[50]; ///< Message-Type in text |
charly | 1:6321e6784ada | 92 | uint32_t frm_adr; ///< Unique address of device From |
charly | 1:6321e6784ada | 93 | uint32_t to_adr; ///< Unique address of device To |
charly | 1:6321e6784ada | 94 | uint8_t groupid; ///< Groupid |
charly | 1:6321e6784ada | 95 | uint8_t payload[50]; ///< Data |
charly | 1:6321e6784ada | 96 | uint16_t crc; ///< CRC for the message |
charly | 1:6321e6784ada | 97 | char state[50]; ///< State of the device: open, closed, auto, eco,... |
charly | 1:6321e6784ada | 98 | char battery_state[50]; ///< Battery-state of the device : good, low |
charly | 1:6321e6784ada | 99 | } max_message; |
charly | 0:565a81d6f278 | 100 | |
charly | 1:6321e6784ada | 101 | /// Constructor |
charly | 1:6321e6784ada | 102 | /// Create an object for a RFM22-module connected to the controller via SPI, SlaveSelect and Interrupt-pin |
charly | 1:6321e6784ada | 103 | /// \param[in] slaveSelectPin SlaveSelectPin |
charly | 1:6321e6784ada | 104 | /// \param[in] mosi SPI |
charly | 1:6321e6784ada | 105 | /// \param[in] miso SPI |
charly | 1:6321e6784ada | 106 | /// \param[in] sclk SPI |
charly | 1:6321e6784ada | 107 | /// \param[in] interrupt Interrupt line for RFM22 |
charly | 1:6321e6784ada | 108 | RF22Max(PinName slaveSelectPin, PinName mosi, PinName miso, PinName sclk, PinName interrupt); |
charly | 1:6321e6784ada | 109 | |
charly | 1:6321e6784ada | 110 | /// Initialize the module for MAX!-messages |
charly | 1:6321e6784ada | 111 | /// sets frequency, datarate, ... |
charly | 1:6321e6784ada | 112 | /// \return true if everything was successful |
charly | 1:6321e6784ada | 113 | boolean init(); |
charly | 0:565a81d6f278 | 114 | |
charly | 1:6321e6784ada | 115 | /// start receiver and see if a valid MAX!-message is available and return it undecoded to the caller |
charly | 1:6321e6784ada | 116 | /// nonblocking |
charly | 1:6321e6784ada | 117 | /// check crc and do dewithening |
charly | 1:6321e6784ada | 118 | /// \param[in] buf Location to copy the received message |
charly | 1:6321e6784ada | 119 | /// \param[in,out] len Pointer to available space in buf(copies maximum len bytes!). Set to the actual number of octets copied. |
charly | 1:6321e6784ada | 120 | /// \return true if a valid message was copied to buf |
charly | 1:6321e6784ada | 121 | boolean recv(uint8_t* buf, uint8_t* len); |
charly | 1:6321e6784ada | 122 | |
charly | 1:6321e6784ada | 123 | /// start receiver and see if a valid MAX!-message is available and return the decoded message to the caller |
charly | 1:6321e6784ada | 124 | /// nonblocking |
charly | 1:6321e6784ada | 125 | /// check crc and do dewithening and do decoding of fields |
charly | 1:6321e6784ada | 126 | /// \param[in] message A pointer to a RF22Max::max_message |
charly | 1:6321e6784ada | 127 | /// \return true if a valid message was copied to buf |
charly | 1:6321e6784ada | 128 | boolean recv_max(RF22Max::max_message* message); |
charly | 0:565a81d6f278 | 129 | |
charly | 0:565a81d6f278 | 130 | private: |
charly | 0:565a81d6f278 | 131 | |
charly | 0:565a81d6f278 | 132 | #ifdef DEBUG |
charly | 1:6321e6784ada | 133 | /// show received buffer on serial pc |
charly | 1:6321e6784ada | 134 | void printHex(uint8_t *buf, size_t len, bool nl); |
charly | 0:565a81d6f278 | 135 | #endif |
charly | 0:565a81d6f278 | 136 | |
charly | 1:6321e6784ada | 137 | /// calc_crc_setup setup crc-calculation |
charly | 1:6321e6784ada | 138 | uint16_t calc_crc_step(uint8_t crcData, uint16_t crcReg); |
charly | 0:565a81d6f278 | 139 | |
charly | 1:6321e6784ada | 140 | /// calc_crc calculate crc for the data in buf |
charly | 1:6321e6784ada | 141 | uint16_t calc_crc(uint8_t *buf, size_t len); |
charly | 0:565a81d6f278 | 142 | |
charly | 0:565a81d6f278 | 143 | |
charly | 0:565a81d6f278 | 144 | }; // end class RF22Max |
charly | 0:565a81d6f278 | 145 | |
charly | 1:6321e6784ada | 146 | #endif |