SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By marker5a
#34294
Ok
So, I have been messing around with the TLP434A/RLP434A pair. I am doing a very basic function using examples from MikroC. The transmitter sends a message and displays it on the receiver's LCD. I have done this first without using the RF modules and instead a direct wire connecting the two PIC's. When I do this, it works over and over again without any problems. However, when I remove the wire and add the modules in, it no longer works. The clocks are running independent from each other and therefore I have been using manchester to encode the signal.

I haven't done any modification to the adjustable inductor and I just received this pair not too long ago in the mail.

Any suggestions?
By maf
#34297
How close are they? The TLP and RLP modules don't work if they're too close without attenuation.

What is the bit rate? 4K is about the limit for the "fast" version that I received without the error rate going up too high.

Are you using the UART? A full blown implementation of a manchester receiver which recovers the clock isn't required, just enough so that the average message is DC balanced (relatively same # of 1's and 0's). Also on a PIC make sure to clear the UART error bit -- if (OERR) CREN=0,CREN=1; since you'll always be receiving noise.

Are you sending a preamble? The RLP needs a little time for the AGC to adjust. The easy way to do this is just send a "1" for about 16ms. Then send a start code like 0xCC 0x33 to get the UART locked on, wait for this sequence on the receiver side before looking for the message.

These modules should ship with an FAQ.

See also
http://www.printcapture.com/files/X10_RF_Receiver.pdf
By marker5a
#34302
no i'm frustrated...

As far as distance between them, I have them about 5 feet apart... should this be increased?

I am frustrated because I have spent a good amount of time trying to get the hang of manchester because everyone I have talked to has said to use that.

I tried using the USART on the PIC, but I could never get them synchronized to send a message, everything was jumbled.

I tried sending one's for 15ms as you said, to adjust the gain, but that didn't show any results...

I appreciate your help maf (wasnt frustrated at you btw)... do you or any one else have any other suggestions?
By saipan59
#34306
Be sure to read other related topics in the forum on this subject - there's been many threads on the problems/solutions.

Meanwhile:

As for 5 feet distance: it may or may not be far enough, depending on what you use for antennas on the rcvr and xmtr. Start with no antennas at all.

Manchester: It's a fine solution to the "DC balance" issue. But I had success with simply sending each byte followed by the bit-wise inverse of the byte, using the 4800-bps versions of the modules.

When the xmtr is off, check that you are getting 'garbage' from the rcvr.

As already mentioned, you'll need to repeatedly clear OERR, or the UART will lock up.

You said you couldn't get the UARTs synced - was that with a plain wire? And what are you doing now?

On the xmtr side, start with code that sends 3 or 4 chars of 11111111, followed by a continuous stream of 'U' chars (the bit pattern is 10101010, which is ideal). If you can make that work, you're well on your way.

Pete
By maf
#34307
5' should be fine when using a short wire antenna. The problems started around 3' for me.

The UART method adds extra overhead (start/stop bits) and requires the PIC USART. If its not used for anything else and the overhead is not an issue it works fine. The manchester encoding doubles the sizes of the messages, again if that's not an issue... Encoding provides some error checking for free (invalid symbols). It's also possible the USART might not be able to lock on to the received signal. The 1's and 0's are not the same pulsewidth depending on the transmit rate. In practice this didn't appear to ever be a problem.

I would try something simple like transmit '0xAA' in a tight loop and verify the receiver can see it. If this doesn't work make sure you're connected to the digital out of the RX module. Some have analog outputs.**

The trick to making this work with the USART is the 16ms "1" followed by a bit sequence which the receive USART can synch up to. After that just ensure the data message is DC balanced and add a checksum at the end. If nothing is showing up on the RX side make sure the OERR condition is handled correctly. The RX USART will be receiving noise most of the time which almost guarantees the OERR state will be entered which prevents any further received bits until the CREN=0, CREN=1 sequence is executed.

If you're just sending a simple one byte message the protocol in the X10 document can work well too. Transmit is simple, receive can be done with the help of the CCP peripheral.

Here's a working encode/decode routine for an 8 byte message (net_msg) and 18 byte tx/rx buffer (net_tx_buf and net_rx_buf).
The first two bytes in the tx/rx buffer are assumed the start sequence. The remaining 16 are the manchester symbols for the 8 byte message.

** Leaving the transmitter on like this is probably not legal and may cause problems for nearby keyless entry systems on cars, garage door openers, etc.

void net_msg_encode(void)
{
unsigned char i,j,k,l,b,vb,mb;

/* index to encoded message */
l = 2;

/* foreach byte in the message */
for (i = 0; i < 8; ++i) {
/* get vanilla byte */
vb = net_msg;
/* foreach nybble */
for (j = 0; j < 2; ++j) {
/* manchester byte=0 */
mb = 0;
/* foreach bit in the nybble */
for (k = 0; k < 4; ++k) {
/* get a bit */
b = vb & 0x01;
/* next bit in vanilla byte */
vb = vb >>1;
/* next twobit in manchester byte */
mb = mb >>2;
if (b == 0)
mb = mb | 0x40; /* 01 */
else
mb = mb | 0x80; /* 10 */
} /* k */
net_tx_buf[l++] = mb;
} /* j */
} /* i */

} /* net_msg_encode */

unsigned char net_rx_decode(void)
{
unsigned char i,j,k,x,tb,mb,vb;
/* tb=two bit,ijkx=counter,mb=manchester byte,vb=vanilla byte */

i = 0;

for (x = 0; x < 8; ++x) {
vb = 0;
for (j = 0; j < 2; ++j) {
mb = net_rx_buf[i++];
for (k = 0; k < 4; ++k) {
tb = mb & 0x03;
vb = vb >>1;
if (tb == 2) {
vb = vb | 0x80;
} else if (tb != 1) {
net_msg[0] = net_rx_buf[i-1];
return i+1; /* decode error */
}
mb = mb >>2;
} /* k */
} /* j */
net_msg[x] = vb;
} /* x */

return 0; /* good */

} /* net_rx_decode */
By Philba
#34317
I don't suppose you have an o'scope? I did something very similar to what you are doing and found the scope to be invaluable in debugging my design. Maybe you could borrow one...

One thing I ran into is when you transmit balanced pulses (ie 50% duty cycle), the TLP/RLP pair winds up making the high pulse shorter than the low pulse. I suspect it's due to the time it takes to turn on the transmitter (while turning it off is instantaneous). This messed up my manchester receive code. I compensated by increasing the on time and decreasing the off time to better balance the two. It worked quite well after that. I did not use a UART.
By marker5a
#34318
well, i wish I had an o-scope... I'm an EE student, however, we don't have access on our own time to use the school's lab's... I just need to keep trying out new things. If and when I do get it up and running, I am going to make a dumbed-down write up on how to do this on these cheaper RF units.
By Philba
#34337
You know, I bet if you talked to the lab assistant, he/she might let you go in during another lab session. I'm certain that they would be impressed that you are doing more than the curriculum.

A couple other things to consider.

The rf link will have noise. I found a lot of short spikes would come in on the receiver. I used a state machine approach to the receive side. I start in the IDLE state and any leading edge causes me to enter the LEAD_IN_WAITING state. Entering that state kicks off a timer with a period longer than the pulse width. It also toggles the interrupt edge sense but a noise spike is too short to catch the trailing edge so if the timer interrupt happens and the input is low, the state is transitioned back to IDLE. This filters out the vast majority of the noise.

You might also consider using a low pass filter with a cut off frequency set to something like 8X your data rate or even higher. This might filter out a lot of the noise. Most the the spikes I saw were pretty high frequency. I didn't try this since it was easier for me to tweak my code.

The LEAD_IN_WAITING state looks for several clock cycles of a high. I made this configurable and found that it can be pretty short. IIRC, I ended up using 3 half cycles. It's important to have a solid basis for going into the next stage (the actual data). I think I started out with 8.
By johnsmith123
#34930
marker5a wrote:Ok
So, I have been messing around with the TLP434A/RLP434A pair. I am doing a very basic function using examples from MikroC. The transmitter sends a message and displays it on the receiver's LCD. I have done this first without using the RF modules and instead a direct wire connecting the two PIC's. When I do this, it works over and over again without any problems. However, when I remove the wire and add the modules in, it no longer works. The clocks are running independent from each other and therefore I have been using manchester to encode the signal.

I haven't done any modification to the adjustable inductor and I just received this pair not too long ago in the mail.

Any suggestions?
Just wondering if you figured it out? I am also using the TLP434A.
I have the same problems. I am using two avr's, one as receiver, one as transmitter. Both are on separate boards with separate power supplies.

Both units are hooked to a terminal (via a max232) to allow me to see what is being sent from the transmitter to the receiver. In the terminal connected to the transmitter I can type any data which will be sent by the transmitter, received by the receiver and displayed to the second terminal via the avr and max232 circuit. I am using the hardware uart in both avr's (not bit banging code) and the baud rate is 2400 bps. I tried it with no antennas, but now I am using an 8" piece of copper wire on both units stripped from the center of an RG6 cable.

When I remove the transmitter and receiver, and connect a wire from the data line output of the transmitting avr into the uart input of the receiving avr, all data received is perfect. Whatever is sent, is being received perfectly.

The data being received is always consistant,

i.e.
if I send a "1", the receiver receives a "g".
if I send a "2", the receiver receives a "3".
if I send a "3", the receiver receives a "f".
if I send a "5", the receiver receives a "e".
if I send a "6", the receiver receives a "2".
if I send a "7", the receiver receives a "d".
if I send a "8", the receiver receives a return.
if I send a "9", the receiver receives a "c".

This is the same all the time, even when its reset. I know the problem is not with the code since it works perfectly when directly connected without the RF modules(as mentioned above)

The transmitter seems to be transmitting ok, but its just not the right info.

I tried moving both units right beside each other, and 5 feet away, 20 feet away and 30 feet away. Always same thing.

Can someone with some experience with these units Please shed some light?
There just doesn't seem to be much information about these units on the internet. I downloaded the Module walkthrough on this site, but it didn't seem to help.

Anyone with any ideas??
By Philba
#34935
sorry but the problem is very much likely to be in your code. The transmitter/receiver creates all sorts of issues. read the above thread and search for several similar threads from the past year.

these transmitters want to see balanced input. That's what manchester coding is all about. I personally wouldn't bother with using async (and NRZ).
By johnsmith123
#34942
I had no idea there were so many threads about this same thing. I am trying to figure out which way to go.

Does anyone have any asm examples in avr or 8051 they would like to share?
By johnsmith123
#35026
this link may give some ideas if you are having trouble. Its a great site:
http://www.serasidis.gr/

Well I figured out a more efficient way of accomplishing what I want.

The transmitter sends a packet like this:
AA BB 01 10
AA = 1st identifier
BB = 2nd identifier
01 = command
10 = checksum - result of all three bytes xor'ed together.

The transmitting routine will xor each byte with the next byte in the packet. The receiver filters the first two leader bytes and only if they are valid, it will proceed to read the third byte (command). If the 4rth byte (checksum) fails, then the packet is discarded.

The only problem is HOW TO enable interrupts without complications. If interrupts are enabled on every byte, there would be no way of knowing when the packet begins. i thought of enabling interrupts and checking for the first byte (AA), once this byte is found, disable interrupts and read the next three bytes with the polling method. Once the packet has been received ok, and the command executed, re-enable interrupts.

Any ideas anyone? By the way I am using avr in asm. (I don't do C)

IF anyone wants to see the code let me know.
By saipan59
#35035
The transmitting routine will xor each byte with the next byte in the packet. The receiver filters the first two leader bytes and only if they are valid, it will proceed to read the third byte (command). If the 4rth byte (checksum) fails, then the packet is discarded.
The only problem is HOW TO enable interrupts without complications. If interrupts are enabled on every byte, there would be no way of knowing when the packet begins. i thought of enabling interrupts and checking for the first byte (AA), once this byte is found, disable interrupts and read the next three bytes with the polling method. Once the packet has been received ok, and the command executed, re-enable interrupts.
Any ideas anyone? By the way I am using avr in asm. (I don't do C)
What you describe is (sort of) what a 'preamble' is for.
What I do is this:
- Interrupts are enabled by default.
- In the ISR is a simple 3-byte FIFO buffer. Every time I get a new char, I check it and the two previous chars to see if it matches the expected pattern. If not, leave the ISR and do nothing.
- If the pattern matches ('preamble received'), then set a flag. This flag is checked by the main() routine (outside the ISR).
- While the flag is set, every additional byte I receive is assumed to be part of the message packet.
- When enough bytes have been received to fill up the packet, turn off the flag, and start processing whatever was in the packet. You may want to disable interrupts while processing the packet.

You should consider learning C. I have C code for PIC that I will share if you want.

Pete
By johnsmith123
#35041
saipan59 wrote: You should consider learning C. I have C code for PIC that I will share if you want.
Pete
Yes I hear you. Everything nowadays seems to be in C. I can't get away from it.
Installing a HUGE compiler and having the headache of making sure the right path is set up for every file has always been the reason for me to give up on C. Besides I think that its very easy to debug asm code if you know asm than it is to do it in C. I always like to know what is going on in the code and be in control. I think a compiler does most of the work for you, relieving you of this burden. It can be beneficial if you are working with rather large source files.

I DO want to learn it, but its on the back burner for me.
Maybe someday.... I do have quite a few avr tutorials in C just waiting to be read.

Thanks for your post, you have given me some good ideas.

Cheers!
User avatar
By davemaster
#40041
Greetings,

Some steps to get some results:

1. Try tx/rx without the rf modules, ie, directly with a wire.

2. You must read the modules datasheet, so you can know the speed limit.

3. Once you did 2, configure your "serial" connection to speed supported by rf modules. The data will be sent/received in serial way. For example, if in transmiter you configure a PIN (microcontroller) as rs232, 2400 bps, parity none, 8 bit data, 1 stop bit; you must use this same parameters in receiver.

4. I recommend microcontrollers with add-on UART.

5. You can make your own encode/decode scheme... ie:
- 1 is ---__
- 0 is -----__
- start data is --------_____
- new byte -------------______
- etc...

This is the best way i think, because you can correct signal error to get more range...

Good luck...