Manchester code (phase encoding) library.
Dependents: Manchester_Transmitter Manchester_Receiver
Manchester code (phase encoding) library
It implements Manchester code according to both IEEE 802.3 and G.E. Thomas' conventions.
- A '0' is expressed by a high-to-low transition, a '1' by low-to-high transition in the IEEE 802.3 convention. The reverse is true in the G.E. Thomas' convention.
- The transitions which signify '0' or '1' occur at the midpoint of a period.
- Transitions at the start of a period are overhead and don't signify data.
- Least significant bit is sent first
- There are synchronization pulses (the number can be set) at the begin of transmission
Select a convention to be used by commenting or uncommenting the line below in theManchester.h
header file.
Manchester.h
#define G_E_THOMAS 1
The IEEE 802.3 convention is used by default.
A Manchester encoded message (using G.E. Thomas' convention), with one sync pulse in the preamble, carrying four bytes:
ACKNOWLEDGEMENT: The code in this library was based on this article published by Robert Guastella.
Import programManchester_Transmitter
Manchester transmitter demo.
Import programManchester_Receiver
Manchester receiver demo.
NOTE: To perform a simple test (without radio modules) connect the txPin on transmitter board to the rxPin on the receiver board and make sure that grounds are also connected one another.
ManchesterMsg.h@0:d5c75b0e5708, 2017-05-17 (annotated)
- Committer:
- hudakz
- Date:
- Wed May 17 07:52:15 2017 +0000
- Revision:
- 0:d5c75b0e5708
- Child:
- 2:de778df5892c
Initial issue.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hudakz | 0:d5c75b0e5708 | 1 | /* |
hudakz | 0:d5c75b0e5708 | 2 | ****************************************************************************** |
hudakz | 0:d5c75b0e5708 | 3 | * @file ManchesterMsg.h |
hudakz | 0:d5c75b0e5708 | 4 | * @author Zoltan Hudak |
hudakz | 0:d5c75b0e5708 | 5 | * @version |
hudakz | 0:d5c75b0e5708 | 6 | * @date 16-May-2017 |
hudakz | 0:d5c75b0e5708 | 7 | * @brief Message container |
hudakz | 0:d5c75b0e5708 | 8 | ****************************************************************************** |
hudakz | 0:d5c75b0e5708 | 9 | * @attention |
hudakz | 0:d5c75b0e5708 | 10 | * |
hudakz | 0:d5c75b0e5708 | 11 | * <h2><center>© COPYRIGHT(c) 2017 Zoltan Hudak <hudakz@outlook.com> |
hudakz | 0:d5c75b0e5708 | 12 | * |
hudakz | 0:d5c75b0e5708 | 13 | * All rights reserved. |
hudakz | 0:d5c75b0e5708 | 14 | |
hudakz | 0:d5c75b0e5708 | 15 | This program is free software: you can redistribute it and/or modify |
hudakz | 0:d5c75b0e5708 | 16 | it under the terms of the GNU General Public License as published by |
hudakz | 0:d5c75b0e5708 | 17 | the Free Software Foundation, either version 3 of the License, or |
hudakz | 0:d5c75b0e5708 | 18 | (at your option) any later version. |
hudakz | 0:d5c75b0e5708 | 19 | |
hudakz | 0:d5c75b0e5708 | 20 | This program is distributed in the hope that it will be useful, |
hudakz | 0:d5c75b0e5708 | 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
hudakz | 0:d5c75b0e5708 | 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
hudakz | 0:d5c75b0e5708 | 23 | GNU General Public License for more details. |
hudakz | 0:d5c75b0e5708 | 24 | |
hudakz | 0:d5c75b0e5708 | 25 | You should have received a copy of the GNU General Public License |
hudakz | 0:d5c75b0e5708 | 26 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
hudakz | 0:d5c75b0e5708 | 27 | */ |
hudakz | 0:d5c75b0e5708 | 28 | |
hudakz | 0:d5c75b0e5708 | 29 | #ifndef MANCHESTERMSG_H |
hudakz | 0:d5c75b0e5708 | 30 | #define MANCHESTERMSG_H |
hudakz | 0:d5c75b0e5708 | 31 | |
hudakz | 0:d5c75b0e5708 | 32 | //#define DEBUG 1 |
hudakz | 0:d5c75b0e5708 | 33 | |
hudakz | 0:d5c75b0e5708 | 34 | /** ManchesterMsg class |
hudakz | 0:d5c75b0e5708 | 35 | */ |
hudakz | 0:d5c75b0e5708 | 36 | class ManchesterMsg |
hudakz | 0:d5c75b0e5708 | 37 | { |
hudakz | 0:d5c75b0e5708 | 38 | unsigned char _max; // Max length (capacity) of data field in bytes |
hudakz | 0:d5c75b0e5708 | 39 | |
hudakz | 0:d5c75b0e5708 | 40 | public: |
hudakz | 0:d5c75b0e5708 | 41 | char* data; // Data field |
hudakz | 0:d5c75b0e5708 | 42 | unsigned char len; // Length of data in bytes |
hudakz | 0:d5c75b0e5708 | 43 | |
hudakz | 0:d5c75b0e5708 | 44 | /** Creates empty Manchester message of specified capacity. |
hudakz | 0:d5c75b0e5708 | 45 | */ |
hudakz | 0:d5c75b0e5708 | 46 | ManchesterMsg(unsigned char max) : |
hudakz | 0:d5c75b0e5708 | 47 | _max(max), |
hudakz | 0:d5c75b0e5708 | 48 | data(new char[max]) { len = 0; } |
hudakz | 0:d5c75b0e5708 | 49 | |
hudakz | 0:d5c75b0e5708 | 50 | ~ManchesterMsg(void) { delete[] data; } |
hudakz | 0:d5c75b0e5708 | 51 | |
hudakz | 0:d5c75b0e5708 | 52 | /** Copy constructor. |
hudakz | 0:d5c75b0e5708 | 53 | */ |
hudakz | 0:d5c75b0e5708 | 54 | ManchesterMsg(const ManchesterMsg& msg) { |
hudakz | 0:d5c75b0e5708 | 55 | len = msg.len; |
hudakz | 0:d5c75b0e5708 | 56 | memcpy(data, msg.data, msg.len); |
hudakz | 0:d5c75b0e5708 | 57 | } |
hudakz | 0:d5c75b0e5708 | 58 | |
hudakz | 0:d5c75b0e5708 | 59 | |
hudakz | 0:d5c75b0e5708 | 60 | /** Returns message maximum length (capacity) |
hudakz | 0:d5c75b0e5708 | 61 | */ |
hudakz | 0:d5c75b0e5708 | 62 | unsigned char maxLen(void) { return _max; } |
hudakz | 0:d5c75b0e5708 | 63 | |
hudakz | 0:d5c75b0e5708 | 64 | /** Clears message content |
hudakz | 0:d5c75b0e5708 | 65 | */ |
hudakz | 0:d5c75b0e5708 | 66 | void clear(void) { len = 0; memset(data, 0, _max); } |
hudakz | 0:d5c75b0e5708 | 67 | |
hudakz | 0:d5c75b0e5708 | 68 | /** Inserter operator: Appends data (value) to Manchester message |
hudakz | 0:d5c75b0e5708 | 69 | */ |
hudakz | 0:d5c75b0e5708 | 70 | template<class T> |
hudakz | 0:d5c75b0e5708 | 71 | ManchesterMsg &operator<<(const T val) { |
hudakz | 0:d5c75b0e5708 | 72 | if(len + sizeof(T) <= _max) { |
hudakz | 0:d5c75b0e5708 | 73 | *reinterpret_cast <T*> (&data[len]) = val; |
hudakz | 0:d5c75b0e5708 | 74 | len += sizeof(T); |
hudakz | 0:d5c75b0e5708 | 75 | } |
hudakz | 0:d5c75b0e5708 | 76 | |
hudakz | 0:d5c75b0e5708 | 77 | #if DEBUG |
hudakz | 0:d5c75b0e5708 | 78 | else { |
hudakz | 0:d5c75b0e5708 | 79 | printf("Error: Cannot append data. Exceeding max data length!\r\n"); |
hudakz | 0:d5c75b0e5708 | 80 | } |
hudakz | 0:d5c75b0e5708 | 81 | #endif |
hudakz | 0:d5c75b0e5708 | 82 | return *this; |
hudakz | 0:d5c75b0e5708 | 83 | } |
hudakz | 0:d5c75b0e5708 | 84 | |
hudakz | 0:d5c75b0e5708 | 85 | /** Inserter operator: Appends string of char to Manchester message |
hudakz | 0:d5c75b0e5708 | 86 | */ |
hudakz | 0:d5c75b0e5708 | 87 | ManchesterMsg &operator<<(const char* str) { |
hudakz | 0:d5c75b0e5708 | 88 | unsigned char strLen = strlen(str); |
hudakz | 0:d5c75b0e5708 | 89 | if(len + strLen + 1 <= _max) { |
hudakz | 0:d5c75b0e5708 | 90 | memcpy(data + len, (char*)str, strLen); |
hudakz | 0:d5c75b0e5708 | 91 | len += strLen; |
hudakz | 0:d5c75b0e5708 | 92 | data[len++] = '\0'; |
hudakz | 0:d5c75b0e5708 | 93 | } |
hudakz | 0:d5c75b0e5708 | 94 | |
hudakz | 0:d5c75b0e5708 | 95 | #if DEBUG |
hudakz | 0:d5c75b0e5708 | 96 | else { |
hudakz | 0:d5c75b0e5708 | 97 | printf("Error: Cannot append data. Exceeding max data length!\r\n"); |
hudakz | 0:d5c75b0e5708 | 98 | } |
hudakz | 0:d5c75b0e5708 | 99 | #endif |
hudakz | 0:d5c75b0e5708 | 100 | return *this; |
hudakz | 0:d5c75b0e5708 | 101 | } |
hudakz | 0:d5c75b0e5708 | 102 | |
hudakz | 0:d5c75b0e5708 | 103 | /** Extractor operator: Extracts data (value) from CAN message |
hudakz | 0:d5c75b0e5708 | 104 | */ |
hudakz | 0:d5c75b0e5708 | 105 | template<class T> |
hudakz | 0:d5c75b0e5708 | 106 | ManchesterMsg &operator>>(T& val) { |
hudakz | 0:d5c75b0e5708 | 107 | if(sizeof(T) <= len) { |
hudakz | 0:d5c75b0e5708 | 108 | val = *reinterpret_cast <T*> (&data[0]); |
hudakz | 0:d5c75b0e5708 | 109 | len -= sizeof(T); |
hudakz | 0:d5c75b0e5708 | 110 | memcpy(data, data + sizeof(T), len); |
hudakz | 0:d5c75b0e5708 | 111 | } |
hudakz | 0:d5c75b0e5708 | 112 | |
hudakz | 0:d5c75b0e5708 | 113 | #if DEBUG |
hudakz | 0:d5c75b0e5708 | 114 | else { |
hudakz | 0:d5c75b0e5708 | 115 | printf("Error: Cannot extract data. Exceeding data length!\r\n"); |
hudakz | 0:d5c75b0e5708 | 116 | } |
hudakz | 0:d5c75b0e5708 | 117 | #endif |
hudakz | 0:d5c75b0e5708 | 118 | return *this; |
hudakz | 0:d5c75b0e5708 | 119 | } |
hudakz | 0:d5c75b0e5708 | 120 | /** Extractor operator: Extracts string of char from CAN message |
hudakz | 0:d5c75b0e5708 | 121 | */ |
hudakz | 0:d5c75b0e5708 | 122 | ManchesterMsg &operator>>(char* str) { |
hudakz | 0:d5c75b0e5708 | 123 | unsigned char strLen = strlen(data); |
hudakz | 0:d5c75b0e5708 | 124 | if(strLen <= len) { |
hudakz | 0:d5c75b0e5708 | 125 | memcpy(str, data, strLen + 1); |
hudakz | 0:d5c75b0e5708 | 126 | len -= (strLen + 1); |
hudakz | 0:d5c75b0e5708 | 127 | memcpy(data, data + strLen + 1, len); |
hudakz | 0:d5c75b0e5708 | 128 | } |
hudakz | 0:d5c75b0e5708 | 129 | |
hudakz | 0:d5c75b0e5708 | 130 | #if DEBUG |
hudakz | 0:d5c75b0e5708 | 131 | else { |
hudakz | 0:d5c75b0e5708 | 132 | printf("Error: Cannot extract data. Exceeding data length!\r\n"); |
hudakz | 0:d5c75b0e5708 | 133 | } |
hudakz | 0:d5c75b0e5708 | 134 | #endif |
hudakz | 0:d5c75b0e5708 | 135 | return *this; |
hudakz | 0:d5c75b0e5708 | 136 | } |
hudakz | 0:d5c75b0e5708 | 137 | }; |
hudakz | 0:d5c75b0e5708 | 138 | #endif // MANCHESTERMSG_H |