|
|
View previous topic :: View next topic |
Author |
Message |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
Communcation between PIC's using wireless RS232 |
Posted: Wed Aug 03, 2005 9:27 am |
|
|
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: 1909
|
|
Posted: Wed Aug 03, 2005 9:53 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 2:13 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 5:04 am |
|
|
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
|
|
|
Guest
|
|
Posted: Thu Aug 04, 2005 7:23 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 8:09 am |
|
|
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: 1909
|
|
Posted: Thu Aug 04, 2005 9:40 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 10:35 am |
|
|
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
|
|
Posted: Fri Aug 05, 2005 6:14 am |
|
|
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
|
|
Posted: Fri Mar 03, 2006 10:22 am |
|
|
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
|
|
Posted: Fri Mar 03, 2006 11:14 am |
|
|
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
|
|
Posted: Fri Mar 03, 2006 11:31 am |
|
|
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
|
|
Posted: Fri Mar 03, 2006 4:29 pm |
|
|
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
|
|
Posted: Fri Mar 03, 2006 4:41 pm |
|
|
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. |
|
|
|
|
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
|