PIC16f628 radio link

Thread Starter

cykrus

Joined Oct 1, 2012
4
Hello all,

I am very new to the micro-controller world so bare with me.

I want to make a remote control to be able to send data between t PIC's (16f628). I know that there are already products out there (i have tested h12e/d rd600 d/e and they work great). My scope is to learn and play with PIC and not to use already made products :)

Before this project i did the "flash led" type of tutorials to learn a little bit about PIC's. I have a picckit3 programmer and I'm using the PIC C compiler.

Environment setup :
I have 2 16f628 pic's and a set of 434 Mhz RX/TX. I also have a max 232
connected to my serial port and receiver PIC in order to be able to debug data. At the hardware level have no problems setting it up.

Software setup:

The idea is that I want to be able to send a data package (comming from input pins) from PIC1(connected to the TX 434) to PIC2(connected to rx 434).

An here comes the code I have already wrote. Again ... this is my first real program so bare with me :)

DECODER

Rich (BB code):
#include <16F628.h>
#fuses INTRC_IO, NOLVP, NOWDT, PUT, BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=19200, xmit=pin_B2, rcv=pin_B1)


void display_binary(int c){
int i;
   i = 8;
   do
     {
       if( c & 0x01 )
         { putc('1'); }
       else
         { putc('0'); }

       c >>= 1;  i--;
     } while(i);
} 


int sync(int a){
   int found;
   int string;
   int bit;
   
   int original;
   
   original = a;
   
   do{
      a = original;
      found = 0; // found the string
      string = 0x00;
         
      do{
           if( input(PIN_A0) ){
               bit = 0x01;
           }
           else{
               bit = 0x00;
           }
           string = string | bit;
           string <<= 1;                    
           
           if( ((a & 0x01) ^ bit ) == 0 ){ // right bit == input
               a >>= 1; // shift 1 position right
           }
           else{
              return 0; // error
           }
           
           if( a == 0x00){
                found = 1;
           }
           
           delay_us(500); // wait until next bit
           
      }while( found == 0 );   

  }while( found == 0 );

  return 1; 
}

int getdata(){
   
   int string = 0x00;
   int i;
   
   for(i=0;i<8;i++){
      string <<= 1;
      if( input(PIN_A0) ){
         string |= 0x01;
      }
      else{
         string |= 0x00;
      }   
      delay_us(500);
   }
   
   return string;
}


void main(void) {

   int prev, k, i;
   unsigned int data;

   while(1) {
      
      k=0; // until i get 3 time the same result
      do{
      
         i=0;
         do{
            if( sync(0xAB) == 1 ){
               i++;
               delay_us(500);
            }
            else{
               i = 0;
            }
         }while(i<3);
         
         data = getdata();
         
         if( k > 0 && data != prev) k=1; // reset
         else k++; // one more good result
         
         prev = data; // previous result used in the next loop
         
      }
      while(k<3);
      
      if( data == -1 ) output_high(PIN_A2);
      if( data == 63 ) output_high(PIN_A1);
      
      printf("Found %d = ", data);
      display_binary(data);
      printf("\r\n");
      
      delay_ms(250);
      output_low(PIN_A2);
      output_low(PIN_A1);
   }

}
ENCODER

Rich (BB code):
#include <16F628.h>
#fuses INTRC_IO, NOLVP, NOWDT, PUT, BROWNOUT
#use delay(clock=4000000)

void send1(){
   output_high(PIN_A0);
   delay_us(500);
   output_low(PIN_A0);
}
void send0(){
   output_low(PIN_A0);
   delay_us(500);
   output_high(PIN_A0);
}

void sendbyte(int x){
   int i=8;
   do{
      if(x & 0x01){
         send1();
      }
      else{
         send0();
      }
      x >>= 1;
      i--;
   }while(i);
}


main() {

   while(true) {
      if(input( PIN_B0) ){
         // sync
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xFF);
         delay_us(500);

      }
      else if(input( PIN_B1) ){
         // sync
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xAB);
         delay_us(500);
         sendbyte(0xFC);
         delay_us(500);
     }
   }
}
The idea is the encoder is sending 3 bytes (AB) as a sync (in order to align it with the RX) and then it send a byte of data depending on which pin B0 or B1 is high. The decoder searched for the 3 sync packages and then reads the byte (I'm reading it until i get 3 times the same value .. as i have experienced some errors due to radio noise i guess). Everything work so far but I'm sure it's not the perfect way to do it.

My questions are :

1. I have set a delay of 500us between bits and bytes as well. Is this correct ? What should be an optimal value ?
2. I coded 2 function for sending 1 or 0 bits. Is there another way to send directly a full byte to a pic PIN ?
2a. I have seen that in manchester it says that 1 is 0to1 transition and 1 is 1to0 ... does this mean that for sending a 1 I should do the following code ?
Rich (BB code):
output high;
delay 250us;
output_low;
delay 250us
How do i read this data (from port) on the other end ?


3. I have studied for 1 week a lot about the manchester encoding, i have understood how it works but i dont know how to apply it to hardware. Meaning how to I put the bits on the PORTS and how do i read them ? What is the delay between bits ? I searched a whole week but did not find any c sample of this ... only the manchester encoding process.

4. Is the way that i'm reading data from 434RX correct ? I have setup on both tx and rx same timing (delays between bits) and this is the way i "sync" .. is there another way do to this ?

Please feel free to correct/adjust my code and tell me what do I do wrong.

I want to learn and experimenting is for me the best way to do this.

Thanks,
Vlad
 

Thread Starter

cykrus

Joined Oct 1, 2012
4
Another question just came into my mind. The way that i'm syncronising the encoder/decoder is my seting the same delay between bits. Now my question is this ... how much time does it take to execute operations between sending bits ? For example is the encoder has a code like

Rich (BB code):
output high
delay 10us
output low
delay 10us
and the decoder has the code


Rich (BB code):
read input
delay 10us
<=== other 10 instructions come here
read input
delay 10us
How much does it take for the "10 instructions" to execute ... can that cause a delay and with the 10us added on top the second "input" would no longer be aligned with the encoder's timing ?

How to solve this issue ... I suppose there is a way with the clock ? ... like in the so if we say "we'll meet there in 10 minutes" ... it is not so accurate as saying "we'll meet there at 2:50 PM" .. right ?
 

Thread Starter

cykrus

Joined Oct 1, 2012
4
OOps ... i did some more reading and it looks like my code reinvented the wheel :)))) ... sorry for that ... i just discovered ... "USART" ...

It looks like my code for sending/receiving bits is a "stoneage" version of USART ...
 

Thread Starter

cykrus

Joined Oct 1, 2012
4
So .. after another day spent on forums i got the idea. I am using the UART and I have learner about all the registeres and bits for the rx buffer, error, etc etc. Great stuff ...

So I managed to implement a fully working link with a 4 bit address and 8 bit (can be extended to 10 - two pins are still left as rx/tx for the wireless link ) data between 2 pic16f628.

Next question just for fun ... can i save one more pin ? Is there a way when init the UART to only assign a pin (the tx) and rx to leave it undefined OR assigning it to some kind of NULL ?
 
Top