CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

what is the problem with my manchester en(de)coding program?
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 8:26 am     Reply with quote

Hi Humberto:
here is the code that I changed according to your advised bit by bit manchester data transmitting, please have a check if I am doing correct, specially about the timing

Code:

/*********************************************************/
/*                                                       */
/*      Send Manchester data bit by bit                  */
/*                                                       */
/*********************************************************/


#if defined(__PCM__)
#include <16F819.h>
#include <stdio.h>
#include <stdlib.h>
#fuses HS,WDT,NOPROTECT
//#device ADC=10
#use delay(clock=10000000)
#use rs232(baud=2400, parity=N, xmit=PIN_A0)

#define M_Tx_Pin PIN_A1

void SEND_DATA(BYTE txbyte)
{
    int i,j,b,me;

    b = txbyte;

    for (i=0; i<2; i++)
    {
        delay_ms(10);
        me = 0;         // manchester encoded txbyte
        for (j=0 ; j<4; j++) {
            me >>=2;
            if (bit_test(b,0) )
                me |= 0b01000000; // 1->0
            else
                me |= 0b10000000; // 0->1
            b >>=1;
        }
     //send data bit by bit through M_Tx_Pin for every 416.66 ms
        for(i=0;i<8;i++)
         {
          //putc(me);
          if(bit_test(me,i))
             output_high(M_Tx_Pin);
          else
             output_low(M_Tx_Pin);
          delay_us(417);
         }

    }

}
//

void remoteprintf(char *c)
{
   int8 i,length;
   length=strlen(c);
   //premable data to init TWS
   for(i=0;i<4;i++)
   {
    output_low(M_Tx_Pin);
    delay_us(417);
   }


   // send data
   for (i=0; i<length;i++)
      SEND_DATA(c[i]);


   //send stop

   for(i=0;i<4;i++)
   {
    output_high(M_Tx_Pin);
    delay_us(417);
   }

}


void main()
{
  char data[]="I am flying!";
   setup_port_a(ADC_OFF);
   set_tris_a(0xf3);
   setup_CCP1(CCP_OFF);
   setup_timer_1(T1_DISABLED);

   enable_interrupts(global);

   while(1)
   {
   remoteprintf(data);
  }
}

Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 9:15 am     Reply with quote

Imanjl wrote:
Quote:

I put a scope probe on the rx output of rf module and the waveform was
a continuous 01010101 bit with this pattern if we route this pin to PIC RX
input It always fills the buffer and aslo generate RDA interrupt that is
unwantted ..


I wrote:"To detect the data you need to know what is the iddle state of Rx
output in the RWS434 receiver."

1)Receiver Iddle state = no RF present

2)I never mention to enable RDA interrupt. To receive this kind of signal,
you must write a software handler.

3)As you see, DATA info has a transition in every bit. The idea to send the
sequence 0000 is to detect a LOW STATE 4 times longer than a
LOW in the DATA frame and validate it as a START.
Sending the sequence 1111 is to detect a HIGH STATE 4 times longer
than a HIGH in the DATA frame and validate it as a STOP.
START and STOP are used only as header and trailer
0000 + 1111 give you a null DC component in your DATA packets (D).

Example:

START DDDDDDDDDDDDDDDD STOP


Humberto
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 9:42 am     Reply with quote

remodified encoding file

Code:
/*********************************************************/
/*                                                       */
/*      Send Manchester data bit by bit                  */
/*                                                       */
/*********************************************************/


#if defined(__PCM__)
#include <16F819.h>
#include <stdio.h>
#include <stdlib.h>
#fuses HS,WDT,NOPROTECT
//#device ADC=10
#use delay(clock=10000000)
#use rs232(baud=2400, parity=N, xmit=PIN_A0)

#define M_Tx_Pin PIN_A1

void SEND_DATA(BYTE txbyte)
{

 
    int i,j,b,me;

    b = txbyte;
    putc(txbyte);
    for(i=0;i<8;i++)
    {
      if(bit_test(me,i))
      {  output_high(M_Tx_Pin);
        delay_us(417);
        output_low(M_Tx_Pin);
        delay_us(417);
      }
      else
    {  output_low(M_Tx_Pin);
        delay_us(417);
        output_high(M_Tx_Pin);
        delay_us(417);
      }
    }
}
//

void remoteprintf(char *c)
{
   int8 i,length;
   length=strlen(c);
   //premable data to init TWS
   for(i=0;i<4;i++)
   {
    output_low(M_Tx_Pin);
    delay_us(417);
   }

 //  printf("length: %u\r\n",length);
   // send data
   for (i=0; i<length;i++)
      SEND_DATA(c[i]);


   //send stop

   for(i=0;i<4;i++)
   {
    output_high(M_Tx_Pin);
    delay_us(417);
   }

}


void main()
{
  char data[]="bc";
   setup_port_a(ADC_OFF);
   set_tris_a(0xf3);
   setup_CCP1(CCP_OFF);
   setup_timer_1(T1_DISABLED);

   enable_interrupts(global);

   while(1)
   {
   remoteprintf(data);
  }
}

young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 9:58 am     Reply with quote

Hi Humberto:

Great appreciation for your come back!


I put a delay after my sending data
while(1)
{
remoteprintf(data);
delay_ms(100);
}
and find out that my idal state of Rx is High.


Here I have three questions

1. This the timing delay after sending each individual bit delay_us(417) right,
2. I am really not sure how to detect start and stop bit even It is clear in concept, I do not not how to program it?
3. during the ideal states there are some noise (it is not alway high, occassionally, there is low signal also, is it normal?
Would you please help
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 10:18 am     Reply with quote

another problem I found is that between each byte (not bit) there is period of low signal for the program, I made, which I think it should not be there, why?
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 10:22 am     Reply with quote

and why I delete the delay_ms(100) after sending the data, the above low level signal will be gone, all the data is just as what you describs
start data stop, why this delay is so trouble making?
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 11:41 am     Reply with quote

saw some posts that use interrupt to decode the received data, here is my proposal, is this right?

1. define the external interrupt Pin as Receive Pin

#define M_Rx_Pin PIN_B0 //(16f819) at edge H_L

2. when a exteral interrupt occured, the external interrupt routine (Ext_int)will setup a timer, for example timer0(Timer_int);

3. Timer0 will count the time, if time reach a certain value; it will invoke (Timer_int);

4. in the routine(Timer_int); will disable external interrupt routine,read input data from the M_Rx_Pin for every certain time period, and at same time setup external interrupt as low to high, at setup timer, if timer reach a certain period, means a stops bit being encounted, end the reading data.

is this doable?
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 12:28 pm     Reply with quote

Hola young,

Sorry for this delay but I had been busy.
I preffer that you work, not me Very Happy and I want to say you that I like the
way you solve the routine SEND_DATA(BYTE txbyte) it's a very
good aproach and the most important: you learn

Quote:

Here I have three questions

1. This the timing delay after sending each individual bit delay_us(417) right,
2. I am really not sure how to detect start and stop bit even It is clear in concept, I do not not how to program it?
3. during the ideal states there are some noise (it is not alway high, occassionally, there is low signal also, is it normal?


1. YES. Baud is the number of signal level changes per second in a
communication line, regardless of the information content of those
signals. Bits per second is the rate of transfer of information bits.
The ratio of BPS to baud depends on the information coding
scheme that you are using. 1 or 2 Stop bit, Parity, etc
For example, each character in asynchronous RS232 coding includes a
start and stop bit that are not counted as information bits, so
the BPS rate is actually less than the baud rate.

2.Fortunately there are a few options:
a) Using CCP
b) Using INT_EXT + any TIMER
c) Polling + TIMER (Higher overhead)

3.The receiver is very noisy when it's in iddle state because it is
sensing another RF sources so itīs normal. The way to "wake up" is
sending a "strong and heavy signal" like 0000111100001111 to
differentiate from the iddle state. With this example we get a square wave
with 1.66ms LOW followed by 1.66ms HIGH. This is critical for proper
operation ot the receiver because it is AC coupled.

Quote:

another problem I found is that between each byte (not bit) there is period of low signal for the program, I made, which I think it should not be there, why?

Don't understand, sorry. Confused

Humberto Very Happy
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 12:49 pm     Reply with quote

young wrote:

Quote:

saw some posts that use interrupt to decode the received data, here is my proposal, is this right?

1. define the external interrupt Pin as Receive Pin

#define M_Rx_Pin PIN_B0 //(16f819) at edge H_L

2. when a exteral interrupt occured, the external interrupt routine (Ext_int)will setup a timer, for example timer0(Timer_int);

3. Timer0 will count the time, if time reach a certain value; it will invoke (Timer_int);

4. in the routine(Timer_int); will disable external interrupt routine,read input data from the M_Rx_Pin for every certain time period, and at same time setup external interrupt as low to high, at setup timer, if timer reach a certain period, means a stops bit being encounted, end the reading data.

is this doable?


YES, thatīs the way Idea

Tell us your result. Very Happy

Humberto
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 12:55 pm     Reply with quote

thank you Humberto:

When you come back, I am alive again! The way I talk, and the way you explain to me, keep me thinking for new approaches!

I am writing program using external interrupt + timer to decode the data right now, I changed a little bit of my proposal in the last post.

Quote:

1. define the external interrupt Pin as Receive Pin

#define M_Rx_Pin PIN_B0 //(16f819) at edge H_L

2. when a exteral interrupt occured, the external interrupt routine (Ext_int)will setup a timer, for example timer0(Timer_int);

3. Timer0 will count the time, if time reach a certain value; it will invoke (Timer_int);

4. in the routine(Timer_int); will disable external interrupt routine,read input data from the M_Rx_Pin for every certain time period, and at same time setup external interrupt as low to high, at setup timer, if timer reach a certain period, means a stops bit being encounted, end the reading data.


It is a little data check, if I am receiving data, data bit number is a integer num, and num divide by 8 is one byte, when stop bit occured, I will remove any data that is over the exactly 8 times of data:

hard to explain: I will do this,
if I received 20 bit of data, and stop bit occured, 20/8 the left over is 4, so I will just keep the first 16 bit of data and remove the rest 4 bit of data.

please evaluate my approach.
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 2:27 pm     Reply with quote

This is an excellent thread.

I just want to add the following link with code for manchester comms between PICs. The author uses another 'cool' trick for the coding/decoding. Anyway, hope it helps.
http://www.ottawarobotics.org/articles/rf/rf.html

Also, I have been able to do burst-communications by applying suggestions previously posted by Humberto and Ttelmah, something like this:
Code:
#define junk 0xAA
#define STX 0xF3
#define ETX 0xCF

...

void xmt()
{
   output_high(RFEN);      // enable rfPIC & stabilize PLL
   delay_ms(5);
   output_high(DATA);      // warmup receiver
   delay_ms(15);
   for (n=0;n<5;n++)
   {
      putc( junk );      // unbias data-slicer
   }
   for ( n = 0; n < (bufferSize - 1) ; n++ )
   {
      printf( "%c%u%c",STX,n,ETX );   // send byte
   }
   delay_us(50);
   output_low(RFEN);      // disable rfPIC
}


The use of STX and ETX to properly identify your good character works great because (if properly selected), the receiver has some inmunity to receiving bad characters. When it does however, they are lost (i.e. if the character does not follow the STX-CHR-ETX it is thrown out). They do not have to, you could implement error correction but that's more overhead on the link. Choosing STX and ETX is also very important as you have to choose something that provides some inmunity to noise (a series of "1010..." are bad because noise is very correlated to this), better links would have more than one STX and ETX (more like, STX1-STX2-STX3 etc) which provides even better inmunity.

Understand that "plain" manchester encoding/decoding only improves the probabilty of receiving the characters, but does nothing against receiving noise. It is error detection (which Ttelmah's example had, and the link above does too), error correction, and some communication protocol helps you on this.

I am currently working on implementing the code provided on the above link over RS232 comms (having a little trouble on the receive side).

just my two cents...
young



Joined: 24 Jun 2004
Posts: 285

View user's profile Send private message

PostPosted: Mon Feb 28, 2005 12:08 pm     Reply with quote

Hi Humberto:

Here is the program for encoding and decoding, so far I saw at the receiver that the data I transfer from the TWS is received by RWS correctly, However, I am having a little bit of problem decoding it.


encoding

Code:

/*********************************************************/
/*                                                       */
/*      Send Manchester data bit by bit                  */
/*                                                       */
/*********************************************************/


#if defined(__PCM__)
#include <16F819.h>
#include <stdio.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOPROTECT
//#device ADC=10
#use delay(clock=10000000)
#use rs232(baud=9600, parity=N, xmit=PIN_A0)

#define M_Tx_Pin PIN_A1

void SEND_DATA(BYTE txbyte)
{


    int i,j,b;

    b = txbyte;
//    putc(txbyte);
 
   for(i=0;i<8;i++)
    {
      if(bit_test(b,i))
      { output_high(M_Tx_Pin);
        delay_us(417);
        output_low(M_Tx_Pin);
        delay_us(417);
      }
      else
    {  output_low(M_Tx_Pin);
        delay_us(417);
        output_high(M_Tx_Pin);
        delay_us(417);
      }
    }
}
//

void remoteprintf(char *c)
{
   int8 i,length;
   length=strlen(c);
   //premable data to init TWS
   for(i=0;i<4;i++)
   {
    output_low(M_Tx_Pin);
    delay_us(417);
   }

 //  printf("length: %u\r\n",length);
   // send data
   for (i=0; i<length;i++)
      SEND_DATA(c[i]);


   //send stop

   for(i=0;i<4;i++)
   {
    output_high(M_Tx_Pin);
    delay_us(417);
   }

}


void main()
{
  char data[]="bc";
   setup_port_a(ADC_OFF);
   set_tris_a(0xf3);
   setup_CCP1(CCP_OFF);
   setup_timer_1(T1_DISABLED);

   enable_interrupts(global);

   while(1)
   {
   remoteprintf(data);
   delay_ms(1);
  }
}

decoding
Code:

/*********************************************************/
/*                                                       */
/*      Decoding Manchester data bit by bit              */
/*                                                       */
/*********************************************************/

#if defined(__PCM__)
#include <16F819.h>
#Device *=16
#include <stdio.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT
//#device ADC=10
#use delay(clock=10000000)
#use rs232(baud=9600, parity=N, xmit=PIN_A0, rcv=PIN_A1,ERRORS)

#define M_Rx_Pin PIN_B0

int16 data_ori[40];
char data_decod[40];
char status;  //data 1 start 0 stop
int8 bit_num,data_num,i,j,k;
int1 tem;


#int_ext //allow ext interrupt
int_isr() //Interrupt Service Routine
{
if(status==1)
  set_timer0(0); //Set Timer 0 to zero equal to 256*6.4=1638.4us

if(status==0);
   set_timer1(0);

 }

#INT_TIMER0
timer0_isr()
{
 EXT_INT_EDGE(L_TO_H);
 disABLE_INTERRUPTS(INT_TIMER0);
 ENABLE_INTERRUPTS(INT_TIMER1);
 enable_interrupts(int_ext); //Allow ext Interrupt on Rb0
 enable_interrupts(global); //Allow Global Interrupt
 status=0;
}
#INT_TIMER1
timer1_isr()
{
 EXT_INT_EDGE(H_TO_L);
 disABLE_INTERRUPTS(INT_TIMER1);
 ENABLE_INTERRUPTS(INT_TIMER0);
 enable_interrupts(int_ext); //Allow ext Interrupt on Rb0
 enable_interrupts(global); //Allow Global Interrupt
 status=1;
}

void main()
{
  char data1[20],datar,ddl,ddh,datadecode;
  char firstbit;

  status=1;  //data pre and post part

   SET_TRIS_b(0xff);
   set_Tris_a(0x00);
   SETUP_CCP1(CCP_OFF);
   SETUP_ADC_PORTS(NO_ANALOGS);
   SET_TIMER0(RTCC_DIV_16|RTCC_Internal);
   setup_timer_1(T1_DIV_BY_8 |T1_INTERNAL ); //Timer 1 Setup
   ext_int_edge(H_TO_L); //Wait for falling edge--> then jump to Interrupt Service Routine
   enable_interrupts(int_ext); //Allow ext Interrupt on Rb0
   ENABLE_INTERRUPTS(INT_TIMER0);
   ENABLE_INTERRUPTS(INT_TIMER1);
   enable_interrupts(global); //Allow Global Interrupt

   status=0;  //lsb part
   bit_num=0;
   firstbit=0;
   while(1)
   {
    //start bit detected after H_TO_L edge and certain time period
    if(status==0)
    {
    //Start reading bit by bit for every certain time period
    if(firstbit==1)
      {delay_us(179); firstbit=0;}  //take the data at the input wave center of the first bit
      //179+29=208=417/2  1638us timer0 interrupt, delay start bit =4*417=1667
      //1667-1638=29
    else
      delay_us(417);

    tem=input(PIN_B0);
    data_num=bit_num/16;  //
    j=bit_num%16;
    if(tem==1)
      { bit_set(data_ori[data_num],j); }
    else
      { bit_clear(data_ori[data_num],j);}

    bit_num++;

    }
    //stop bit detected after L_TO_H detected
    if(status==1)
    {
    firstbit=1;//process the data (decoding the data)
    for(i=0;i<data_num;i++)
      {

      for(k=0;k<8;k++)
         {
         if((bit_test(data_ori[i],2*k)==1) && ((bit_test(data_ori[i],2*k+1)==0)))
            bit_set(data_decod[i],k);
         else if((bit_test(data_ori[i],2*k)==0) && ((bit_test(data_ori[i],2*k+1)==1)))
            bit_clear(data_decod[i],k);
         }
      }

      data_decod[data_num+1]='\0';
 //     printf("Data_num: %u\r\n",data_num);
      puts(data_decod);
   
    }
   }
}



I am sending data as these format:
starting bit (4)
1 delay_us(417) 1 delay_us(417) 1 delay_us(417) 1 delay_us(417)
data
bit by bit with a 417us delay;
stopping bit
0 delay_us(417) 0 delay_us(417) 0 delay_us(417) 0delay_us(417)

receiving method:

1. setup a external interrupt RB0 (PIN_RB0):
in this routine set timer0 or timer1 for start or stop detection.
2. in timer0 routine:
change external interrrupt int as L_T_H to detecting stop bit, and set status as 0, which means after detecting the external interrupt a certain period (4 start bit delay time), which means the program is facing the data right now
3. in timer1 rountine
change external interrupt as H_T_L to detect start bit,and set status as 1, which means after detecting the external interrupt a certain period (4 stop bit delay time), which means the program is facing the stop bit right now

4. in main rountin:
keep checking start status,if status=0, and it there is no data receive yet, set first bit staus and start a delay which is eaqual to the middle of rhe first bit, else the first bit have been taken then take another 417 us delay for the continuous data.
if status=1 stop bit, then in this routine, decode every bit back to original bit sent from the TWS.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Feb 28, 2005 3:14 pm     Reply with quote

Hi young,

Well, I have been reading your code and ufff!! Shocked itīs not easy to
understand and I donīt have all the time for this, at least letīs assume
that itīs complex and twisted.
Remember what I said you in the beggining of this thread, that itīs not
the only or the best way to do this, but such method was very easy
and self demostrative just to explain the idea.


Now that you have a better understanding of what and how to do it, we
can go to the site that you mention:
http://www.quickbuilder.co.uk/qb/articles/
where there are a less complex encoding/decoding technique that I
suggest we can follow, to save our sanity. Confused

Let me know if you are agree.

Humberto
Guest








PostPosted: Mon Feb 28, 2005 3:26 pm     Reply with quote

Thank you:

My purpose is to make the system work,, no matter what the code could be.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Feb 28, 2005 4:17 pm     Reply with quote

I didnīt test it but it seems easy to impliment, you can use the UART and
all the advantages of the rs232 built in functions like kbhit() and getc().

Humberto
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group