![]() |
![]() |
![]() |
|
|
|||||||
| 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) |
|
Here is my problem:
I need to control 18 servos for a hexapod robot. I need to be able to control all 18 servos simultaneously. I have been looking at the PWM setup, but I am not sure if this would be best, since there are not many channels on each PIC. Option 1: *use 6 PICs with at least 3 PWM outputs (one for each leg) *each leg PIC controlled by master PIC (brain, tells legs what coordinates to move to, also handles sensors (maybe another 10 pins)) Option 2 *use 18F master PIC as brain(sensor, decision handling, gives leg positions to slave PIC) *use one slave PIC with 18 outputs and bit-bang the pins. (receives move direction, stop, body pitch/roll/yaw, etc. modes from master) Option 3 *find a PIC with 18 PWM channels I am hoping some of you have some experience with this, cause I cannot make up my mind as to what would be the better choice. I will be using an 18F series for the brain, since making a crude AI will be easier with C. |
|
|
|
|
|
|
(permalink) |
|
I don't know how useful this will be for you, but might get some ideas from what they did. I pick it up on AVRFreaks yesterday. It controls 20 servos, the source is in 'C', and uses 2 x 4017. I think they used a ATmega16, a 40 pin chip, but only 3 pins go to the 4017s. Just took a brief look, don't know 'C'.
|
|
|
|
|
|
|
(permalink) |
|
It looks like a much simpler design then I need to use. It looks like they are cascading the servos by using the decade counter? I need to be able to control each servo in real time.
Will a mux for the PWM signal work? Or does that signal need to be present on the servo input at all times? |
|
|
|
|
|
|
(permalink) |
|
You can do something similar on the PIC using the CCP module "compare" mode. The following example uses a single 74HC4017 IC and 2 PIC pins for 9 channels (on the 74HC4017 Q1..Q9 output pins). This could be expanded to 18 channels by adding another 74HC4017 driven by the CCP2 pin (and some additional interrupt code).
Code:
static unsigned char Qn = 0;
static unsigned int Qarray [] = { 1500, 1500, 1500, 1500,
1500, 1500, 1500, 1500,
1500, 20000 }; // 800..2200 range
void isr_hi ()
{
/****************************************************************
* K8LH Crazy-8 HiRez Hard 8-channel 74HC4017 Servo Algorithm *
****************************************************************/
if (PIR1bits.CCP1IF == 1) // if CCP1 "compare" interrupt
{
CCPR1H++; // avoid update "match"
CCPR1 += Qarray[Qn]; // update "compare" int value
CCPR1H--; // fix CCPR1H
LATCbits.LATC1 = 0; // clear CCP1 "CLK" line
PIR1bits.CCP1IF = 0; // clear CCP1 interrupt flag
Qarray[9] -= Qarray[Qn++]; // adjust end-of-period off time
if (Qn = 10) // if end-of-period
{ Qn = 0; // reset Qn array index
Qarray[9] = 21000; // reset 20.0-msec period and
LATAbits.LATA0 = 1; // toggle 74HC4017 "CLR" line
LATAbits.LATA0 = 0; // to force Q0 output sync'
}
}
}
Last edited by Mike, K8LH; 5th December 2007 at 01:58 AM. |
|
|
|
|
|
|
(permalink) |
|
Code for 30 servos @ 256 resolution with a single PIC:
http://www.manhattancontrols.com/for...topic.php?t=68 Also, I have a board and superb PC software using a USB PIC to drive the servos: http://www.circuit-ed.com/30-Servo-H...S-P117C10.aspx |
|
|
|
|
|
|
(permalink) | |
|
Quote:
Mike. |
||
|
|
|
|
|
(permalink) | |
|
Quote:
Instead consider using a "standard" (isochronous) soft PWM routine which doesn't destroy the PWM array values. It'll continue to ouput pulses cycle after cycle and allows you to update one or more PWM array values at any time or interval (during your 17.5 msec 'window'). The soft PWM routine also correctly handles PWM array values of 0 (handy for LEDs) since it updates the output port from a shadow register. Code:
clrf PWM ;
setf Shadow ; shadow bits all on
PWM256 movf PWM,W ; PWM counter 0..255
cpfsgt Servo+0 ; servo 0 (0..255) match?
bcf Shadow,0 ; yes, turn off output bit
cpfsgt Servo+1 ;
bcf Shadow,1 ;
cpfsgt Servo+2 ;
bcf Shadow,2 ;
cpfsgt Servo+3 ;
bcf Shadow,3 ;
cpfsgt Servo+4 ;
bcf Shadow,4 ;
cpfsgt Servo+5 ;
bcf Shadow,5 ;
cpfsgt Servo+6 ;
bcf Shadow,6 ;
cpfsgt Servo+7 ;
bcf Shadow,7 ;
movff Shadow,LATB ; update output port
incfsz PWM,F ; bump PWM counter
bra PWM256 ; do it again
Last edited by Mike, K8LH; 5th December 2007 at 01:01 PM. |
||
|
|
|
|
|
(permalink) |
|
Mike,
It doesn't need to make a copy as each servo value is decremented 256 times. I also don't understand why you think the original code would jitter? There would be a slight discrepancy between the first and last servo but it could be easily fixed (have a similar line of code to set the bits initially) and wouldn't cause jitter anyway. Mike. |
|
|
|
|
|
|
(permalink) |
|
Oops, I missed that (each array element decremented 256 times). Sorry.
But as far as jitter, he's turning on all of the port LAT bits at the same time at the beginning of the code but turning off the bits one group at a time with many cycles difference between groups. I don't see the "easy fix" you mention without using shadow registers. Please enlighten me some more? Thanks. Last edited by Mike, K8LH; 5th December 2007 at 02:18 PM. |
|
|
|
|
|
|
(permalink) |
|
The easy fix is to turn the bits on with similar code to in the PWM loop but with just a bsf followed by a nop for each output. This would be placed before the 500uS delay.
Mike. |
|
|
|
|
|
|
(permalink) |
|
I don't understand. Can you show me?
Also, that code doesn't seem capable of handling Servo PWM values of 0 for the minimum 500 msec timing. |
|
|
|
|
|
|
(permalink) |
|
Worst case is if the last servo pin in the decfsz array is 0 movement and nearly 1/256 resolution time has passed in the On state. Since 500us of delay at the beginning is an arbitrary value for this example, there is room for adjustment at this point to fine tune out any real physical servo movement for a 0 servo at the beginning of the routine. Maybe I should more accurately say that the resolution is 255 with a spare do nothing loop at the beginning.
|
|
|
|
|
|
|
(permalink) |
|
The code to turn on the outputs would be,
Code:
bsf PORTA.0 nop bsf PORTA.1 nop bsf PORTA.2 nop bsf PORTA.3 nop bsf PORTA.5 nop bsf PORTB.0 nop Then would come the 500uS delay. Then would come the loop that consist of, Code:
decfsz _servo+0, 1,0
iorlw 1
decfsz _servo+1, 1,0
iorlw 2
decfsz _servo+2, 1,0
iorlw 4
decfsz _servo+3, 1,0
Mike. |
|
|
|
|
|
|
(permalink) |
|
I do have other code where I incremented all the servo values to make 0 = 0:
Code:
i = 30 FSR0ptr = @servo Do inc(POSTINC0) dec(i) Loop Until i = 0 |
|
|
|
|
|
|
(permalink) |
|
Warren;
I apologize. There really is no jitter other than the normal plus or minus 1 cycle jitter associated with interrupt entry. All of the servo pulses maintain the same timing from 20 msec cycle to 20 msec cycle. It's just pulse width timing that's off a bit; Servo 00 (LATA) = 1 ---> 501.2 usecs Servo 05 (LATB) = 1 ---> 503.0 usecs Servo 13 (LATC) = 1 ---> 504.4 usecs Servo 19 (LATD) = 1 ---> 506.2 usecs No jitter... Mike, Yes, of course. Now that's a simple and elegant and (embarrassingly) intuitive solution. Of course you'd need some extra 'nops' to account for those instructions writing the the LATx registers too. Then modify that delay_us(500) statement to take into account the 12 cycles that occur before writing LATA and you've eliminated the pulse width timing problems... Last edited by Mike, K8LH; 7th December 2007 at 10:33 AM. |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| 555 servo controller? can get them working | lompa | General Electronics Chat | 9 | 31st May 2007 06:24 AM |
| Help required with servo motor controller | mayhem | Robotics Chat | 3 | 26th May 2006 04:21 PM |
| Auto servo controller, need help with the 555 | linuxglobal | General Electronics Chat | 2 | 20th April 2006 03:52 PM |
| looking for servo controller circuit diagram using switch ? | calico | Micro Controllers | 49 | 27th February 2006 01:35 AM |
| Help me start, making a servo controller for motorcycle use. | motoracer | General Electronics Chat | 4 | 11th November 2003 10:29 PM |