Jump to content
waxpanic1

Sensing RC Receiver Signal w/ PIC

Recommended Posts

Hi Gang,

I am in the process of building a new PIC microchip application. I want to use the extra channels on my RC transmitter to trigger the PIC response. Therefore, the PIC will be looking at the RC receiver to determine if there has been a change in the transmitter switch (a pulse duration change from 1 msec to 2 msec).

The PIC input from the receiver is similar to the input for the Aiptek CAM-Man project and the RCFS project. The timing diagram for the RCFS project is very helpful for my design (providing me with the background informaiton I need to understand the RC receiver's typical output signal). The place where I am struggling is establishing the PIC code to determine the pulse duration during the high signal condition (1 msec, 1.5 msec, 2 msec, etc.). I typically use a PICBASIC Pro compiler when I build applications. Therefore, a solution using PBP is most helpful. I may have to resort to assembly code to find my solution (I'm fine with that).

Can anyone out there provide me with a PICBasic Pro or assembly code example to help me?

Cheers

Share this post


Link to post
Share on other sites

What speed are you running the pic at?

Use the pulsin command.

Pulsin,1, variablename

The pulsin is the command, 1 tells it to look for a high, and the variablename is whatever u program in. Make sure to define whatever u call the variable as a byte.

If you are running the pic on internal 4 mhz oscillator then the resolution of the pulsin measurement is every 10uS and where we normally talk about a servo traveling from 1000uS to 2000uS with 1500uS being center you are now measuring from 100 to 200 with 150 as center.

If you are running a 20mhz external oscillator then the resolution is 2uS and you now are talking 500 to 1000 with 750 being center. All depends on the pic processor speed.

Matt Klarich

Share this post


Link to post
Share on other sites

I am trying to use the pulsin command but, there is a lot of variability in the readings. Here is a list of the last 11 readings:

Pulse Duration = 2

Pulse Duration = 3

Pulse Duration = 3

Pulse Duration = 2

Pulse Duration = 88

Pulse Duration = 88

Pulse Duration = 86

Pulse Duration = 2

Pulse Duration = 81

Pulse Duration = 82

Pulse Duration = 84

I am running the code on a PIC16F88 microchip. The RC receiver is a GWS PICO reciever. The PIC is reading off of channel 1 (Therefore, the receiver pulse should be about 1.5 msec when the transmitter stick is at the neutral "center" point). The PIC is built up on a PCB prototyping board (one of the DH Microsystems prototyping PCBs). The PICBasic Pro code I am running is below:

'--------[Title]-----------------------------------------------

'

'Purpose: RC Transmitter -> RC Reciever -> PIC

'Compiler: PIC Basic Pro

'Created: 11Jan2005

'By: WaxPanic1

'

'--------[Description]-----------------------------------------

'

'

'To determine if Transmitter switch (Channel 5)

'is ON (receiver signal = 2 msec) or

'OFF (receiver signal = 1 msec)

'

'

'

'-------[PCP Program Includes]---------------------------------

'

'

'

INCLUDE "modedefs.bas" ' Mode definitions for Serout

'

'

'

'--------[Define Variables]------------------------------------

'

'

PO VAR BYTE 'Define variable to contain Pulse Count

'

'

'

'-------[Main Program Loop]------------------------------------

'

'

loop:

'Measure the input pulse width on PortB.1 & store in variable PO

PulsIn PORTB.1, 1, PO

'Send PO data out to monitoring computer serial port, baud = 2400

SerOut PORTB.0,T2400,["Pulse Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PO,10,13,10,13]

'Return to the Progam Beginning

GoTo loop

End

Share this post


Link to post
Share on other sites

Your serout statements are taking nearly 100mS to complete. The R/C pulses arrive every 20mS. So, I suspect that when the last char is output, the next pulsin is not synchronized to the servo pulse arrival.

There are a number of ways to fix this. The easiest is to perform two pulsin's. The first one is a dummy (ignore the value). The second one will hold valid data. The serout follows the second pulsin.

As a general rule, you should perform a lot of error checking on your measured data. I would qualify it using several measurements to confirm the data is not noise or glitches.

Share this post


Link to post
Share on other sites

When using the pulsin statement with the 1 modifier the program waits for the next low to high change. So even if the program reaches the pulsin command in the middle of the high of the R/C pulse it will actually wait for the next low to high and make a correct measurement.

Give this a try, first of all change your data rate to 19200 in your terminal program. Try this without modification. Also what speed are you running your pic at? ARE you using internal or external crystal/oscillator. I am assuming you are running external 4mhz crystal using a microengineering labs proto board. Am I wrong?

'--------[Title]-----------------------------------------------

'

'Purpose: RC Transmitter -> RC Reciever -> PIC

'Compiler: PIC Basic Pro

'Created: 11Jan2005

'By: WaxPanic1 (edited by matt klarich)

'

'-------[PCP Program Includes]---------------------------------

INCLUDE "modedefs.bas" ' Mode definitions for Serout

DEFINE OSC 4 'CHANGE THIS To 20 if you aren't using 4 mhz

'

'--------[Define Variables]------------------------------------

CH5PWM VAR WORD 'Define variable to contain Pulse Count

I19200 CON 16416 'INVERTED 19200

Input portb.1 'Sets portb.1 to input

output portb.0 'Sets porb.0 to output

ch5in var portb.1

dataout var portb.0

'-------[Main Program Loop]------------------------------------

'

loop1:

PulsIn ch5in, 1, CH5PWM

pause 5

SerOut2 dataout,I19200,["Pulse Duration =", DEC ch5in, 10, 13]

GoTo loop1

End

===================================

There, give that a try. After it works replace loop1 with this leaving everything above loop1 the same.

===================================

loop2:

PulsIn ch5in, 1, CH5PWM

pause 5

IF CH5PWM>150 then

SerOut2 dataout,I19200,["GEAR ON. CH5= ", DEC ch5in, 10, 13]

else

SerOut2 dataout,I19200,["GEAR OFF. CH5= ", DEC ch5in, 10, 13]

endif

GoTo loop2

End

Matt Klarich

Share this post


Link to post
Share on other sites

Whoops, I hit a button and I don't know what happened. I may end up posting a response twice.

I tried to add an additional Pulsin command prior to performing the serial output (in fact, I added 4 more pulsin commands for extra assurance). The Serial output remained the same...there was just more readings. The highest values were averaged around 84 (82,83,84,85,87) and the lowest readings were centered around 3 (2,3,4). Changing the transmitter input has no effect upon the measured pulse width. I even added a line to make sure all of the port B pins were output except the pulsin pin (using the TRISB command) just to make sure that there wasn't any drift from untied down input pins. Here is the main loop that I tested out:

____________________________________________________________________

loop:

'Take a dummy Pulse In measurement to syncronize the PIC with the receiver signal.

'Then, Take a real measurement of the Input pulse width ON PORTB.1 & store in variable PO

PulsIn PORTB.1, 1, PD

PulsIn PORTB.1, 1, PI1

PulsIn PORTB.1, 1, PI2

PulsIn PORTB.1, 1, PI3

PulsIn PORTB.1, 1, PI4

'Send PO data out to monitoring computer serial port, baud = 2400

SerOut PORTB.0,T2400,["Dummy Pulse Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PD,10,13,10,13]

Pause 20

SerOut PORTB.0,T2400,["Real Pulse 1 Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PI1,10,13,10,13]

Pause 20

SerOut PORTB.0,T2400,["Real Pulse2 Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PI2,10,13,10,13]

Pause 20

SerOut PORTB.0,T2400,["Real Pulse 3 Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PI3,10,13,10,13]

Pause 20

SerOut PORTB.0,T2400,["Real Pulse 4 Duration = "]

Pause 20

SerOut PORTB.0,T2400,[#PI4,10,13,10,13]

Pause 1000

'Return to the Program Beginning

GoTo loop

____________________________________________________________________

Matt...I also tried your suggestions. Indeed I am using an external 4Mhz oscillator on a PCB similar to the MELABS X-series. The only real difference I noted in your code was the definition of the oscillator speed, the use of SEROUT2, the change in baud rate, and the definition of i/o pins. I compiled you code as it was written (no errors...excellent job) and I loaded it onto the PIC16F88. When I ran the circuit, there was not output to the computer terminal. I don't think Windows Hyperterminal supports Inverted serial data. I changed the baud rate code to 32 (which operates at 19200 baud but in a Non-inverted form) and the serial output was recognized by my computer's terminal software. The output from the PIC only read either 0 or 1. It was as if the PIC wasn't measuring the pulsin at all.

Any other suggestions? I'd really like to get this up and running (Matt, you had the right idea with the landing gear...very perceptive).

Thanks!

Share this post


Link to post
Share on other sites

Ok, I am moving to the next thing I know about measuring pulse measurements from R/C Receivers. That is the fact that some R/C receivers do not output their PWM signal at 0 low and 5 volt high. They are more around 0 low and 3.3-3.8 high. New futaba PCM being one of them.

If you have an oscilloscope hook it up and measure the peak voltage on the signal line. Your receiver may be using low voltage processors and the PIC may not be recognizing the highs. Have had major problems with that before. A 16F628 will recognize signals from futaba receiver and a 16F877 wouldn't just because of the lower voltage.

Matt

Share this post


Link to post
Share on other sites
That is the fact that some R/C receivers do not output their PWM signal at 0 low and 5 volt high. They are more around 0 low and 3.3-3.8 high. New futaba PCM being one of them.

Futaba PCM has done this for years. I made some simple r/c switches for NAV light control years ago and they would not work on Futaba PCM because of this. I wound up using a pull-up resistor.

Share this post


Link to post
Share on other sites

Well, It looks like I'm at a stand still at this point. I tried to measure the duration based upon a 0 state (Low pin pulse) and I tried to connect a 5V pull up by connecting a 10K resistor to the pin and a 5V source. The result of the pull up is readings of 0 (the pull up overwhelmed the receiver signal). I don't have an oscilloscope to assess the high state voltage or the receiver output signal pattern. can timing functions be performed on every PIC port that is an I/O port or does it need to be a special port?

Share this post


Link to post
Share on other sites

wax,

have you tried plugging a servo into the channel you are using on the rx and then flip the tx switch? This will tell you if the RX is outputting a valid pulse train on that channel.

Regards,

Bill

Share this post


Link to post
Share on other sites

I tried connecting a servor to the receiver prior to beginning the project just to see which channel on the TX went with the RX channel. Everything seemed to work like normal. I'm guessing that the problem is with my PIC code. Quickly looking on the RC groups discussion board reveals a number of people who have successfully created this circuit. All of the examples I could find, however, were written in assembly code (something I'm not familiar with).

Cheers

Share this post


Link to post
Share on other sites

Don't blame the software just yet. There are a hardware issues that could be in the way.

Since we can't see what you are doing, let's go over the setup. Correct me where needed:

- PIC16F88

- GWS Pico (possibly one of the most glitch prone Rx's out there).

- Port B B.1 is servo pulse input

- ME Labs experimentor's board using external Xtal.

Here is what is not known:

- What are your PIC's fuse settings? What are you doing with MCLR and the WDT?

- How is the Rx powered? Does it share power and ground from the ME board?

- When you run your system with the software running, does a servo plugged into an adjacent channel experience glitches? This is a key observation that you should be making throughout your testing.

Some comments:

The GWS PICO's servo outputs are about 3.5V for Logic highs and nearly 0V for logic lows. This is compliments of a CD4000 series shift register. The PIC's B.1 input needs to see <.15V Logic lows and >2.0V logic high input levels. The Pico will provide this with ease. Even with a 10K pullup. Since you found that using a 10K caused it to work worse, then there is something evil going on. Are you sure it was a 10K?

The PICO Rx can easily go nuts with nearby EMI/RFI sources (it is a simple design with a very cheap 455Khz filter). The ME Lab board and your local PC will probably be of concern (lots of RFI!). You can test for this by installing servos on the three open channels while you run your program. They must behave like angles. If they glitch, then your measurements will consist of glitched data too. To minimize this, disable the PIC's external Osc and use its 4Mhz internal Osc instead. And disconnect the PC's communication cable from the ME Lab board while running the program (reduces conductive EMI).

I'm not a PIC basic user, so I cannot help much in that area. However, there is a good chance the problem involves something with your hardware setup. As a last resort, maybe some clear photos of your stuff, with a narrative, will help us out.

Share this post


Link to post
Share on other sites

You are correct on all of your assumptions except with the PCB prototyping board. I am using a DHMicrosystems protyping board. It is very similar to the MELabs prototyping boards (I have one of those as well). I've used the board before to conduct other experiments (flashing LED, A/D conversion of a Temp sensor, and the sending of serial data to my laptop computer (of course). A photo of the board is attached to my reply. the schematics for the board can be found here:

http://www.dhmicro.com/PDFs/Rapid18iXL_Man.pdf

The crystal is an external 4Mhz crystal (with internal capacitors). My Radio Shack voltmeter can read oscillation frequencies up to 4 Mhz and it indicates that my crystal is running at 3.968 Mhz.

The PIC is programmed with the following options:

Oscillator: HS

Code Protection: off

WDT Enabled

Power-up timer enabled

Brown out Reset enabled

Masterclear Reset Enabled

Flash Program Write Enabled

Internal External Switch Over Enabled

Fail Safe Clock Monitor Enabled

CCP Multiplex Enabled

The PIC is powered by a wall wart that is converted from 15 volts to 5 volts by a 7805A Mosfet. The RC system is powered by its own battery pack (ThunderTiger Lipoly pack). The servo attached on another channel appears to be very stable (almost no jittering). I tried to use a Berg 4 microstamp 2 reciever as well (just to rule out the GWS reciever).

I would have to rewire the circuit to disable the external oscillator (either desolder it or reconfigure the PIC wiring, so I'd like to do this as a last resort).

Thanks for the help. Any other thoughts???

Waxpanic1

post-6-1105607405_thumb.jpg

Share this post


Link to post
Share on other sites

From the photos, the first glaring thing I see is that you only have one wire connecting the Pico Rx to the board. Where is gound? If it is there, I don't see it.

Oscillator: HS

WDT Enabled

Masterclear Reset Enabled

- Set the Oscillator to XT. This lowers EMI. HS is best for 8Mhz-20Mhz. Better yet, use the Internal 4Mhz Osc.

- Disable the WDT. I don't know how PBP manages the W-Dog, but for now you don't need to invite timeout reset problems. You can always turn it back on later.

- Disable the Masterclear reset. This is rarely used on modern designs since the newer PICs have other ways to ensure a reliable boot. {My concern with using the MasterClear is that the board's design has a diode isolated reset. This allows for ICSP support, but effectively removes the reset components from MCLR (making the reset components dead weight). The R/C Tx's RF could get into the MCLR input and cause havok.}

The RC system is powered by its own battery pack (ThunderTiger Lipoly pack).

If it is a single LiPO, then you are running on a low voltage (3V-4V). In any event, for now, power the GWS from the regulated 5V on the board.

I would have to rewire the circuit to disable the external oscillator (either desolder it or reconfigure the PIC wiring, so I'd like to do this as a last resort).

That is not what you need to do. All that is required is to use the internal Osc fuse setting. The PIC will default to the 4Mhz internal Osc. It will turn off the external Osc Amp. The xtal components will become paper weights and not cause any harm. However, since you say that the servos connected on all the spare Rx ports are not jittery or glitchy, then perhaps we can assume that the GWS Rx is not getting RFI noise. For now, it is important that you leave a couple servos connected (to unused channels) so that you can watch to see that the PPM signal is intact while you test your program.

Lastly, until you get the system running well, keep the R/C Tx at least ten feet away from the board. This will ensure that the strong local RF is not causing false readings. Later, when it is working, you can determine if your nest of wires is immune to it.

Share this post


Link to post
Share on other sites

I thought about that last night at about 1:00Am when thunderstorm rolled thru and woke me up... I said to myself...."I hope he has a ground between the RC RX and the protoboard" that was about the only thing I could think of..

GET A GROUND ON THERE!!!!!

Matt Klarich

Share this post


Link to post
Share on other sites

Eureka!!!! Powering the receiver off of the prototyping power supply got it up an running! The scale is a little off (low pulse = 105, neutral pulse = 143, high pulse = 180). Since the pulse error is greater on the High side, I'm guessing that this has to do with how the PIC measures the pulse. Now I need to explore this phenomenon.

Great thinking on the common grounding! Now for some more information. Why does the PIC need to share a common ground / power supply with the receiver?

Hey Matt...That was probably the same thunderstorm that woke me up (in California) two nights ago.

CAM-MAN...thanks for the sage advice. I aspire to be as knowledgable about PIC's as you.

WaxPanic1

Share this post


Link to post
Share on other sites
Why does the PIC need to share a common ground / power supply with the receiver?

The PIC doesn't need to share a common power supply, just a common ground.

The signal from the RC receiver needs a return path, hence the need to share the ground.

Regards,

Bill

Share this post


Link to post
Share on other sites
Why does the PIC need to share a common ground / power supply with the receiver?

Common ground is needed for signal return. Sharing the power supply was recommended to minimize some unknowns. In cases where the signals are greater than the PIC's Vdd, using the same power supply prevents input latchup. In cases where the signal source is using a low voltage, it helps to match things up to the PIC's Vdd. Since you are now running, this is no longer a concern.

Share this post


Link to post
Share on other sites

The next project I want to take on is connecting a PIC to the transmitter switch for one of the extra channels (Such as channel 5). The goal is to add extra buttons to the transmitter. A button press will be encoded by a PIC as a series of transmitter switch flips. A PIC on the receiver side will decode the transmitter switching. One PIC on the receiver side will be dedicated to converting the receiver pulses to pin outputs. A second PIC will carryout the commands (take picture, gear down, lights on, transmit data for example).

Has anyone else tried to build a similar system? Any thoughts on the systems design?

Cheers,

WaxPanic1

Jeremy

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×