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 CCS Technical Support

Communcation between PIC's using wireless RS232
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
homfray



Joined: 19 Nov 2003
Posts: 45
Location: Oxford

View user's profile Send private message Visit poster's website

Communcation between PIC's using wireless RS232
PostPosted: Wed Aug 03, 2005 9:27 am     Reply with quote

Hi there, I have searched the forum and although there have been lots of similar questions no one has actually ever posted the answer so I will atempt to make sure this thread is seen to its conclusion.

I have two PICs and they communicate to each other via wireless RS232 (Easy Radio ER400TRS). The talker is just sending a letter and a carriage return (although I would like to send 2 letters in the future). The Listner waits for kbhit() does an fgets and then prints it out. Unfortunately the output comes out like this

Rcv_String = └

instead of

Rcv_String = Z

It must be sort of working because the fgets receives the carriage return and obviously must recognise it as it goes to the next line

any help would be appreciated

TALKER CODE
Code:
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000                 // I'm using a 40 MHz crystal
#include <STDLIB.H>
//-------------------------------------------------------------------------------------
// DEFINES
#define WireTX PIN_C7
#define WireRX PIN_C6
#define ConsTX PIN_G1
#define ConsRX PIN_G2
//-------------------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#use delay(clock = Fosc)

#fuses EC_IO      // EC Oscillator with RA6 configured as DIO
#fuses NOOSCSEN   // Oscillator System Clock Switch Disabled
#fuses NODEBUG   // No Background Debugger
#fuses NOLVP      // Low Voltage ICSP Disabled
#fuses NOPROTECT   // No Code Protect
#fuses NOWDT      // No onboard watchdog
#fuses PUT         // Power Up Timer Enabled
#fuses BROWNOUT   // Brown Out Reset enabled

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console)             //Setup RS232

char Rcv_String[2] ;

void main()
{
   while(1)
   {
      fprintf(Wireless,"Z\r");
      delay_ms(5000);
   }   
}


LISTNER CODE
Code:
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000                 // I'm using a 40 MHz crystal
#include <STDLIB.H>
//-------------------------------------------------------------------------------------
// DEFINES
#define WireTX PIN_C7
#define WireRX PIN_C6
#define ConsTX PIN_G1
#define ConsRX PIN_G2
//-------------------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#use delay(clock = Fosc)

#fuses EC_IO      // EC Oscillator with RA6 configured as DIO
#fuses NOOSCSEN   // Oscillator System Clock Switch Disabled
#fuses NODEBUG   // No Background Debugger
#fuses NOLVP      // Low Voltage ICSP Disabled
#fuses NOPROTECT   // No Code Protect
#fuses NOWDT      // No onboard watchdog
#fuses PUT         // Power Up Timer Enabled
#fuses BROWNOUT   // Brown Out Reset enabled

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console)             //Setup RS232
char Rcv_String[3] ;  //NOT SURE HOW MANY CHARACTERS TO LOOK FOR

void main()
{   
   fprintf(Console,"Lets Begin\n\r");
   while(1)
   {
      if(kbhit(Wireless))
      {
         fprintf(Console,"inside loop\n\r");
         fgets(Rcv_String,Wireless);
         fprintf(Console,"Rcv_String = %s\n\r",Rcv_String);   
      }   
   }
}

_________________
Nice!!!


Last edited by homfray on Fri Aug 05, 2005 6:02 am; edited 1 time in total
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Wed Aug 03, 2005 9:53 am     Reply with quote

I've never used those particular radio modules, but I have done lots of RF comms between pics using their built-in USART.

The first thing you should consider is a warmup/lockon time. When the transmitter is not transmitting, the receiver will try to lock onto the strongest RF signal in its frequency band and demodulate it. Even if it's noise, it will still try to demod the noise. This means the receiving USART is getting a constant stream of digital "hash" noise, which the receiving USART will try to dig through for "valid" data.

You need to do things like this:
1. Transmitter power up.
2. Send a preamble - just a set of "disposable" characters. Also known as a LAM (look at me) signal. The purpose of the preamble is to allow the receiver's USART to lock on to this valid data, in other words, be able to distinguish valid start & stop bits, and sync the data clock.
3. Send an ID - something unique that only your product "knows" or uses to avoid interference with other RF devices.
4. Send the data. You may want to include an error check such as a CRC or, a quick & dirty easy way out: send the data, then send the inverse of the data (i.e. data 0xC4, inverse 0x3B).
5. Turn off the transmitter.

The complete sequence would be: Power up transmitter, wait x ms for the transmitter output to stabilize, then send the LAM (I read somewhere on this board that sending hex BABEFACE works well, and it really does.) Now send your ID code, perhaps "HITHERE" (in reality, only 3 characters are really needed in the ID code), then your data, then power down the transmitter.

On the receiver side, you'd be better off going with an interrupt driven receive. Look here for a recent example discussing this: http://www.ccsinfo.com/forum/viewtopic.php?t=23870

Just remember that on the receive side, you DON'T look for the LAM signal, only the unique ID of the transmitter. Use a state machine to "unlock" the receiver as the ID is recognized, then accept the next character(s) after the ID as valid data.

Don't hesitate to ask more questions if this doesn't make sense.
Guest








PostPosted: Thu Aug 04, 2005 2:13 am     Reply with quote

Thanks for the reply newguy!!

Look I feel like a bit of a thicky but I don't quite see what your saying, is there some example code for tx and rx PICS as I am unsure how exactly the LAM works in the Tx code and how the interupt works in the RX code (the example.

In the long run I will have one Tx PICS and many Rx PICS all the Rx PICS will hear what the Tx is transmitting but included in the transmission will be an unique identifier for each Rx PIC

Thaks for your help newguy!!
homfray



Joined: 19 Nov 2003
Posts: 45
Location: Oxford

View user's profile Send private message Visit poster's website

PostPosted: Thu Aug 04, 2005 5:04 am     Reply with quote

So I have worked on my code and I have limited sucess using the code below I now get some of the data (Tx sends 'Dave Rocks') and some garbage. Included is a capture of some of the output


> COM Port : COM5
> Baud Rate : 9600
> Data Bits : 8
> Parity : None
> Stop Bits : 1
> Hardware Flow Control : None
> Software Flow Control : None

Connected to COM5...

working4: rx_buffer[rx_wr_index]= €[
4: rx_buffer[rx_wr_index]= T¢
4: rx_buffer[rx_wr_index]=
4: rx_buffer[rx_wr_index]=
4: rx_buffer[rx_wr_index]= ÿ
4: rx_buffer[rx_wr_index]=
ave Rockser[rx_wr_index]= Dave Rocks
4: rx_buffer[rx_wr_index]=
4: rx_buffer[rx_wr_index]= €Á[
4: rx_buffer[rx_wr_index]= ’!!‰# @”À
4: rx_buffer[rx_wr_index]=
4: rx_buffer[rx_wr_index]=
@ ˆ`kser[rx_wr_index]=
4: rx_buffer[rx_wr_index]=
4: rx_buffer[rx_wr_index]=
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= e Rocks
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= e Rocks
: rx_buffer[rx_wr_index]= Dave ˆ`
ave ˆ`ffer[rx_wr_index]= cks
: rx_buffer[rx_wr_index]= Roc ˆ`
ave Roc ˆ`[rx_wr_index]= cks
: rx_buffer[rx_wr_index]= Roc ˆ`
ave Roc ˆ`[rx_wr_index]= cks
: rx_buffer[rx_wr_index]= Roc ˆ`
ave Roc ˆ`[rx_wr_index]= cks



Connection closed...


As you can see it is obviously picking something up.

Again any comments would be appreciated as I am not quite sure what newguy's clever code does completely

RECEIVE CODE
Code:
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000 
#define WireTX PIN_C6
#define WireRX PIN_C7
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console)             //Setup RS232

#define RX_BUFFER_SIZE 80
#define TX_BUFFER_SIZE 80

int8 rx_wr_index = 0, tx_rd_index = 0, tx_wr_index = 0, tx_counter = 0, received = 0;
unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1], tx_buffer[TX_BUFFER_SIZE + 1];
int1 data_avail = FALSE;

#int_RDA
void RDA_isr(void) {
   rx_buffer[rx_wr_index] = getc();
   rx_wr_index++;
   if (rx_wr_index > RX_BUFFER_SIZE) {
      rx_wr_index = 0;
   }
   data_avail = TRUE;
}

#int_TBE
void TBE_isr(void) {
   if (tx_counter != 0) {
      putc(tx_buffer[tx_rd_index]);
      if (++tx_rd_index > TX_BUFFER_SIZE) {
         tx_rd_index = 0;
      }
      tx_counter--;
      if (tx_counter == 0) {
         disable_interrupts(INT_TBE);
      }
   }
}

void bputc(int c) {
   int restart = 0;

   while (tx_counter > (TX_BUFFER_SIZE - 1));

   if (tx_counter == 0) {
      restart = 1;
   }
   tx_buffer[tx_wr_index++] = c;
   if (tx_wr_index > TX_BUFFER_SIZE) {
      tx_wr_index = 0;
   }
   tx_counter++;
   if (restart == 1) {
      enable_interrupts(INT_TBE);
   }
}

void main() {

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_ON);
   setup_timer_0(RTCC_INTERNAL|RTCC_OFF|RTCC_8_bit);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_RDA);
   //enable_interrupts(INT_TBE);
   enable_interrupts(global);

   set_tris_e(0);
         fprintf(Console,"working");
   while (TRUE) {
      restart_wdt();
      if (data_avail) {
         data_avail = FALSE;
         received++;
         if (received == 21) {
         fprintf(Console,"1: rx_buffer[rx_wr_index]= %s\n\r",rx_buffer[rx_wr_index]);
         }
         else if (received == 41) {
            received = 0;
            fprintf(Console,"2: rx_buffer[rx_wr_index]= %s\n\r",rx_buffer[rx_wr_index]);
         }
         if (rx_wr_index == 0) {
            fprintf(Console,"3: rx_buffer[rx_wr_index]= %s\n\r",rx_buffer[rx_wr_index]);
//            bputc(rx_buffer[RX_BUFFER_SIZE]);
         }
         else {
         fprintf(Console,"4: rx_buffer[rx_wr_index]= %s\n\r",rx_buffer[rx_wr_index]);
            // echo is below
//            bputc(rx_buffer[rx_wr_index - 1]);
         }
      }
   }

}


TRANSMIT CODE
Code:

// INCLUDE FILES
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000              
//-------------------------------------------------------------------------------------
// DEFINES
#define WireTX PIN_C6
#define WireRX PIN_C7
//-------------------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#use delay(clock = Fosc)

#fuses EC_IO      // EC Oscillator with RA6 configured as DIO
#fuses NOOSCSEN   // Oscillator System Clock Switch Disabled
#fuses NODEBUG   // No Background Debugger
#fuses NOLVP      // Low Voltage ICSP Disabled
#fuses NOPROTECT   // No Code Protect
#fuses NOWDT      // No onboard watchdog
#fuses PUT         // Power Up Timer Enabled
#fuses BROWNOUT   // Brown Out Reset enabled

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
void main()
{
   while(1)
   {
      fprintf(Wireless,"Dave Rocks\r");
      delay_ms(5000);
   }   
}

_________________
Nice!!!
Humberto



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

View user's profile Send private message

PostPosted: Thu Aug 04, 2005 5:48 am     Reply with quote

homfray wrote:

Quote:

So I have worked on my code and I have limited sucess using the code below I now get
some of the data (Tx sends 'Dave Rocks') and some garbage


The problem is not related to fgetc() or any other coding errors. The real problem is the
transmiting mode used in an RF link, where each bit will not be treated in the some way
as if it were sending through a wire.

This issue had been discussed deeply in this forum a time ago, just as a reference
I address you to these links:

http://www.ccsinfo.com/forum/viewtopic.php?t=19141&highlight=manchester

http://www.ccsinfo.com/forum/viewtopic.php?t=21987&highlight=manchester

Best wishes

Humberto
Guest








PostPosted: Thu Aug 04, 2005 7:23 am     Reply with quote

Cheers Humberto

tried to add the Manchester encode/decode thingy and it has stopped givng me crap, it now gives me nothing. I suppose that is a noise improvement.

OK I am a bit of a newbie having never done anything like this before and wondered if anybody had any example code, the links you kind people are sending me are actually confusing me more than helping.

If I could just see an example of some code I could try to fathom what is going on.

What I really would like to do is the following

TX PIC: send two characters, i.e printf("XY\r")
RX PIC: listen when kbhit or #int_rda then receive those two characters on wireless rs232 stream and printf those characters to the screen using another stream


If I could just see a little code then maybe I can begin to understand whats happening, I would really appreciate any help.

thanks

dave
Humberto



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

View user's profile Send private message

PostPosted: Thu Aug 04, 2005 8:09 am     Reply with quote

Hi homfray,

Just copied and pasted -in blue- the following paragraph of my previous post to introduce you what I mean:

Lower AM transceivers requires a balanced signal. Sending unbalanced signals as ASCII chars, the demodulator (in the received side) would get biased improperly and blocked until another string of chars of oposite polarity would recover such situation.

The "clue" is that the "weight" of the equivalent '1' and '0' of your string must be equal. Sending binary ASCII signals over the RF link obviously won´t meet this requeriment.

A) Rigth way to solve this is using Manchester encoding. Not so easy for begginers.

B) A "dirt" an easy solution -if your packet is very short- is to send each ASCII chars precedded by an "balanced" char like 'U' whose binary equivalent is 0b01010101 in this fashion :
Your packet: "G021D"
Sending: "UUGU0U2U1UD"



If you want to send a short packet of bytes, (being short packet < 10) then you can use the "dirt or tricky way".
Start sending a burst of balanced char 'U' (0x55) as a preamble and to " biasing wake up" the RF receiver module.

Code:

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
void main()
{
   while(1)
   {
      fprintf(Wireless,"UUUUXUYU\rU\n");
      delay_ms(5000);
   }   
}


In colors:
fprintf(Wireless,"UUUUXUYU\rU\n");

In the receiver side, just through away the 'U's and recover the XY.

Best wishes,

Humberto
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Thu Aug 04, 2005 9:40 am     Reply with quote

Homfray,

Can't type long - the wife is bugging me to go somewhere. I didn't compile this code to see if it works - there may be some missing declarations & such, but I hope you see what I am doing. Try it, see if it works.

Transmitter code:
Code:
// INCLUDE FILES
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000               
//-------------------------------------------------------------------------------------
// DEFINES
#define WireTX PIN_C6
#define WireRX PIN_C7
//-------------------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#use delay(clock = Fosc)

#fuses EC_IO      // EC Oscillator with RA6 configured as DIO
#fuses NOOSCSEN   // Oscillator System Clock Switch Disabled
#fuses NODEBUG   // No Background Debugger
#fuses NOLVP      // Low Voltage ICSP Disabled
#fuses NOPROTECT   // No Code Protect
#fuses NOWDT      // No onboard watchdog
#fuses PUT         // Power Up Timer Enabled
#fuses BROWNOUT   // Brown Out Reset enabled

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
void main()
{
   while(1)
   {
      fprintf(Wireless, 0xba); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, 0xbe); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, 0xfa); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, 0xce); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless,"Dave Rocks\r"); // I'm going to get the RX code to look for "Dave " as the ID...
      // ...and "Rocks" as the command/data
      delay_ms(5000);
   }   
}


Receiver code:
Code:
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000 
#define WireTX PIN_C6
#define WireRX PIN_C7
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console)             //Setup RS232

#define RX_BUFFER_SIZE 80
#define TX_BUFFER_SIZE 80

int8 rx_wr_index = 0, tx_rd_index = 0, tx_wr_index = 0, tx_counter = 0, received = 0;
int8 lock_state = 0, rxd, i, valid_data_count;
unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1], tx_buffer[TX_BUFFER_SIZE + 1];
int1 data_avail = FALSE, got_id = FALSE;

#int_RDA
void RDA_isr(void) {
   rx_buffer[rx_wr_index] = getc();
   rxd = rx_buffer[rx_wr_index]; // this just makes it easier typing-wise later on
   rx_wr_index++;
   if (rx_wr_index > RX_BUFFER_SIZE) {
      rx_wr_index = 0;
   }
   
   // now look for unique ID: "Dave "
   if (rxd == 'D' && lock_state == 0) {
      lock_state++;
   }
   else if (rxd == 'a' && lock_state == 1) {
      lock_state++;
   }
   else if (rxd == 'v' && lock_state == 2) {
      lock_state++;
   }
   else if (rxd == 'e' && lock_state == 3) {
      lock_state++;
   }
   else if (rxd == ' ' && lock_state == 4) { // got the entire string "Dave ", in that order
      lock_state = 0; // reset our "combination lock"
      got_id = TRUE;
      valid_data_count = 0xff; // get ready to count the number of data bytes - we know we have to expect 5 (Rocks)
      // also going to reset the buffer write index back to 0, so that I know where my valid data will be
      rx_wr_index = 0;
   }
   else { // we didn't receive "Dave ", so reset the lock back to the beginning
      lock_state = 0;
   }
   
   if (got_id && ++valid_data_count == 5) {
      data_avail = TRUE;
      got_id = FALSE;
   }
}

#int_TBE
void TBE_isr(void) {
   if (tx_counter != 0) {
      putc(tx_buffer[tx_rd_index]);
      if (++tx_rd_index > TX_BUFFER_SIZE) {
         tx_rd_index = 0;
      }
      tx_counter--;
      if (tx_counter == 0) {
         disable_interrupts(INT_TBE);
      }
   }
}

void bputc(int c) {
   int restart = 0;

   while (tx_counter > (TX_BUFFER_SIZE - 1));

   if (tx_counter == 0) {
      restart = 1;
   }
   tx_buffer[tx_wr_index++] = c;
   if (tx_wr_index > TX_BUFFER_SIZE) {
      tx_wr_index = 0;
   }
   tx_counter++;
   if (restart == 1) {
      enable_interrupts(INT_TBE);
   }
}

void main() {

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_ON);
   setup_timer_0(RTCC_INTERNAL|RTCC_OFF|RTCC_8_bit);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_RDA);
   //enable_interrupts(INT_TBE);
   enable_interrupts(global);

   set_tris_e(0);
         fprintf(Console,"working");
   while (TRUE) {
      restart_wdt();
      if (data_avail) {
         data_avail = FALSE;
         fprintf(Console,"Data is now available\r\nData: ");
         for (i = 0; i < 5; i++) {
            fprintf(Console,"%s",rx_buffer[i]);
         }
      }
   }
}
homfray



Joined: 19 Nov 2003
Posts: 45
Location: Oxford

View user's profile Send private message Visit poster's website

PostPosted: Thu Aug 04, 2005 10:35 am     Reply with quote

your a bloody good 'un. Let me try that tomorrow and will come back

Thanks newguy!!!!!!!!!!!
_________________
Nice!!!
homfray



Joined: 19 Nov 2003
Posts: 45
Location: Oxford

View user's profile Send private message Visit poster's website

PostPosted: Fri Aug 05, 2005 6:14 am     Reply with quote

Thought I would change the title to make it more appropriate

Guys, thanks, I really appreciate everything you have done, the code works perfectly and I can transmit on one device and recieve on the other. With this code it appears to be fairly easy to add extra recievers giving them individual addresses. Although I may have to use more standard names and data instead of 'dave rocks'.

The code below is only slightly different from newguys with a few minor errors corrected.

Thanks everyone for all your help I really appreciate the fact that you took your time to help someone you don't know!!!!


Transmitter Code:
Code:
// INCLUDE FILES
#include <18F8621.h>
#device *=16 ADC=8
#include <STRING.H>
#include <STDIO.H>
#include <STDLIB.H>
#define Fosc 40000000               
//-------------------------------------------------------------------------------------
// DEFINES
#define WireTX PIN_C6
#define WireRX PIN_C7
//-------------------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#use delay(clock = Fosc)

#fuses EC_IO      // EC Oscillator with RA6 configured as DIO
#fuses NOOSCSEN   // Oscillator System Clock Switch Disabled
#fuses NODEBUG   // No Background Debugger
#fuses NOLVP      // Low Voltage ICSP Disabled
#fuses NOPROTECT   // No Code Protect
#fuses NOWDT      // No onboard watchdog
#fuses PUT         // Power Up Timer Enabled
#fuses BROWNOUT   // Brown Out Reset enabled

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
void main()
{
   while(1)
   {
      fprintf(Wireless, "%c", 0xBA); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, "%c", 0xBE); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, "%c", 0xFA); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless, "%c", 0xCE); // LAM - something for the RX's USART to "lock onto"
      fprintf(Wireless,"Dave Nice\r"); // I'm going to get the RX code to look for "Dave " as the ID...
      // ...and "Rocks" as the command/data
      delay_ms(5000);
   }   
}


Reciever Code

Code:
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000 
#define WireTX PIN_C6
#define WireRX PIN_C7
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console)             //Setup RS232

#define RX_BUFFER_SIZE 80
#define TX_BUFFER_SIZE 80

int8 rx_wr_index = 0, tx_rd_index = 0, tx_wr_index = 0, tx_counter = 0, received = 0;
int8 lock_state = 0, rxd, i, valid_data_count;
unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1], tx_buffer[TX_BUFFER_SIZE + 1];
int1 data_avail = FALSE, got_id = FALSE;

#int_RDA
void RDA_isr(void) {
   rx_buffer[rx_wr_index] = getc();
   rxd = rx_buffer[rx_wr_index]; // this just makes it easier typing-wise later on
   rx_wr_index++;
   if (rx_wr_index > RX_BUFFER_SIZE) {
      rx_wr_index = 0;
   }
   
   // now look for unique ID: "Dave "
   if (rxd == 'D' && lock_state == 0) {
      lock_state++;
   }
   else if (rxd == 'a' && lock_state == 1) {
      lock_state++;
   }
   else if (rxd == 'v' && lock_state == 2) {
      lock_state++;
   }
   else if (rxd == 'e' && lock_state == 3) {
      lock_state++;
   }
   else if (rxd == ' ' && lock_state == 4) { // got the entire string "Dave ", in that order
      lock_state = 0; // reset our "combination lock"
      got_id = TRUE;
      valid_data_count = 0xff; // get ready to count the number of data bytes - we know we have to expect 5 (Rocks)
      // also going to reset the buffer write index back to 0, so that I know where my valid data will be
      rx_wr_index = 0;
   }
   else { // we didn't receive "Dave ", so reset the lock back to the beginning
      lock_state = 0;
   }
   
   if (got_id && ++valid_data_count == 5) {
      data_avail = TRUE;
      got_id = FALSE;
   }
}

#int_TBE
void TBE_isr(void) {
   if (tx_counter != 0) {
      putc(tx_buffer[tx_rd_index]);
      if (++tx_rd_index > TX_BUFFER_SIZE) {
         tx_rd_index = 0;
      }
      tx_counter--;
      if (tx_counter == 0) {
         disable_interrupts(INT_TBE);
      }
   }
}

void bputc(int c) {
   int restart = 0;

   while (tx_counter > (TX_BUFFER_SIZE - 1));

   if (tx_counter == 0) {
      restart = 1;
   }
   tx_buffer[tx_wr_index++] = c;
   if (tx_wr_index > TX_BUFFER_SIZE) {
      tx_wr_index = 0;
   }
   tx_counter++;
   if (restart == 1) {
      enable_interrupts(INT_TBE);
   }
}

void main() {

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_ON);
   setup_timer_0(RTCC_INTERNAL|RTCC_OFF|RTCC_8_bit);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_RDA);
   //enable_interrupts(INT_TBE);
   enable_interrupts(global);

   set_tris_e(0);
   fprintf(Console,"working");
   while (TRUE) {
      restart_wdt();
      if (data_avail) {
         data_avail = FALSE;
         fprintf(Console,"\r\n\r\nData is now available\r\nData: ");
         for (i = 0; i < 5; i++) {
            fprintf(Console,"%c",rx_buffer[i]);
         }
      }
   }
}


cheers

dave
_________________
Nice!!!
Guest








PostPosted: Fri Mar 03, 2006 10:22 am     Reply with quote

I don't understand what u mean by unbalanced signals

Humberto wrote:
Hi homfray,

Just copied and pasted -in blue- the following paragraph of my previous post to introduce you what I mean:

Lower AM transceivers requires a balanced signal. Sending unbalanced signals as ASCII chars, the demodulator (in the received side) would get biased improperly and blocked until another string of chars of oposite polarity would recover such situation.

The "clue" is that the "weight" of the equivalent '1' and '0' of your string must be equal. Sending binary ASCII signals over the RF link obviously won´t meet this requeriment.

A) Rigth way to solve this is using Manchester encoding. Not so easy for begginers.

B) A "dirt" an easy solution -if your packet is very short- is to send each ASCII chars precedded by an "balanced" char like 'U' whose binary equivalent is 0b01010101 in this fashion :
Your packet: "G021D"
Sending: "UUGU0U2U1UD"



If you want to send a short packet of bytes, (being short packet < 10) then you can use the "dirt or tricky way".
Start sending a burst of balanced char 'U' (0x55) as a preamble and to " biasing wake up" the RF receiver module.

Code:

#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless) 
void main()
{
   while(1)
   {
      fprintf(Wireless,"UUUUXUYU\rU\n");
      delay_ms(5000);
   }   
}


In colors:
fprintf(Wireless,"UUUUXUYU\rU\n");

In the receiver side, just through away the 'U's and recover the XY.

Best wishes,

Humberto
Ttelmah
Guest







PostPosted: Fri Mar 03, 2006 11:14 am     Reply with quote

Visualise the letter 'A', coded in ASCII. The representation, is 0x41, and in binary 01000001.
There are two 1's, and six zeros. This is an 'unbalanced' signal. Unfortunately, if this is sent over simple radio systems, using direct signal transmission (rather than sending 'tones' to represent the bits), this results in the bias levels in parts of the recovery circuit shifting, and the radio becomes unable to correctly recover the data after a few such characters. Some characters are inherently 'balanced'. The pair that are balanced with the shortest period, are heximecimal 0xAA, and 0x55. The latter is ASCII 'U', which is why Humberto selected this. In general, most systems can handle a certain number of bits imbalance before it becomes a problem. If the radio can handle 8 bits without a problem, then you can use the trick of adding balanced 'padding' characters. You can also get the same effect, by sending each character twice, and inverting the second copy. So you send 'A' as 01000001 101111110. Unfortunately all these approaches waste a lot of signalling bandwidth (you are only receiving one character for each pair sent in either case). Manchester encoding, is a much more efficient way of doing this, but is fairly processor intensive, to code/decode.

Best Wishes
Humberto



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

View user's profile Send private message

PostPosted: Fri Mar 03, 2006 11:31 am     Reply with quote

Quote:

I don't understand what u mean by unbalanced signals

Well, in fact the suitable term would be "zero DC component"

For example:
To modulate the letter 'A' has its binary equivalent '0b01000001'
The RF txmiter would switch-on for every '1' and switch-off for every '0' found in the bit stream.
You will see that the letter 'A' has only two '1' and seven '0'. The relation of ' 1 ' and '0'
determines the amount of component of DC of the signal, being the '1' additives
and '0' the substracting ones.

In an RF link a number of things have to be taken into consideration, most notably is the
need to maintain a zero DC component in the serial bit stream.


Humberto

Edited: Sorry Ttelmah. I keep opened the post reply window for a while and I didn't see your answer.
GUST1
Guest







PostPosted: Fri Mar 03, 2006 4:29 pm     Reply with quote

So is an unbalanced signal a physical problem or is it a software problem?
I'm still not clear. To make a balance signal, you would need the same number of 1's and 0's? I still don't see why having more 0's than one can cause a problem.

Humberto wrote:
Quote:

I don't understand what u mean by unbalanced signals

Well, in fact the suitable term would be "zero DC component"

For example:
To modulate the letter 'A' has its binary equivalent '0b01000001'
The RF txmiter would switch-on for every '1' and switch-off for every '0' found in the bit stream.
You will see that the letter 'A' has only two '1' and seven '0'. The relation of ' 1 ' and '0'
determines the amount of component of DC of the signal, being the '1' additives
and '0' the substracting ones.

In an RF link a number of things have to be taken into consideration, most notably is the
need to maintain a zero DC component in the serial bit stream.


Humberto

Edited: Sorry Ttelmah. I keep opened the post reply window for a while and I didn't see your answer.
david90



Joined: 25 Feb 2006
Posts: 23

View user's profile Send private message

PostPosted: Fri Mar 03, 2006 4:41 pm     Reply with quote

i'm the same guy posted above. I was too lazy to log in.

Quote:
being the '1' additives and '0' the substracting ones.


So your saying that sending a binary 1 will offset the rx's output signal voltage and a 0 will decrease it? Why is that? I thought if the tx sends a 1, the rx will output a 1 and will go back to 0 if the tx sends out a 0.
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 1, 2  Next
Page 1 of 2

 
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