Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Thread Tools Display Modes
Old 5th December 2007, 03:49 PM   (permalink)
Default

Mike,

You don't have to apologize. Your evaluations are always worthy of note. I didn't get involved with PIC's until a couple years ago, so some of my code can certainly use some refinement. I would now write the reload of the Timer by adding the 20ms number... a trick I learned a few months ago and before I wrote the PIC RTC examples for SF.

By the way, some of your ideas have turned out to be an inspiration for some new stuff I'm working on.
wschroeder is offline   Reply With Quote
Old 5th December 2007, 04:08 PM   (permalink)
Default

Ok guys, I'm impressed.

Between the two of you you've shown me that a jitter-free lo-rez 'soft' solution with more than 8 channels (which has eluded me) is feasable and probably practical (just not in the current form of Warren's demo')

Now, could you build interface code that would allow single channel serial updates instead of that 30 byte serial update? Are there any pins left over to allow using one pin for hardware handshaking to the host to signal when we're sitting in that 17.5 msec 'window' (where we can use the serial port) instead of sending that flag character?

Warren,

I learn a lot by disecting code and your code is no exception. In this case, decrementing the pwm array values 256 times is better because it would work with 16F' devices too.
Mike, K8LH is offline   Reply With Quote
Old 5th December 2007, 05:06 PM   (permalink)
Default

Quote:
Originally Posted by Ambient
Will a mux for the PWM signal work? Or does that signal need to be present on the servo input at all times?
You need to provide each Servo with a pulse of 1000 to 2000 usecs duration every 20 msecs.

You can use the CCP module PWM mode but you need to break up the 20 msec servo period into smaller faster PWM frames in order to maintain usable hi-rez pulse width resolution.

You can multiplex the PWM output signal by using it to drive one of the enable lines on a 74HC238 IC. Change the address lines on the 74HC4017 to direct a 1000 to 2000 usec PWM pulse to one of the eight 74HC238 outputs every 2500 usec interval.

While this provides a wonderful hi-rez no-jitter solution, it will only provide you with 16 servo outputs using two 74HC238 ICs and 5 pins (CCP1, CCP2, and 3 pins for decoder address lines). The following example is for 4 MHz (prescaler 1:1) or 16 MHz (prescaler 4:1) clocks.

Code:
/*                                                               *
 *  array1 and array2 elements hold Servo pulse width values     *
 *  ranging from 3000..9000 in 250-nsec 'ticks' representing an  *
 *  extended pulse width range of 750-usecs to 2250-usecs        *
 *                                                               */
static unsigned int array1 [] = { 6000, 6000, 6000, 6000,
                                  6000, 6000, 6000, 6000 };
static unsigned int array2 [] = { 6000, 6000, 6000, 6000,
                                  6000, 6000, 6000, 6000 };

/*****************************************************************
 *  K8LH 16-Channel 74HC238 Hi-Rez 'PWM' Servo Algorithm Driver  *
 *****************************************************************/
#pragma interrupt isr_hi

void isr_hi ()
{ if(PIR1bits.TMR2IF)
  { PIR1bits.TMR2IF = 0;            // clear TMR2 interrupt flag
   /**************************************************************
    *                                                            *
    *  setup 74HC238 address lines and our work variables for    *
    *  the next servo channel interval during the final (10th)   *
    *  frame of the current servo channel interval (the final    *
    *  frame in each interval will always have a 0% duty cycle   *
    *  and all 74HC238 outputs are 'off' so it will be safe to   *
    *  change the address lines)                                 *
    *                                                            */
    if(frame == 10)             // 10 PWM frames/Servo interval
    { frame = 0;                // reset PWM frame counter
      select %= 8;              // 8 Servo intervals/20-msec cycle
      pulse1 = array1[select];
      pulse2 = array2[select];
      PORTB = (PORTB & 0b11111000) | select;
      select++;                 // bump for next interval
    }
    frame++;                    // bump for next interrupt
   /**************************************************************
    *  setup CCP1 PWM duty cycle for next 250-usec PWM 'frame'   *
    *                                                            */
    if(pulse1 > 1000)           // if pulse1 > 250-usecs
    { CCPR1L = 250;             // do a 100% duty cycle frame
      pulse1 -= 1000;           // subtract 250-usecs
    }
    else                        // do a variable or 0% frame
    { CCP1CONbits.CCP1Y = (pulse1 & 1);
      CCP1CONbits.CCP1X = (pulse1 & 2);
      CCPR1L = (pulse1 >>= 2);
      pulse1 = 0;               // remaining frames are %0
    }

   /**************************************************************
    *  setup CCP2 PWM duty cycle for next 250-usec PWM 'frame'   *
    *                                                            */
    if(pulse2 > 1000)           // if pulse2 > 250-usecs
    { CCPR2L = 250;             // do a 100% duty cycle frame
      pulse2 -= 1000;           // subtract 250-usecs
    }
    else                        // do a variable or 0% frame
    { CCP2CONbits.CCP2Y = (pulse1 & 1);
      CCP2CONbits.CCP2X = (pulse1 & 2);
      CCPR2L = (pulse2 >>= 2);
      pulse2 = 0;               // remaining frames are %0
    }
  }
}
If 16 channels isn't enough and a software or hardware 18 channel solution seems like too much baggage, you might consider using a couple 9 channel "slaves" connected via RS232. The drawing below shows 8 channels but it could easily be changed to include the 74HC4017 Q9 output for 9 channels with an 800..2200 usec range for each servo.


Last edited by Mike, K8LH; 5th December 2007 at 06:05 PM.
Mike, K8LH is offline   Reply With Quote
Old 5th December 2007, 05:11 PM   (permalink)
Default

An interesting proposition for the communication. The TX pin could be used as a hardware CTS I suppose and then turn on USART/UART for RX only on the RX pin. I don't know if this is what you're inferring. Or, are you thinking of a more compact method of transmitting the data?

I'm referring to your previous posting above.... not the last post.

Last edited by wschroeder; 5th December 2007 at 05:13 PM.
wschroeder is offline   Reply With Quote
Old 5th December 2007, 05:50 PM   (permalink)
Default

You've got it. Could hardware handshaking eliminate the requirement for the Host to watch for that flag character. Just to simplify host requirements...
Mike, K8LH is offline   Reply With Quote
Old 5th December 2007, 06:15 PM   (permalink)
Default

Brilliant piece of code that 30 servo, I'll put it in one of the Junebug / Firefly tutorials.
The more I work with 18F PICs (in assembly) the less I want to use the 14bit core PICs.
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com
blueroomelectronics is offline   Reply With Quote
Old 5th December 2007, 08:17 PM   (permalink)
Default

So it might just work then, for 10 channel max with one pin, using soft PWM. From what I have seen, the PW is 10% max required for full travel. So practically, I can get 9 channels max on one pin using a mux. Does that sound like it will work?

Also, it looks like I can do it all with one small PIC, with an 18F and C code running the sensors and "brain". Or would it still be best to use the PWM pins and use one PIC per leg (some 16F's have pins to use in PWM mode)?

Thanks for the help guys.

Last edited by Ambient; 5th December 2007 at 08:46 PM.
Ambient is offline   Reply With Quote
Old 5th December 2007, 09:49 PM   (permalink)
Default

It would appear to be possible with almost any PIC.
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com
blueroomelectronics is offline   Reply With Quote
Old 6th December 2007, 12:13 AM   (permalink)
Default

Quote:
Originally Posted by Mike, K8LH
Now, could you build interface code that would allow single channel serial updates instead of that 30 byte serial update? Are there any pins left over to allow using one pin for hardware handshaking to the host to signal when we're sitting in that 17.5 msec 'window' (where we can use the serial port) instead of sending that flag character?
Mike,

There is no need to worry about the serial communication. At 19200 baud a byte can arrive each 5mS, this fact combined with the 2 byte hardware buffer means that overflow cannot occur and, consequently, no handshake is required. You could simply send something like 128+servo number, high nibble/16, low nibble.

Edit, I'm out by a factor of 10 as pointed out by Warren below.

Mike.

Last edited by Pommie; 6th December 2007 at 01:35 AM.
Pommie is online now   Reply With Quote
Old 6th December 2007, 01:24 AM   (permalink)
Default

Quote:
Originally Posted by Pommie
There is no need to worry about the serial communication. At 19200 baud a byte can arrive each 5mS,
Make that about every 500uS... 10 Bytes can arrive in a bit over 5mS @ 19200 baud.
wschroeder is offline   Reply With Quote
Old 6th December 2007, 01:34 AM   (permalink)
Default

Whoops, you are correct, I must remember to keep track of that decimal point in future.

Mike.
Pommie is online now   Reply With Quote
Old 6th December 2007, 01:58 AM   (permalink)
Default

You could use the indirect register as a fifo.

Replace
Code:
	iorlw	4 
	andwf	LATE, 1,0 
	nop 
	nop 
	nop 
	nop 
	nop 
	incfsz	_pos, 1,0 
	bra	$-76
With
Code:
	iorlw	4		 
	andwf	LATE, 1,0	
	btfss	PIR1,RCIF	;byte recieved
	goto	DoneRS		;no, so go do a delay
	movfw	RXREG		;yes, get it and
	movwf	POSTINC0	;store it in buffer
	bcf	PIR1,RCIF	;clr IF
CarryOn	incfsz	_pos, 1,0		
	bra	$-76		


DoneRS	goto	CarryOn		;just delay and jump back
At the end of the interrupt, the fifo could be emptied into a more usable array and the FSR register restored.

I'm not sure how usable the FSR register is with Basic but it should be fine as long as it is saved and restored in the asm part.

Mike.

Last edited by Pommie; 6th December 2007 at 03:38 AM.
Pommie is online now   Reply With Quote
Old 6th December 2007, 03:44 AM   (permalink)
Default

Tying up the processor for 2500 usecs without being able to cache serial data in a circular buffer as it's coming in is a potentially big problem, in my opinion.

Mike,

Just spotted your idea. That would actually work quite well and Main could easily determine the number of characters in the buffer by the value of FSR0L. BTW, you don't need the bcf PIR1,RCIF instruction as it's cleared automatically when you pull a character from RCREG...

Last edited by Mike, K8LH; 6th December 2007 at 03:49 AM.
Mike, K8LH is offline   Reply With Quote
Old 6th December 2007, 03:55 AM   (permalink)
Default

Quote:
Originally Posted by Mike, K8LH
Tying up the processor for 2500 usecs without being able to cache serial data in a circular buffer as it's coming in is a potentially big problem, in my opinion.
Mike,

Here is my attempt at caching the serial data.

I have guessed the basic syntax and how variables are accessed.

Code:
program SERVO30_18F452 
'********************************************************************** 
'******                                                          ****** 
'******    30 Servo Driver @ 256 Positions using P18 @ 40MHz     ****** 
'******            by W. Schroeder on July 22, 2006              ****** 
'******   REVISED on Sept 19, 2006..added USART & code tweaks    ****** 
'******   Compiled with mikroBASIC 5.0.0.1 & Tested on 18F452    ****** 
'******                                                          ****** 
'******      Servo routines use only ~2.5ms of 20ms cycle        ****** 
'******   This ensures enough time for changing servo values     ****** 
'******                                                          ****** 
'******   USART is used for communicating new servo values to    ****** 
'******   the PIC.  It is important that the PIC initiate this   ****** 
'******   communication with the PC.  Therefore, PC software     ****** 
'******   must regularly scan the Comm Port for receipt of a     ****** 
'******   an initiate-communication signal.  The PC will send    ****** 
'******   exactly 30 bytes which represent the servo values.     ****** 
'******                                                          ****** 
'********************************************************************** 
'       These are the port pin assignments for the servo array: 
'            servo[0]- PORTA.0 
'            servo[1]- PORTA.1 
'            servo[2]- PORTA.2 
'            servo[3]- PORTA.3 
'            servo[4]- PORTA.5  <-- note: skips RA4 open-drain output 
'            servo[5]- PORTB.0 
'            servo[6]- PORTB.1 
'            servo[7]- PORTB.2 
'            servo[8]- PORTB.3 
'            servo[9]- PORTB.4 
'            servo[10]-PORTB.5 
'            servo[11]-PORTB.6 
'            servo[12]-PORTB.7 
'            servo[13]-PORTC.0 
'            servo[14]-PORTC.1 
'            servo[15]-PORTC.2 
'            servo[16]-PORTC.3 
'            servo[17]-PORTC.4 
'            servo[18]-PORTC.5 
'            servo[19]-PORTD.0 
'            servo[20]-PORTD.1 
'            servo[21]-PORTD.2 
'            servo[22]-PORTD.3 
'            servo[23]-PORTD.4 
'            servo[24]-PORTD.5 
'            servo[25]-PORTD.6 
'            servo[26]-PORTD.7 
'            servo[27]-PORTE.0 
'            servo[28]-PORTE.1 
'            servo[29]-PORTE.2 
'******************************************************************** 

dim aa, pos, tmp as byte 
dim tmr as word 
dim servo as byte[30] 
dim saveFSR as byte
dim buffer as byte[10]
dim bufferlen as byte
dim bufferpoint as byte
dim position as byte

sub procedure interrupt 
    LATA = 63                                  ' turn on all servos on PortA 
    LATB = 255                                 ' turn on all servos on PortB 
    LATC = 63                                  ' turn on all servos on PORTC 
    LATD = 255                                 ' turn on all servos on PortD 
    LATE = 7                                   ' turn on all servos on PORTE 
    pos = 0                                    ' manage 8 outputs with 256 positions each 
    delay_us(500) 
          ASM                                  ' VERY efficient PWM masking routine 
            movfw	FSR0
            movwf	saveFSR
            movlw	_buffer		       'maybe this should be &buffer
            movwf	FSR0                   'so FSR points to buffer
                                               'not sure how banking works here
            movlw     0
            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 
            iorlw     8 
            decfsz    _servo+4, 1,0 
            iorlw     32 
            andwf     LATA, 1,0 
            movlw     0 
            decfsz    _servo+5, 1,0 
            iorlw     1 
            decfsz    _servo+6, 1,0 
            iorlw     2 
            decfsz    _servo+7, 1,0 
            iorlw     4 
            decfsz    _servo+8, 1,0 
            iorlw     8 
            decfsz    _servo+9, 1,0 
            iorlw     16 
            decfsz    _servo+10, 1,0 
            iorlw     32 
            decfsz    _servo+11, 1,0 
            iorlw     64 
            decfsz    _servo+12, 1,0 
            iorlw     128 
            andwf     LATB, 1,0 
            movlw     0 
            decfsz    _servo+13, 1,0 
            iorlw     1 
            decfsz    _servo+14, 1,0 
            iorlw     2 
            decfsz    _servo+15, 1,0 
            iorlw     4 
            decfsz    _servo+16, 1,0 
            iorlw     8 
            decfsz    _servo+17, 1,0 
            iorlw     16 
            decfsz    _servo+18, 1,0 
            iorlw     32 
            andwf     LATC, 1,0 
            movlw     0 
            decfsz    _servo+19, 1,0 
            iorlw     1 
            decfsz    _servo+20, 1,0 
            iorlw     2 
            decfsz    _servo+21, 1,0 
            iorlw     4 
            decfsz    _servo+22, 1,0 
            iorlw     8 
            decfsz    _servo+23, 1,0 
            iorlw     16 
            decfsz    _servo+24, 1,0 
            iorlw     32 
            decfsz    _servo+25, 1,0 
            iorlw     64 
            decfsz    _servo+26, 1,0 
            iorlw     128 
            andwf     LATD, 1,0 
            movlw     0 
            decfsz    _servo+27, 1,0 
            iorlw     1 
            decfsz    _servo+28, 1,0 
            iorlw     2 
            decfsz    _servo+29, 1,0 
            iorlw     4 
            andwf     LATE, 1,0 
            btfsz     PIR1,RCIF
            goto      DoneRS
            movfw     RXREG
            movwf     POSTINC0
            bcf       PIR1,RCIF
CarryOn     incfsz    _pos, 1,0 
            bra       $-76 

            movlw     _buffer
            subfw     FSR0,W		;W=FSR0-&buffer = len received
            movwf     _bufferlen
            movfw     saveFSR		;restore FSR
            movwf     FSR0


          END ASM                              ' these routines have used ~2500us to this point 
    TMR0H= Hi(-5438)                           ' balance of time for 20ms cycle (=17.5ms) 
    TMR0L = -5438 
    INTCON.TMR0IF = 0                          ' clear interrupt flag 
    aa = 1 
end sub 

sub procedure _init 
   LATA = 0 
   LATB = 0 
   LATC = 0 
   LATD = 0 
   LATE = 0 
   TRISA = 0 
   TRISB = 0 
   TRISC = 0 
   TRISD = 0 
   TRISE = 0 
   ADCON1 = 7 
   T0CON = %00000100                           ' prescaler = 32 or 3.2us per increment 
   TMR0H = -2                                  ' load high byte first 
   TMR0L = 0                                   ' load low byte second 
   INTCON = %10100000                          ' Timer0 Interrupt Enabled and Flag Cleared 
   T0CON.7 = 1                                 ' Timer0 On 
   aa = 0 
end sub 

sub function getRS232 as byte
'this relies on the buffer being flushed before another interrupt comes along
dim temp as int
    temp=-1
    While temp=-1
        if bufferlen<>0 then                   'any bytes in buffer
            temp=buffer[bufferpoint]
            bufferpoint=bufferpoint+1
            if bufferpoint=bufferlen then      'read all bytes in buffer?
                bufferpoint=0
                bufferlen=0
            endif
        else
            aa=0                               'clear the interrupt flag
            ASM
            btfss PIR1,RCIF                    'byte available
            goto  NoRS232                      'no carry on
            bcf   INTCON,7                     'dissable interrupts - can't see a way around this
            movfw aa                           'has an interrupt occured and stolen our data
            btfss STATUS,Z                     'if so,
            goto  NoRS232                      'go around the outer loop and get it from the buffer
            movfw RXREG                        'get byte
            bsf   INTCON,7                     'reenable interrupts
            movwf _temp                        'byte to return
            clrf  _temp+1                      'ensure temp <>-1
NoRS232     bsf	  INTCON,7                     'needed for when goto (above) executed
            END ASM
        endif
    Wend
end sub

main: 
  _init 
  USART_Init(19200)                            ' 19200 should be minimum speed...faster is better 
                                               ' communicate with PC every 20ms 
    While true
	do
            tmp=getRS232
	loop until tmp>127                     'wait for servo number
	tmp=tmp & 127
	position = getRS232*16                 'get servo position
	position = position + getRS232
        servo[tmp] = position                  ' store servo value 
    Wend 

end.
Mike.
Edit, Mike, I couldn't find a way around disabling interrupts. Have you any ideas?

Edit2, changed code.

Last edited by Pommie; 6th December 2007 at 04:12 AM.
Pommie is online now   Reply With Quote
Old 6th December 2007, 04:00 AM   (permalink)
Default

This is untested right now, but it should allow simple USART RX source at any baudrate (maybe 115K should be the upper limit). The only stipulation is that the PC starts communication after the PIC has been started.

It's written presently in mikroBasic and will compile with the free version:

Code:
program SERVO30_USART

'**********************************************************************
'******                                                          ******
'******    30 Servo Driver @ 256 Positions using P18 @ 40MHz     ******
'******            by W. Schroeder on July 22, 2006              ******
'******                                                          ******
'******   REVISED on Sept 19, 2006..added USART & code tweaks    ******
'******   Compiled with mikroBASIC 5.0.0.1 & Tested on 18F452    ******
'******                                                          ******
'******   REVISED on Dec 5, 2007.. added USART for any Baud      ******
'******   Compiled with mikroBASIC 6.0 & Tested on 18F452        ******
'******                                                          ******
'******      Servo routines use only ~2.5ms of 20ms cycle        ******
'******      USART at any baudrate to change servo values        ******
'******                                                          ******
'**********************************************************************
'       These are the port pin assignments for the servo array:
'            servo[0]- PORTA.0
'            servo[1]- PORTA.1
'            servo[2]- PORTA.2
'            servo[3]- PORTA.3
'            servo[4]- PORTA.5
'            servo[5]- PORTB.0
'            servo[6]- PORTB.1
'            servo[7]- PORTB.2
'            servo[8]- PORTB.3
'            servo[9]- PORTB.4
'            servo[10]-PORTB.5
'            servo[11]-PORTB.6
'            servo[12]-PORTB.7
'            servo[13]-PORTC.0
'            servo[14]-PORTC.1
'            servo[15]-PORTC.2
'            servo[16]-PORTC.3
'            servo[17]-PORTC.4
'            servo[18]-PORTC.5
'            servo[19]-PORTD.0
'            servo[20]-PORTD.1
'            servo[21]-PORTD.2
'            servo[22]-PORTD.3
'            servo[23]-PORTD.4
'            servo[24]-PORTD.5
'            servo[25]-PORTD.6
'            servo[26]-PORTD.7
'            servo[27]-PORTE.0
'            servo[28]-PORTE.1
'            servo[29]-PORTE.2
'********************************************************************

const T1_20ms as word = 65536-50000+6      ' 20ms + stop timer1 stop compensation
dim pos as byte
dim servo as byte[30]
dim servobuffer as byte[30]
dim lastservobufaddr as word
dim T1 As word absolute $FCE

sub procedure interrupt
    LATA = 63                              ' turn on all servos on PortA
    LATB = 255                             ' turn on all servos on PortB
    LATC = 63                              ' turn on all servos on PORTC
    LATD = 255                             ' turn on all servos on PortD
    LATE = 7                               ' turn on all servos on PORTE
    pos = 0                                ' 256 counts.. rollover to original value
    delay_us(500)                          ' 0 position delay; adjust to suit needs
          ASM                              ' VERY efficient PWM masking routine
             movlw     0
             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
             iorlw     8
             decfsz    _servo+4, 1,0
             iorlw     32
             andwf     LATA, 1,0
             movlw     0
             decfsz    _servo+5, 1,0
             iorlw     1
             decfsz    _servo+6, 1,0
             iorlw     2
             decfsz    _servo+7, 1,0
             iorlw     4
             decfsz    _servo+8, 1,0
             iorlw     8
             decfsz    _servo+9, 1,0
             iorlw     16
             decfsz    _servo+10, 1,0
             iorlw     32
             decfsz    _servo+11, 1,0
             iorlw     64
             decfsz    _servo+12, 1,0
             iorlw     128
             andwf     LATB, 1,0
             movlw     0
             decfsz    _servo+13, 1,0
             iorlw     1
             decfsz    _servo+14, 1,0
             iorlw     2
             decfsz    _servo+15, 1,0
             iorlw     4
             decfsz    _servo+16, 1,0
             iorlw     8
             decfsz    _servo+17, 1,0
             iorlw     16
             decfsz    _servo+18, 1,0
             iorlw     32
             andwf     LATC, 1,0
             movlw     0
             decfsz    _servo+19, 1,0
             iorlw     1
             decfsz    _servo+20, 1,0
             iorlw     2
             decfsz    _servo+21, 1,0
             iorlw     4
             decfsz    _servo+22, 1,0
             iorlw     8
             decfsz    _servo+23, 1,0
             iorlw     16
             decfsz    _servo+24, 1,0
             iorlw     32
             decfsz    _servo+25, 1,0
             iorlw     64
             decfsz    _servo+26, 1,0
             iorlw     128
             andwf     LATD, 1,0
             movlw     0
             decfsz    _servo+27, 1,0
             iorlw     1
             decfsz    _servo+28, 1,0
             iorlw     2
             decfsz    _servo+29, 1,0
             iorlw     4
             andwf     LATE, 1,0
             nop
             btfsc     PIR1, 5,0           ' check USART RX buffer
             movff     RCREG, POSTINC2     ' move RX byte into servobuffer
             nop
             incfsz    _pos, 1,0
             bra       $-76                ' loop total of 20224 cycles = 2.02ms
          END ASM
    T1CON.TMR1ON = 0                       ' stop timer1
    T1 = T1 + T1_20ms                      ' reload timer1
    T1CON.TMR1ON = 1                       ' restart timer1
    PIR1.TMR1IF = 0                        ' clear interrupt flag
end sub

sub procedure _init
   LATA = 0
   LATB = 0
   LATC = 0
   LATD = 0
   LATE = 0
   TRISA = 0
   TRISB = 0
   TRISC = 0
   TRISD = 0
   TRISE = 0
   ADCON1 = 7                              ' disable ADC's
   lastservobufaddr = @servobuffer + 30
   INTCON = 192                            ' enable GIE & PEIE
   T1CON = 32                              ' prescaler=4, timer off
   T1 = 0                                  ' load Timer1
   PIE1.TMR1IE = 1                         ' enable Timer1 Interrupt
   PIR1.TMR1IF = 0                         ' clear Timer1 Interrupt Flag
   T1CON.TMR1ON = 1                        ' start Timer1
end sub

main:
  _init
  USART_Init(115200)                       ' any baudrate is permissible
  FSR0ptr = @servo
  While FSR0ptr < (@servo + 30)            ' initialize all servo values to 0 position
     POSTINC0 = 1
  Wend
  FSR2ptr = @servobuffer
  While true

     While FSR2ptr < lastservobufaddr      ' FSR2 is RX servobuffer
        Do
        Loop Until PIR1.RCIF = 1           ' wait for new RX byte
        POSTINC2 = RCREG                   ' 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
     
  Wend
end.

Last edited by wschroeder; 6th December 2007 at 04:05 AM.
wschroeder is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes


Similar Threads
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



All times are GMT. The time now is 11:11 PM.


Electronic Circuits  |  Electronics Wiki
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.