Jump to content
Sign in to follow this  
geogecko

Nav-Lights Variation Project Help

Recommended Posts

Hi. I'm wanting to build a variation of the Nav-Lights project, but was needing an idea to help get started.

The chip I want to use is the PIC12F675, which has both timer 0 and 1. I'm trying to come up with a way to measure the pulse width of the output of the Rx channel (servo output), however, using the internal 4MHz oscillator (which I have to do, do to pin limitations), the count on the timer is 10, if set up for a 10us timer. The problem with this is that I will be doing some other code, and may miss the timer timing out.

The 10us would be a nice resolution for the timer, however, I guess I could make it longer. I wouldn't want it to be any greater than about 50us though.

Any ideas? Should I use interrupts or just stick with using the interrupt flag? I really don't want to do the timing in software, unless necessary.

Any help is appreciated.

Jason.

Share this post


Link to post
Share on other sites

A 10uS timer interrupt on a 4Mhz PIC will be a resource hog. Perhaps 25uS will be a better choice (40 step servo pulse resolution). If you have a lot other tasks to do then it may be best to just monitor the T0 flag or the T0 count.

My usual technique {when using the internal oscillator} involves state table driven code that is synced to the R/C pulse. With the PIC12C50X series PICs, I just monitor the T0 count for overflow, as well as employ loop driven machine cycle counters. The code is efficient, minimizes measurement jitter, and offers reasonable servo pulse resolution. However, it is bothersome when I port it to my other designs since the state counts need to be recalculated.

There are so many different ways to skin this cat -- just do what you feel the most comfortable with.

Share this post


Link to post
Share on other sites

I agree with you that the 10us timer would be a resource hog. If I go this route, the 25us should be sufficient.

So, by "synced to the R/C pulse," I assume that you start your code looking for the edge of the servo pulse, then wait in a software loop for the for the other edge of the pulse, afterward, you take care of all the other tasks that you have to do, because at this point, you have some 18ms before you expect the next pulse? Is this why you say that it minimizes measurement jitter, because you don't do anything else while waiting to measure the entire pulse, and end up overshooting the actual pulse?

Would another method of doing this be to use the interrupt on pin change to catch the pulse, and have the measurement as part of the interrupt service routine?

I have a couple other questions.

1. What is considered a “glitch?” Is this just a pulse that is less than ~1ms and greater than ~2ms?

2. What does an Rx channel (servo output) put out when the Tx is turned off?

Thanks again for the help!

Share this post


Link to post
Share on other sites
...Is this why you say that it minimizes measurement jitter...?
That about sums it up.

Would another method of doing this be to use the interrupt on pin change to catch the pulse, and have the measurement as part of the interrupt service routine?
Yes, you can use that method.

What is considered a “glitch?” Is this just a pulse that is less than ~1ms and greater than ~2ms?
You will need to open up that spec a bit. Some Tx's can easily go beyond the 1mS spread, perhaps by at least +/-20%.

2. What does an Rx channel (servo output) put out when the Tx is turned off?
Generally, anything from a steady logic state to wild random twitches. The Rx's front end is running open ended, so the poor thing will do what it can to decode noise.

Share this post


Link to post
Share on other sites

Great. Thanks for the help. I got my LEDs from superbrightleds yesterday, wow! :blink: Those are bright. We'll see how they do for flying at night. I'm also considering building a version to use in an E-Maxx for headlights/brakelights/off-road lights, etc. I'll let you know how the project is going. Using the 12F675 is just a little different than the 16 series I'm used to.

The data sheet says that a global /GPPU must be enabled for individual pull-ups to be enabled. Does that mean that bit should be cleared to enable pull-ups?

Jason.

Share this post


Link to post
Share on other sites

Next question:

I'm using a 2N2222A made by Motorola, and I'm not getting the brightness that I expect from the LEDs (when I run them off of the power supply with the same resistor, I get a lot more brightness). I measured the Vce across the transistor, and when it's turned on, it has a Vce drop of 2.18V. Is this normal? Is this transistor not the same as the PN2222A that is used in the Nav-Lights project? What Vce are you expecting with the PN2222A part? I assume not much, since you are using resistor values that don't figure in Vce, right?

Thanks for the help.

Share this post


Link to post
Share on other sites

VCE should be MUCH lower (under 1V) . It sounds like you have the Collector and Emitter reversed (my best guess).

Share this post


Link to post
Share on other sites

Okay, seems to be a problem with the PIC output pin. If I hook up the base resistor to the power supply (~5V), the LED comes on as expected. Any ideas now? The PIC is only putting out about .5V on a high level.

Thanks.

Edited by geogecko

Share this post


Link to post
Share on other sites

Okay. It's been a long day. I hope that I haven't wasted too much of anyone's time. It helps to have the correct power and ground hooked up to your PIC, so just remember this.

Now that I have the strobe working, I need to mess with the timing of the servo signal...

Thanks.

Share this post


Link to post
Share on other sites

Hi. I seem to be having a timing problem, or at least, maybe I'm not setting up the timer correctly. The reason I say this, is that it does not seem to have the timing I would expect. I set up for a delay of 1 second or so, and it lasts amost twice that long, maybe a little less. This is the code I'm using to set up the timer for a 20ms delay. (Sorry if the formatting makes it difficult to read.)

;***

INIT_TMR1

;*** Initialize Timer 1 to give 20ms delay

CLRF T1CON ;Stop Timer 1, Internal Clock Source,

;T1 Oscillator Disabled, Prescaler = 1:1

CLRF TMR1H ;Clear Timer 1 High Byte Register

CLRF TMR1L ;Clear Timer 1 Low Byte Register

CLRF INTCON ;Disable Interrupts

BSF BANK_SW ;Switch to BANK 1

CLRF PIE1 ;Disable Peripheral Interrupts

BCF BANK_SW ;Switch to BANK 0

CLRF PIR1 ;Clear Peripheral Interrupts Flags

MOVLW 0x00 ;Internal Clock Source with 1:1 Prescaler

MOVWF T1CON ;Timer 1 is Stopped and T1 Oscillator

;is Disabled

;Set Up Timer 1 for 20ms Overflow

MOVLW 0xB1 ;Timer 1 High Byte Register

MOVWF TMR1H

MOVLW 0xE0 ;Timer 1 Low Byte Register

MOVWF TMR1L

BSF T1CON,TMR1ON ;Timer 1 Starts to Increment

RETURN

;***

Does this seem correct if running off the internal 4MHz oscillator?

The only thing I'm doing in the main routine if the interrupt flag has not been set, is a call to a routine, a bit test which does not branch, a goto, and a return, and that's it. When there is an interrupt flag set, I have way less than 20ms worth of code to run, because that would be something like 20,000 instruction cycles.

Thank you!

Edited by geogecko

Share this post


Link to post
Share on other sites

I don't have to reset TMR1H and TMR1L to the 0xB1 and 0xE0 respectively, after I get an interrupt flag, right? Maybe that is my problem?

Share this post


Link to post
Share on other sites
I don't have to reset TMR1H and TMR1L to the 0xB1 and 0xE0 respectively, after I get an interrupt flag, right? Maybe that is my problem?

You must reload the timer at each overflow/interrupt. Otherwise, your new timer value will default to 0xffff (approx 65mS).

Also, your interrupt routines must take the time to save all the common registers. Otherwise the registers can be corrupted by the branch to the interrupt calls. These sort of details are handled by higher level languages like PBasic or C; PIC assembly coders have to roll up their sleeves and ensure that all the little details are covered.

Share this post


Link to post
Share on other sites

Ahh... That would explain the longer delay. Thanks for the information. At the moment, I'm not using interrupts, just looking at the flags, however, I probably will be using interrupts for the Timer 0 module that will be timing the servo pulses.

Is PicBasic a free tool? I'm just used to the assembly, because that's what we used in school, however, it would probably be a lot easier to use the basic compiler.

Share this post


Link to post
Share on other sites

There may be free PIC Basic compilers out there, but I am not sure. There are some free PIC C compilers available. So, just search around to see what you can find.

I think there are a couple of related links at the Links and Web Resource Sites forum.

Share this post


Link to post
Share on other sites

I know this is covered in one of your articles, as I've read it, however, I just want to be completely sure of what you mean.

When you give an instruction such as "BCF TRISB ^ 0x80,1" or "MOVWF OPTION_REG ^ 0x80" is this for every register that is above address location 0x80? I see that the OPTION_REG for the 12F675 is at address 0x81, so wouldn't XORing an 0x80 with the OPTION_REG change the value of what was in data bit 7? Why would you want this? I guess I'm not following why this is used. It seems to me that you would want to make sure that bit 7 of the ADDRESS is a 1 when in Bank 1, but not the data bit 7. Am I understanding this wrong?

Thanks again for all your help.

Jason.

Edited by geogecko

Share this post


Link to post
Share on other sites

I'm not sure if you are posting the questions to me in particular. If you are, then I cannot offer any advice (the examples are not my native code). Perhaps the author of the code snippets can help.

Share this post


Link to post
Share on other sites

I assumed you were the author of the code... Please excuse me. Anyway, possibly the author will see the message and respond, or someone that understands what is going on might explain it.

As for the next step in my project, I was going to use 0.8ms and 2.2ms as my limits for a valid pulse coming from the receiver for a servo. Does this sound about right? I will have a resolution down to 1us, so I can pretty much set up any limits I like. I'm going to assume that anything below the 0.8ms is a glitch, however, I'm not sure what to consider anything above 2.2ms as? Should this also be considered a glitch, or sould I just throw out the measurement, and try again?

Share this post


Link to post
Share on other sites

Where did the original code come from? Do you have a link?

Your R/C signal limits sound fine. There are situations on some Tx's where their ATV/EPA's, when applied against worse case mixes, will go beyond your chosen values. There isn't a formally agreed upon standard out there, so what you choose is personal preference.

Share this post


Link to post
Share on other sites

Actually, I wish I did have a link to the original code. However, he states many places that he will not provide the original code, only the hex file. I've had to come up with mine from scratch. It's fun though, and a learning experience. I'm going to use what I learned from this project on another, unrelated, project, so it was a good starting point.

It's strange that a standard isn't out there. I guess that servo manufactures may have different standards as well, or maybe they only go by the strict 1ms to 2ms, and not worry about the rest... I'm going to give it a try, and see what happens. I'll be more than happy to provide my code once it is finished.

Thanks. Jason.

Share this post


Link to post
Share on other sites
However, he states many places that he will not provide the original code, only the hex file.

That is common place. FWIW, all my projects, as published on the RC-CAM site, are released as hex files only. The source is not published for various reasons.

So, where did the code snippets you have questions about come from? Is it a project that you can provide a link to?

Share this post


Link to post
Share on other sites

Actually, I must have gotten confused, the code that I got was from another site, so I'm not sure why I was asking the question here. Anyway, I'm using a modified version of this Myke's 2 wire LCD interface. I'm using a 74HCT299 in order to provide read/write capability, which actually turns it into a 4 wire interface (but still better than 7).

http://www.rentron.com/Myke1.htm

He has a lot of useful stuff out there. Let me know if you have any insight into my earlier question.

Edited by geogecko

Share this post


Link to post
Share on other sites

Anyone know of a good place to get information on using Microchip's MPLAB Simulator? I am wanting to provide inputs to the simulation, but I don't know exactly how to do that. Actually, I'd like to connect the output pin of a PIC to the input pin of the same PIC. Is there a way to do this in the simulation?

Share this post


Link to post
Share on other sites

If you are interested, I have some working code for the 12F675 to measure and generate servo pulses (assembly). I bet I'm coming a bit late, but anyway if needed it's here.

I use timer1 and its interrupt to get 8us accuracy with very little processor time usage in both cases. Easy to understand, and the accuracy could be improved if needed.

I've written it in a way in which I could easily copy/paste for in new program, as it's something I use nearly in all my PIC projects.

It could be useful also just to understand the interrupts.

Regards,

Kilrah

Share this post


Link to post
Share on other sites

Kilrah.

Yes, I'd be interested. I am currently having a problem with interrupts right now. I'm using the INT pin as an interrupt for the incoming servo pulse (I set it to check for the rising edge, which is when I clear timer 1, and then I set it to check for the falling edge, which is when I save the value of timer 1 to a register). Your code may help me understand what is going on with my project.

By the way, have you ever noticed the 12F675 losing it's flash program before? I've had that occur a couple times now, where the thing seems to stop working, then I reprogram it, and it works again...

What projects do you use your servo pulse code on?

Thanks.

Jason

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
Sign in to follow this  

×