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

RF Serial Communication Problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
_panzerschreck_



Joined: 06 Feb 2012
Posts: 6

View user's profile Send private message

RF Serial Communication Problems
PostPosted: Mon Feb 06, 2012 7:53 am     Reply with quote

Hi everyone

I am trying to make a communication between two pics (16f877a) over 433mhz rf modules and uart. One pic takes data from computer (I am using pickit's UART tool) processes it and transmits it to the other pic.

Baud rate is set to 1200 and errors are enabled in #use rs232 code part.

When I send the data over a cable (from one pic's tx to others rx) it works perfectly. However when it comes to the rf wireless modules, I have to send a char approximately 10 times in uart tool software to receive the data in the other side. I am using the preamble data and 2 byte pass in order not to be affected by the noise.

There are some possibilities that come into my mind but I am not sure, so I need help

1.) Rf data should be DC balanced. So either using manchester coding or sending bytes including equal number of 0's and 1's should work. Since I don't know how to implement manchester coding, I preferred the second one.

2.) Since the RX buffer is only 1 byte, I might be missing some data in the receiver side. But I do not know how to overcome this.

3.) There are too many processes in the interrupt routine so I may be missing some data in the receiver side.

4.) Other problems which I could not figure out


CODE:
TRANSMITTER SIDE:
Code:
#include "C:\Users\Desktop\PC RS232\main.h"

char temp;
int i;

#int_rda
void rx_interrupt ()
{
   disable_interrupts(int_rda);

   temp=getc();          //GET THE DATA AND STORE IT INTO TEMP VARIABLE
   
   switch (temp)           //CONVERSION PROCESS FOR THE DC BALANCED ISSUE I HAVE MENTIONED ABOVE
   {
      case 'w':
      temp='f';
      break;
      case 'a':
      temp='e';
      break;
      case 's':
      temp='j';
      break;     
      case 'd':
      temp='i';
      break;   
      case 'q':
      temp='S';
      break;
      case 'e':
      temp='V';
      break;
      case 't':
      temp='Z';
      break;
      case 'g':
      temp='Y';
      break;
      case 'b':
      temp='5';
      break;
      case 'n':
      temp='+';
      break;
      case 'h':
      temp='3';
      break;
      case 'l':
      temp='6';
      break;
   }
   
   putc(0x55);          //UUUUU  01010101 PREAMBLE DATA
   putc(0x55);
   putc(0x55);
   putc(0x55);
   putc(0x55);
   
   
   putc('K');          //PASSWORD 1st BYTE
   putc('M');         //PASSWORD 2nd BYTE
   putc(temp);     //1 BYTE DATA TO BE SENT
   }


void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   enable_interrupts(GLOBAL);
   enable_interrupts(int_rda);

   // TODO: USER CODE!!
   
   delay_ms(1000);
   while(1)                                                   //INFINITE LOOP
   {
      enable_interrupts(int_rda);
   }

   
}







RECEIVER SIDE:
Code:
#include "C:\Users\Desktop\PC RS232\ALICI\2\main.h"

#use fast_io(b)
#define use_portb_lcd TRUE
#include <lcd.c>

//DEFINITIONS
#define trig   pin_D0
#define echo   pin_D1
#define pwm1   pin_C1
#define pwm2   pin_C2
#define mot11  pin_A0
#define mot12  pin_A1
#define mot21  pin_A2
#define mot22  pin_A3

//FUNCTIONS
void sol_ileri_20();              //LEFT MOTOR FWD 20% PWM
void sol_geri_20();               //LEFT MOTOR REV 20% PWM
void sag_ileri_20();              //RIGHT MOTOR FWD 20% PWM
void sag_geri_20();              //RIGHT MOTOR REV 20% PWM
void sol_bos();
void sag_bos();
void ileri ();
void geri ();
int sonar ();

//VARIABLES
int okumamodu =0;
char temp;
int temp1=0;
int duty=50;
int16 distance, time;


#int_rda
void rx_interrupt ()
{
   
   disable_interrupts(int_rda);
   
   
   if(okumamodu==0)               //COUNTING THE VARIABLE OKUMAMODU AND IF IT REACHES 3 I READ THE ACTUAL DATA
   { 
      temp=getc();
      if(temp=='K')                               //PASS 1.BYTE CONTROL
      {okumamodu++;
      }
      else           okumamodu=0;
     
   }
   if(okumamodu==1)
   {
      temp=getc();
      if(temp=='M')                              //PASS 2.BYTE CONTROL
      {okumamodu++;
      }
      else           okumamodu=0;
     
   }
   
   
   if(okumamodu==2)                      //START READING DATA AND MAKE ASSIGNMENTS TO USE IN FUNCTIONS
   {
      temp=getc();
         if(temp=='f')           //Corresponding char for w
         {
            temp1=119;           //ascii for w
            okumamodu=0;
         }
     
         else if (temp=='j')     //Corresponding char for s
         {
            temp1=115;           //ascii for s
            okumamodu=0;
         }
     
         else if (temp=='e')      //Corresponding char for a
         {
            temp1=97;            //ascii for a
            okumamodu=0;
         }
         
         else if (temp=='i')     //Corresponding char for d
         {
            temp1=100;           //ascii for d
            okumamodu=0;
         }

         else if (temp=='5')     //Corresponding char for b
         {
            temp1=98;            //ascii for b
            okumamodu=0;
         }
         
         else if (temp=='Z')     //Corresponding char for t
         {
            temp1=116;           //ascii for t
            okumamodu=0;
         }
         
         else if (temp=='Y')     //Corresponding char for g
         {
            temp1=103;           //ascii for g
            okumamodu=0;
         }
         
         else if (temp=='S')     //Corresponding char for q
         {
            temp1=113;           //ascii for q
            okumamodu=0;
         }
         
         else if (temp=='V')     //Corresponding char for e
         {
            temp1=101;           //ascii for e
            okumamodu=0;
         }
         
         else if (temp=='3')     //Corresponding char for h
         {
            temp1=104;           //ascii for h
            okumamodu=0;
         }
         
         else if (temp=='6')     //Corresponding char for l
         {
            temp1=108;           //ascii for l
            okumamodu=0;
         }
      okumamodu=0;
   }

   if(okumamodu==80)
   okumamodu=0;
   


}



void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //USED FOR SONAR
   setup_timer_2(T2_DIV_BY_16,170,1);           //USED FOR PWM
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   set_pwm1_duty(100);
   set_pwm2_duty(100);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_b(0x00);
   lcd_init();
   duty=50;

   delay_ms(1000);
   // TODO: USER CODE!!
   
   enable_interrupts(GLOBAL);
   enable_interrupts(int_rda);
   
   while(1)
   {   
      enable_interrupts(int_rda);     
           
      switch (temp1)
         {
         case (119):                                //CALLING FUNCTIONS FOR THE temp1 VARIABLE FROM THE RX INTERRUPT
            duty=100;
            ileri();
            break;
         case (115):
            duty=100;
            geri();
            break;
         case (97):
            duty=75;
            sag_ileri_20();
            sol_geri_20();
            break;
         case (100):
            duty=75;
            sol_ileri_20();
            sag_geri_20();
            break;
         case (98):
            duty=10;
            sag_bos();
            sol_bos();
            break;
         }
         
         
       
   }
}



//FUNCTIONS
void ileri ()                         
{
   set_pwm1_duty(duty);
   set_pwm2_duty(duty);
   output_low(mot11);
   output_high(mot12);
   output_low(mot21);
   output_high(mot22);
}
void geri ()
{
   set_pwm1_duty(duty);
   set_pwm2_duty(duty);
   output_high(mot11);
   output_low(mot12);
   output_high(mot21);
   output_low(mot22);
}
void sol_ileri_20()

   set_pwm1_duty(duty);
   output_low(mot11);
   output_high(mot12);
}
void sol_geri_20()             
{   
   set_pwm1_duty(duty);
   output_high(mot11);
   output_low(mot12);
}
void sag_ileri_20()
{
   set_pwm2_duty(duty);
   output_low(mot21);
   output_high(mot22);
}
void sag_geri_20()
{
   set_pwm2_duty(duty);
   output_high(mot21);
   output_low(mot22);
}
void sol_bos()
{
   set_pwm1_duty(duty);
   output_low(mot11);
   output_low(mot12);
}
void sag_bos()
{   
   set_pwm2_duty(duty);
   output_low(mot21);
   output_low(mot22);
}






.h FILE:
Code:
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                               //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                      //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)

ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 8:59 am     Reply with quote

I have no experience with the 433MHz modules but on this forum you will find many discussions from people having troubles with them. Some modules are better quality than others, is yours an AM or FM type?
Posting the brand and type number of your modules could give you more hints & tips. Even better, provide a link to the datasheet.

A few issues:
For every character you receive from the PC you are sending 8 characters. The PIC hardware can only buffer up to three characters in the receive buffer, so make sure the PC is sending data with long intervals between the characters or you will overflow the PIC UART and loose data. At 1200 baud that is at least 8 ms between the characters.

Code:
setup_spi(SPI_SS_DISABLED);
This is an illegal configuration and a long known error in the CCS setup wizard. Should be changed to:
Code:
setup_spi(FALSE);


Code:
disable_interrupts(int_rda);
There is no need to disable the interrupts inside the interrupt handler as this has already been done by the PIC hardware. I'm glad you didn't make the error of enabling the global interrupts again inside the interrupt handler. After removing this line you can also remove the enabling inside the main loop.

Quote:
...
else if (temp=='V') //Corresponding char for e
{
temp1=101; //ascii for e
okumamodu=0;
}

else if (temp=='3') //Corresponding char for h
{
temp1=104; //ascii for h
okumamodu=0;
}

else if (temp=='6') //Corresponding char for l
{
temp1=108; //ascii for l
okumamodu=0;
}
okumamodu=0;
You definitely like to make sure okumamodu becomes zero... Razz

A few more links on the 433 MHz modules:
http://www.ccsinfo.com/forum/viewtopic.php?p=144720
http://www.ccsinfo.com/forum/viewtopic.php?p=891
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Comms problem
PostPosted: Mon Feb 06, 2012 9:21 am     Reply with quote

You've not told us which RF module you're using, or how it's connected.

I've used two different types of 433MHz devices, and was amazed at the difficulties I had with the second more modern one!

Your answer is built into the question. Write a short simple program to test your RF link alone (ignore everything else).

Repeatedly send a short message over the link, check with a 'scope that you can see what you're expecting, then proceed from there.

If you are well within the quoted receive range, with proper antennae, missing data should be a rarety.

Mike
_panzerschreck_



Joined: 06 Feb 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 9:56 am     Reply with quote

Quote:
setup_spi(FALSE);

Thanks for the spi issue, even though I am not using spi interface, I have corrected it.

Quote:
You definitely like to make sure okumamodu becomes zero...

okumamodu variable is for checking the validity of pass key and the data, after data received I changed it to default value "0", but as you stated I may have declared okumamodu=0 more than necessary

I am using this transmitter
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wireless/General/TWS-BS-3_433.92MHz_ASK_RF_Transmitter_Module_Data_Sheet.pdf

and this receiver
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wireless/General/RWS-371-6_433.92MHz_ASK_RF_Receiver_Module_Data_Sheet.pdf

They are connected to the corresponding RX and TX pins of 16F877A pic.

Quote:

Repeatedly send a short message over the link, check with a 'scope that you can see what you're expecting, then proceed from there.

I do not have an oscilloscope at home and I will not have an access to the lab in the following days, but I guess I can use UART tool of PICKIT to see what is received in the receiver side by using
Code:
putc(getc);

Would that cause any problems for testing?
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:26 am     Reply with quote

the RF modules that you are using will not work.

Unless you do your own error checking routines, with paritys and checksums and .... still it will only work partially.

the reciever itself has autogain... so it produces uncontrollable noise on its output... and your UART will think its data... and your system will think its garbage.

these modules work best with pulse position or pulse width comunications... (like the one used in wireless doorbels and IR remotes)... not standard serial.

those modules are not a "virtual wire"...

try the Bluesmirf from sparkfun.... that is literaly plug and play... flawless. or an RFM22 module....

ive used succefully your modules to interface with other wirelss mass produced devices and the Bluesmirf for personal proyects...
_________________
CCS PCM 5.078 & CCS PCH 5.093
_panzerschreck_



Joined: 06 Feb 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 10:44 am     Reply with quote

I guess you are right, modules are not good for the applications that is intolerable for data loss. Is there any way to work with these (i.e. intensive coding etc) or should I buy a new pair? Or how can I understand which module is good for this kind of applications in case for future choices.

I have tried an application to test the modules now.

On transmitter side, I have sent K, L for password bytes and numbers from 0 to 9 in an infinite loop.

Code:

putc('K');      putc('L');      putc('0');

putc('K');      putc('L');      putc('1');

putc('K');      putc('L');       putc('2');
   
putc('K');      putc('L');       putc('3');

putc('K');      putc('L');       putc('4');
       
putc('K');      putc('L');       putc('5');

putc('K');      putc('L');       putc('6');

putc('K');      putc('L');       putc('7');

putc('K');      putc('L');       putc('8');

putc('K');      putc('L');       putc('9');
   


On receiver side I have controlled K and L bytes and if they are satisfied I send the data to the serial port to read.

Code:

int okumamodu=0;
int temp;

#int_rda
void rx_interrupt ()
{
   if(okumamodu==0)
   { 
      temp=getc();
      if(temp=='K') 
      {okumamodu++;
      }
      else           okumamodu=0;
     
   }
   if(okumamodu==1)
   {
      temp=getc();
      if(temp=='L') 
      {okumamodu++;
      }
      else           okumamodu=0;
     
   }


      if(okumamodu==2)
      {
      putc(getch());
      okumamodu=0;
      }
   
}




UNFORTUNATELY

The receiver misses some data and it explains why I should have to repeat sending the same data repeatedly which is undesired. This is the log file that is received from serial port which is supposed to be
Code:
0123456789
and it should continue forever

However what I got is: (with a lot of missing data)

Code:
1357913579135791357913579
135791357913579135791357913579
135791357913579135791357913579
135791357913579135791357913579
135791357913579135791357913579
135791357913579135791357901234
567890123456802468012357913579
135791356789012345678901234567
913579123456789012345679123456
791234567912345679123456791234
567912345680123456791235791357
913579135791357912345679123456
791357913579135791357913567912
345680234567913579135791357912
345680123579135791356789012345
680246890123456789123456802468
023456789012345679135791357912
345679135791234567913579123456
802356801234567913579135791234
567913579135791357913579135791
234567890123456791357912345679
135791357913579123456791357913
567890123456791357912345678901
234568024689012345678901246802
456789012345679135791234568012
356802468012345680123456791234
568012345680123456791234568012
345678901234567890123456789012
345678901234567912345679123456
791234567890123456789012345678
901234567801235791345678901234
567802468023456789012345680246
801234567802468012356802356801
235791356789012345678901234568
023568024680235680246801234568
024680123456791357913579135791
234567913579135791357913579135
791356791234567913579135790123
456791357913579123579135791357
913579123456791357912345679135
791234567912345679123457913579
123456791235791357913456791357
913579135791357913579135791357
913579135791357913579135791357
913579135791357913579135791357
913579135791357913579135791357
913579135791357913579135791357
912345679135791357913579135791
357913579135791357913579135791
357913579135791357913579135791
357913579135791357913579135791
35791357
_panzerschreck_



Joined: 06 Feb 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 11:05 am     Reply with quote

CORRECTION:

However when I send preamble data first (putc('U')) five times before sending any data, it works flawlessly. I couldn't figure out what is the problem. On robot, it causes a large delay, but here I can see the characters are sent correctly. (But I encounter some missing data also, not correct all the time)


Quote:
01234567890123456789
01234567890123456789
01234567890123456789
012345673456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
01234567890123456789
012345678901




HOWEVER

when I do not put chars directly, but I send putc(getc()) which is received from the computer, I encounter the delay issue and some unidentified characters again.

What is wrong with these modules or program?
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 12:13 pm     Reply with quote

Sending the 'U' character before the actual data a few times actually helps you because it gives the receiver a chance to properly adjust its gain before receiving data.

Its better if you send char 0XAA before as it has equal amount of hi/lo transitions.

These modules tend to like having the same number of transitions.


First test your communications using a wired connection, then move on to RF.
_________________
CCS PCM 5.078 & CCS PCH 5.093
_panzerschreck_



Joined: 06 Feb 2012
Posts: 6

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 1:32 pm     Reply with quote

Gabriel wrote:
Sending the 'U' character before the actual data a few times actually helps you because it gives the receiver a chance to properly adjust its gain before receiving data.

Its better if you send char 0XAA before as it has equal amount of hi/lo transitions.

These modules tend to like having the same number of transitions.


First test your communications using a wired connection, then move on to RF.


As I mentioned before, I have tested it with cable communication and it works well without any loss. I just get some weird characters when I use rf modules even if I use preamble data and password characters.

By the way, do I need to put any delays for transmitter side when it is set to 1200 baud rate?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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