![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) | |
|
Quote:
|
||
|
|
|
|
|
(permalink) | |
|
Quote:
What's the range? Instead of going from 1.0-msec to 2.0-msec would you like to go from 0.8-msec to 2.2-msec? Still an overall 20-msec period? Mike |
||
|
|
|
|
|
(permalink) |
|
Ok, how does this sound?
Here are the steps I was thinking to control 2 servos at once. 1. determine the smaller pulse width for the 2 servos 2. set both pins to high 3. delay the smaller of the 2 pulse widths 4. turn the pin off corresponding to the smaller pulse width 5. subtract the smaller pulse width from the larger pulse width and delay that much 6. repeat for the next set of 2 servos until 8 sets are performed All together the total pulses should be shorter than 20ms. In my pc side code I will control this by setting the min pulse width to .5ms and the max to 2.5ms. Something like this pusedo code: if(delay1 > delay2){ pin1 = 1; pin2 = 1; Delay(delay2); pin2 = 0; Delay(delay1-delay2) pin1 = 0; } else { pin1 = 1; pin2 = 1; Delay(delay1); pin1 = 0; Delay(delay2-delay1) pin2 = 0; } I like this idea because it allows me to keep the interrupt timer in control of the overall period and have smaller or larger pulses. Does anyone forsee a problem with this code? I have a feeling that the extra logic will not effect the times by much (at least not enough to notice). |
|
|
|
|
|
|
(permalink) |
|
That should work but I have one qualifier; you need to account for the case where delay1 = delay 2.
|
|
|
|
|
|
|
(permalink) |
|
I think that should be ok since it is using an if else. If they are equal then it would go into the else block. The second Delay should get passed up. I know there will be a few clock ticks in between there but should that matter much when dealing with millisecond delays?
} else { pin1 = 1; pin2 = 1; Delay(delay1); pin1 = 0; Delay(delay2-delay1) <-----shouldnt wait if they are equal pin2 = 0; } |
|
|
|
|
|
|
(permalink) |
|
I'm kinda confused as to why this stuff is being implemented as busy-waiting loops when the chip (A PIC18F4550, right?) has 4 separate timer/counter sections? It would seem much more reasonable to use a timer interrupt to schedule the transitions accordingly, plus you'd end up with some pretty insane resolution.
- i.e. set TMR1 to -1000, and you'd get an interrupt in 1000 timer ticks. |
|
|
|
|
|
|
(permalink) |
|
hjames,
Because I'm not really sure how to do that. Last edited by HakBot; 17th July 2006 at 09:22 PM. |
|
|
|
|
|
|
(permalink) |
|
Well, think of it as a learning experience - learning how to use all the modules in there is a definite bonus.
Page 133 of the PIC data sheet has some sample code and a sample ISR for a RTC timer where they force TMR1 to 0x8000 every time the interrupt is called - which causes an interrupt in another 0x8000 ticks But in general, just set TMR1 (all 16 bits) 65536 - "# timer ticks" (and since 65536=0, it's just -#ticks), and you'll get an interrupt at that time. Or you can read up on the "capture/compare" stuff and use some of the PWM logic. I can't give you more details without sinking a lot my time (I usually work with the Atmel chips), but I'd be real surprised if it isn't pretty simple. As for structuring the code, I'd probably break it down into a state-machine like representation to keep the ISR simple. At the start of every frame, caclulate all the delays you need, and then enable the interrupts. The ISR would just do three things : 1) load in a new TMR1 value 2) update the ports with some precalculated values 3) decide whether it needs to execute again, or can shut down and disable it's interrupt. |
|
|
|
|
|
|
(permalink) | |
|
Quote:
I think a timer ISR (based on the resolution he needs) and byte counter for each pin to move the servos will work. Just he needs to wait (block the pin) for each servo to settle before he updates the bytes counters. |
||
|
|
|
|
|
(permalink) |
|
I admit I've become very curious about Servos during all the recent discussions. I wouldn't mind 'playing' with one to see how much resolution between 1.0-msecs and 2.0-msecs (or 0.5-msecs and 2.5-msecs) is useful or perceivable.
I too would prefer an assembly language solution using timers and interrupts but I simply don't have time for a new challenge right now (grin). Have fun guys. Mike |
|
|
|
|
|
|
(permalink) |
|
With current mid-priced transmitters and servos, such as Multiplex EVO and Hitec servos, the smallest change you can see empirically (i.e., 1 click on the trim) is about 25 us +/- 5us.
I just completed my previous servo project based on the 628A. For my next project, I would like more (at least 2; 3 preferred) PWM channels. Do you have any experience with the 16F886? Thanks. John |
|
|
|
|
|
|
(permalink) | ||
|
Quote:
Using a 20MHz PIC, and 25uS timer interrupts, it should easily be possible to do this for 16 servos Quote:
Last edited by Nigel Goodwin; 19th July 2006 at 02:09 PM. |
|||
|
|
|
|
|
(permalink) |
|
That's exactly why I used PWM for the servo. The processor is handling several inputs and outputs. It holds servo position very steady while I do other things in the program. The next project will use the second PWM for a more typical, half-bridge motor control at 20KHz with soft start. Hence, my interest in a chip like the 16F886.
Regards, John |
|
|
|
|
|
|
(permalink) |
|
Xor, at the Mikrobasic forum wrote a multiple servo controller program for 8 or 16 servos( dont recall which) in Mikrobasic. Dont know anything about it personally but there was a lot of interest it it.
zkt |
|
|
|
|
|
|
(permalink) | |
|
Quote:
Mike <added> I found it listed as Future Product. How can anyone have any experience with it if it's not available yet (grin)? Last edited by Mike, K8LH; 19th July 2006 at 06:27 PM. |
||
|
|
|