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 the Manchester.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:

/media/uploads/hudakz/manchester01.png

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.

Revision:
5:3b2c7e9fda3f
Parent:
4:f2c392191c74
Child:
6:7454ad91f714
--- a/Manchester.cpp	Thu May 18 13:37:21 2017 +0000
+++ b/Manchester.cpp	Sun May 21 19:17:28 2017 +0000
@@ -25,6 +25,22 @@
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+/*
+   This library implements Manchester code according to both IEEE 802.3 
+   and G.E. Thomas' convention. 
+   • 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 is one synchronization pulse at the begin of transmission 
+   
+   The IEEE 802.3 convention is used by default.
+   Select a convention to be used by commenting or uncommenting 
+   the line "#define G_E_THOMAS 1" in the Manchester.h header file.
+ */
+
 #include "Manchester.h"
 #include "ManchesterMsg.h"
 
@@ -41,8 +57,8 @@
     (
         PinName txPin, 
         PinName rxPin, 
-        uint32_t speed  /* = 1200 bps */, 
-        uint8_t tol     /* = 20% */ 
+        uint32_t speed, /* = 1200 bps */ 
+        uint8_t tol     /* = (+/-)25% */ 
     ) : 
     _tx(txPin), 
     _rx(rxPin) {
@@ -53,6 +69,11 @@
     _rx.disable_irq();
     _rx.rise(callback(this, &Manchester::reception));
     _rx.fall(callback(this, &Manchester::reception));
+#ifdef G_E_THOMAS
+    _tx = 1;
+#else
+    _tx = 0;
+#endif
 }
 
 /**
@@ -94,7 +115,11 @@
 
     switch(_state) {
     case SYNCH_START:
-        _tx = 0;            // pull the line low to start synch pulse
+#ifdef G_E_THOMAS
+        _tx = 0;            // pull line low to start synch pulse
+#else
+        _tx = 1;            // bring line high to start synch pulse
+#endif
         _state = SYNCH_NEXT;
         break;
 
@@ -103,7 +128,11 @@
         break;
 
     case SYNCH_END:
+#ifdef G_E_THOMAS
         _tx = 1;            // bring line high for end of sych pulse
+#else
+        _tx = 0;            // pull line low for end of sych pulse
+#endif      
         byteIndex = 0;
         encodeByte = _data[byteIndex];
         bitIndex = 0;
@@ -111,15 +140,20 @@
         break;
 
     case SETUP:
-        if(encodeByte & 0x01)
-            _tx = (encodeByte & 0x01) | _tx;    // next bit to transmit is a "1"
-        else
-            _tx = (encodeByte & 0x01) & _tx;    // next bit to transmit is a "0"
+#ifdef G_E_THOMAS
+        _tx = encodeByte & 0x01;    // setup for next bit to transmit
+#else
+        _tx = !(encodeByte & 0x01); // setup for next bit to transmit
+#endif      
         _state = TRANSITION;
         break;
 
     case TRANSITION:
-        _tx = (encodeByte & 0x01) ^ 0x01;       // set line appropriately for transition
+#ifdef G_E_THOMAS
+        _tx = !(encodeByte & 0x01); // set line appropriately for transition
+#else
+        _tx = encodeByte & 0x01;    // set line appropriately for transition
+#endif
         if(++bitIndex < 8) {
             encodeByte = (encodeByte >> 1);
             _state = SETUP;
@@ -136,7 +170,11 @@
         break;
 
     case COMPLETE:
+#ifdef G_E_THOMAS
         _tx = 1;    // transmission is complete, bring line high
+#else
+        _tx = 0;    // transmission is complete, pull line low       
+#endif      
         _state = IDLE;
         break;
 
@@ -151,8 +189,8 @@
  * @brief   ISR handling 'transmission timeout'
  * @note    Called when transmitter is stuck.
  *          Signals 'end of transmission' by setting state to IDLE
- * @param   None
- * @retval  None
+ * @param   
+ * @retval  
  */
 void Manchester::txTimeout(void) {
     _timeout.detach();
@@ -218,7 +256,11 @@
     switch(_state) {
     case LISTEN:
         begin = now;
+#ifdef G_E_THOMAS
         if(_rx == 0)
+#else
+        if(_rx == 1)
+#endif        
             _state = SYNCH_START;
         else
             _state = ERROR;  // It isn't a synch pulse => error
@@ -226,7 +268,11 @@
 
     case SYNCH_START:
         pulseWidth = now - begin;
+#ifdef G_E_THOMAS
         if((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth) && (_rx == 1)) {
+#else
+        if((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth) && (_rx == 0)) {
+#endif
             begin = now;
             decodeByte = 0;
             bitIndex = 0;
@@ -241,7 +287,11 @@
         pulseWidth = now - begin;
         if((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth)) {
             begin = now;
+#ifdef G_E_THOMAS
             decodeByte |= (((_rx == 0) & 0x01) << bitIndex++);
+#else
+            decodeByte |= (((_rx == 1) & 0x01) << bitIndex++);
+#endif
             if(bitIndex > 7) {
                 _data[_len++] = decodeByte;
                 if(_len > _maxLen - 1)
@@ -271,14 +321,19 @@
  * @note    Called when receiver line is idle longer than limit.
  *          Signals 'end of transmission' by setting state to IDLE
  *          or 'timeout error' by setting state to ERROR.
- * @param   None
- * @retval  None
+ * @param   
+ * @retval  
  */
 void Manchester::rxTimeout(void) {
     _timeout.detach();
 
+#ifdef G_E_THOMAS
     if((_state == DECODE) && (_rx == 1))
+#else
+    if((_state == DECODE) && (_rx == 0))
+#endif
         _state = IDLE;  // End of transmission
     else
         _state = ERROR; // Incomplete transmission
 }
+