![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Each '4017 is driven directly by a seperate CCP module CCPx pin and so each '4017 maintains its own 20 msec period. Each '4017 will get 10 "compare" interrupts per 20 msec period. And servicing the interrupt is not critical with these hardware solutions compared to the 'soft' solutions. You could disable interrupts for a hundred microseconds or more at a time without affecting performance. I modified the code to show one way that you might implement dual 74HC4017's. Please note the interrupt code outputs a pulse on the 74HC4017 Q1 through Q9 outputs that corresponds to the ChanA[0] through ChanA[8] pulse width array elements. The interrupt code uses the value in the ChanA[9] element for the Servo period "off time" (20 msecs minus the cumulative pulse on times). Code: static unsigned char Qa = 0;
static unsigned char Qb = 0;
static unsigned int ChanA [] = { 1500, 1500, 1500, 1500,
1500, 1500, 1500, 1500,
1500, 20000 };
static unsigned int ChanB [] = { 1500, 1500, 1500, 1500,
1500, 1500, 1500, 1500,
1500, 20000 };
void isr_hi ()
{
/****************************************************************
* K8LH Crazy-18 Hi-Rez 18-chan Dual 74HC4017 Servo Algorithm *
****************************************************************/
if (PIR1bits.CCP1IF == 1) // if CCP1 "compare" interrupt
{
CCPR1H++; // avoid false update "match"
CCPR1 += ChanA[Qa]; // update "compare" int value
CCPR1H--; // fix CCPR1H
LATCbits.LATC2 = 0; // clear CCP1 "CLK" line
PIR1bits.CCP1IF = 0; // clear CCP1 interrupt flag
ChanA[9] -= ChanA[Qa++]; // adjust end-of-period off time
if (Qa = 10) // if end-of-period
{ Qa = 0; // reset Qa array index
ChanA[9] = 20000; // reset 20.0-msec period and
LATAbits.LATA0 = 1; // toggle 74HC4017 "CLR" line
LATAbits.LATA0 = 0; // to force Q0 output sync'
}
}
if (PIR2bits.CCP2IF == 1) // if CCP2 "compare" interrupt
{
CCPR2H++; // avoid false update "match"
CCPR2 += ChanB[Qb]; // update "compare" int value
CCPR2H--; // fix CCPR2H
LATCbits.LATC1 = 0; // clear CCP2 "CLK" line
PIR2bits.CCP2IF = 0; // clear CCP2 interrupt flag
ChanB[9] -= ChanB[Qb++]; // adjust end-of-period off time
if (Qb = 10) // if end-of-period
{ Qb = 0; // reset Qb array index
ChanB[9] = 20000; // reset 20.0-msec period and
LATAbits.LATA1 = 1; // toggle 74HC4017 "CLR" line
LATAbits.LATA1 = 0; // to force Q0 output sync'
}
}
} Last edited by Mike, K8LH; 7th December 2007 at 11:24 AM. | |
| |
| | (permalink) | |
| Quote:
BTW, my 16-channel dual 74HC238 CCP 'PWM' hardware solution is the only one discussed so far with absoluty 0% pulse width jitter and 0% period jitter. Mike Last edited by Mike, K8LH; 6th December 2007 at 09:39 AM. | ||
| |
| | (permalink) |
| I will have to look over your code some more then. I just need to find a non-inverting 4-16 demux (two for 18 channel, using one for each robot side.), which is looking impossible. Maybe I will just have to get an inverter for it. I have not programmed a PIC with C yet, so I am having a hard time with the code. I gotta start looking at some tutorials. Thanks. | |
| |
| | (permalink) | |
| Quote:
In your opening post you said you'd be programming in C. Whould you like to see that code in Assembler or BASIC instead? | ||
| |
| | (permalink) |
| Mike, I should have realised that you would use 2 CCP/PWM modules. I had it in my head that the interrupts would somehow collide no matter what you did, this of course doesn't matter when it's hardware. This would be Ambient's best solution at the moment. I also missed your 238 solution which, as you say, will give 16 jitter free outputs. My apologies, I got carried away with the other solution. I assume the 2 x 4-16 demultiplexers would be to service 9 servos per PWM output. Wouldn't this give 18 jitter free outputs? Mike. | |
| |
| | (permalink) | |
| Quote:
Here is my solution to the USART reading while running 30 servos: Code: While FSR2ptr < lastservobufaddr ' FSR2 is RX servobuffer
Do
Loop Until PIR1.RCIF = 1 ' wait for new RX byte
While TMR1H = 255 ' avoid trasfer if close to interrupt
Wend
If PIR1.RCIF = 1 Then POSTINC0 = RCREG End If ' load RX byte.. when 30 bytes move on
Wend
FSR2ptr = @servobuffer ' reset RX buffer
FSR1ptr = @servobuffer ' setup tranfer of RX array to
FSR0ptr = @servo ' servo work array
While FSR1ptr < lastservobufaddr
POSTINC0 = inc(POSTINC1) ' transfer RX buffer to work values.. add 1
Wend Code: sub procedure interrupt
LATA = Not(LATA) ' turn on all servos on PortA
LATB = Not(LATB) ' turn on all servos on PortB
LATC = Not(LATC) ' turn on all servos on PORTC
LATD = Not(LATD) ' turn on all servos on PortD
LATE = Not(LATE) ' turn on all servos on PORTE
pos = 0 ' 256 counts.. rollover to original value
ASM
initdelay: ' approx 500us delay using timer1 counts
movlw 5 ' prescaler=4, 2.5 counts / microsecond
delayloop:
btfsc PIR1, 5,0 ' check USART RX buffer
movff RCREG, POSTINC2 ' move RX byte into servobuffer
cpfseq TMR1H, 0 ' timer1 = 1280?
bra delayloop
servomask: ' VERY efficient PWM masking routine
movlw 0
decfsz _servo+0, 1,0
iorlw 1
decfsz _servo+1, 1,0 | ||
| |
| | (permalink) |
| I was planning on using an 18F and C for the AI and sensors, while using a 16F and assembly for the servo control. The 18F would have to just send the servo control PIC the 2d vector to move in, and pitch...etc data. Unless one PIC can handle all of it? The two 4-16 demux would just be for sending the PWM signals to each servo, with each controlling 9. Just like with your 3-8 demux for your 16 servos. Could I actually get away with using a single 18F clocked at 20 MHz? I would probably have 10 or so sensors: IR body heat, ultrasonic distance sensor, 2-3 mics, current sensor (for stalled servo detection and touch detection), temp sensors. I want this robot to be able to navigate obstacles on its own using these sensors. Last edited by Ambient; 6th December 2007 at 07:04 PM. | |
| |
| | (permalink) |
| One option that I just thought of: Use 18F for "brain", and when it needs to update a servos position, it simply sends it to the servo control PIC. The servo control PIC would simply act as a latch of sorts. It would just keep telling the servos their position until it got an update on a certain servos position from the brain. This would really free up the 18F, as it wouldn't have to refresh the servos positions unless it was moving. | |
| |
| | (permalink) |
| As this is for a hexapod (if I remember correctly?) you could have one slave PIC per leg!. | |
| |
| | (permalink) |
| Well there is enough room for 1 PIC each leg, that's for sure. The chassis is huge! I just unpacked it, the usable area for electronics is around 8". Very spacious. But I would like to avoid using more PICs than I need to. One 16F690 would be plenty to handle each side, as well as the current sensors on each leg. | |
| |
| | (permalink) |
| Can you post a few pics or a links to pics so we can have a gander at it. | |
| |
| | (permalink) |
| this is the pic on the manufacturer website, they have vids also: http://lynxmotion.com/images/hi-res/ch3r01.jpg I do not have it assembled at the moment, it is a Christmas present so I have to wait | |
| |
| | (permalink) |
| One other question: If I use a 6V supply for the servos (5-cell NiMH) and a 5V regulator for the PIC, will the PWM servo signal still work properly? Does the PWM voltage need to match the supply voltage of the servo? I can run everything on a 5V buck-boost ad use a huge Lithium cell. | |
| |
| | (permalink) | |
| Quote:
| ||
| |
| | (permalink) |
| I mean 5V on the servo input signal from the PIC, with 6V to the servo power. | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| 555 servo controller? can get them working | lompa | General Electronics Chat | 9 | 31st May 2007 07:25 AM |
| Help required with servo motor controller | mayhem | Robotics Chat | 3 | 26th May 2006 05:21 PM |
| Auto servo controller, need help with the 555 | linuxglobal | General Electronics Chat | 2 | 20th April 2006 04:53 PM |
| looking for servo controller circuit diagram using switch ? | calico | Micro Controllers | 49 | 27th February 2006 02:36 AM |
| Help me start, making a servo controller for motorcycle use. | motoracer | General Electronics Chat | 4 | 11th November 2003 11:29 PM |