Jump to content
Sign in to follow this  
Automate

Manchester decoding

Recommended Posts

It's pretty easy to do.  Oversample the signal 2x and then make a lookup table.  The easiest lookup table has 256 bytes and it converts 8 bit of encoded data into 4 bits of decoded data.

 

Or do you have a more complicated datastream?  If so, it's possible to use timer input-capture to perform a more analog-style decoding.

Share this post


Link to post
Share on other sites

I realize this is old, but it was just bumped, so.

 

You can take the code right out of the virtualwire library and use it as is.  I've ported virtualwire to another microcontroller a long time ago and it's super simple, it just takes a single timer.  Nowadays, using those 'dumb' radio modules is a waste of money as better digital transceivers are actually cheaper.

 

Virtualwire uses a 2byte->3byte coding scheme, not manchester.

Share this post


Link to post
Share on other sites

I am still interested in finding a good decoder,I still have no time to work on it.

 

but bsicly I want to make an interface to microchips UnI/O 1 wire interface.

The data is 16bits long with 2 bit mak.

 

so many things to do, so little time to work on them.

Share this post


Link to post
Share on other sites

I'm not certain if there is a question here or not, because the original question has already been answered.  If you want simple RF encoding, you can take it out of the virtualwire library.  They've updated their encoding scheme since I last saw it.

 

Here's the conversion table and decode function:

// 4 bit to 6 bit symbol converter table
// Used to convert the high and low nybbles of the transmitted data
// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 
// with at most 3 consecutive identical bits
static uint8_t symbols[] =
{
    0xd,  0xe,  0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 
    0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
};

//-----------------------------------------

    // Encode the message into 6 bit symbols. Each byte is converted into 
    // 2 6-bit symbols, high nybble first, low nybble second
    for (i = 0; i < len; i++)
    {
	crc = _crc_ccitt_update(crc, buf[i]);
	p[index++] = symbols[buf[i] >> 4];
	p[index++] = symbols[buf[i] & 0xf];
    }

 

The library encodes with crc inline with this code;  (buf gets converted to p)

 

 // Encode the message into 6 bit symbols. Each byte is converted into 
    // 2 6-bit symbols, high nybble first, low nybble second
    for (i = 0; i < len; i++)
    {
	crc = _crc_ccitt_update(crc, buf[i]);
	p[index++] = symbols[buf[i] >> 4];
	p[index++] = symbols[buf[i] & 0xf];
    }

    // Append the fcs, 16 bits before encoding (4 6-bit symbols after encoding)
    // Caution: VW expects the _ones_complement_ of the CCITT CRC-16 as the FCS
    // VW sends FCS as low byte then hi byte
    crc = ~crc;
    p[index++] = symbols[(crc >> 4)  & 0xf];
    p[index++] = symbols[crc & 0xf];
    p[index++] = symbols[(crc >> 12) & 0xf];
    p[index++] = symbols[(crc >> 8)  & 0xf]; 

 

   

VirtualWire:

http://www.open.com.au/mikem/arduino/

Share this post


Link to post
Share on other sites

Here's some code I wrote in a hurry to test out some alarm system modules I got on eBay... If memory serves me right they used some sort of PT2262 encoder (it seemed like a chinese knockoff clone) that generates a 16us sync code pulse and then uses Manchester encoding for the data.

 

The code's pretty sloppy but it worked for what I was testing and I guess I used the "analog style" that jpnorair was talking about.

#include <msp430g2553.h>
#include <stdio.h>

void startTimerA(void){       
	TAR = 0;                                 
	TACTL = TASSEL_2 + MC_2; 
}

void stopTimerA(void){                                           
	TACTL = TASSEL_2 + MC_0; 
}

void main(void)
{
	//Kill WDT and setup clocks
	WDTCTL = WDTPW + WDTHOLD;         
	BCSCTL1 = CALBC1_1MHZ;          
 	DCOCTL = CALDCO_1MHZ;
  	P1DIR |= 0x01; 
  
	P1IES &= ~BIT4;                            // P1.4 Hi/lo edge
	P1IFG &= ~BIT4;                           // P1.4 IFG cleared
	P1IE |= BIT4;                             // P1.4 interrupt enabled

  	P1SEL = BIT1 + BIT2;             
 	P1SEL2 = BIT1 + BIT2; 
 	
	UCA0CTL1 |= UCSSEL_2;                  
	UCA0BR0 = 104;                  
	UCA0BR1 = 0;                             
	UCA0MCTL = UCBRS0;                        
	UCA0CTL1 &= ~UCSWRST; 

  _BIS_SR(LPM4_bits + GIE);                 // Enter LPM4 w/interrupt
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
	if(P1IFG & BIT4){
		int sync = 0;
		while((P1IN & BIT4)){}
		startTimerA();
		while(!(P1IN & BIT4)){}
		sync = TAR;
		stopTimerA();
		if(sync > 14500 && sync < 16700){
			int j = 0;
			char bitcnt = 7;
			char byte = 0;
			char data[3] = {0,0,0};
			for(j=0; j < 24; j++){
				int low = 0;
				int high = 0;
				startTimerA();
				while(P1IN & BIT4){}
				high = TAR;
				stopTimerA();
				startTimerA();
				while(!(P1IN & BIT4)){}
				low = TAR;
				stopTimerA();
			 	if(low > 1200 && high > 300){
			 		data[byte] |= (0 << bitcnt);
			 	}
				else if(low > 300 && high > 1200){
			 		data[byte] |= (1 << bitcnt);
			 	}else {
			 		
			 	}
			 	if(bitcnt == 0){ bitcnt = 7;  byte++; }else{ bitcnt--; }
			}

		while (!(IFG2&UCA0TXIFG));
  		UCA0TXBUF = data[0];
  		while (!(IFG2&UCA0TXIFG));
  		UCA0TXBUF = data[1];
		
  		if(data[0] == 0xFD && data[1] == 0x4F){
  			P1OUT ^= 0x01; 
  		}
  		if(data[0] == 0xFF && data[1] == 0xF5){
  			P1OUT ^= 0x01; 
  		}
		
		}
		P1IFG &= ~0x10;
	} 
	                      
}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...