Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Multitask servos with PIC

Status
Not open for further replies.

antkids

New Member
I having problem in programming. As we know that we need to keep sending pulses to keep the servo motor keep at a degree of angle that we want. The problem is how can i still holding the angle of the servo and in the same time make others servos turn? Because of the programme run line by line so I can't order 2 or more servos to turn at the same time. Do you have any idea to make it happen?

Thanks. :D :D :D
 
Help

I also having the same problems with you. The 33 servos are not using the C language to programme, so I not really understand how it works.:( :( Can anyone please send me a sample programme in C language?

Thanks:) :)
 
I think someone did provide some C code in that post, or maybe in the one I started about 18 servos. At any rate, you can multiplex the signal wire or just use multiple pins of the uC. Since the signal is max 2ms and with 20ms period, you can get up to 9 servos (considering loss of time in instructions) going with one 16-bit timer. I opted to using one large PIC instead of a multiplexer, so the pcb is easier to design and debug.
 
You could use several different methods.

One relatively simple / high performance / low overhead method uses the CCP module in "compare" mode, a small ISR "engine", and a 9 element array. The first eight Servo array element values of 600..2400 are used to output a pulse to each Servo pin on PORTB. The ninth array element is used for the Servo period "off time" (20000 usecs minus the cumulative servo pulse on time values).

The listing below is the pseudo C code for an 8 channel 16F628A controller. Let me know if anyone needs to see the assembly listing. Care must be taken to update the CCPR1H register before the CCPR1L register to avoid a false "compare" trigger. The C code as written won't do that but my assembly language code does handle this properly.

Good luck with your project.

Mike

Code:
;******************************************************************
;*                                                                *
;*  K8LH Crazy-8 HiRez 8-channel (PORTB) Servo Algorithm          *
;*                                                                *
;*  1800 1.0-usec steps from 600..2400-usecs per Servo (4 MHz)    *
;*                                                                *
;******************************************************************
;
;   unsigned char n = 0;
;   unsigned int Servo [] = { 1500, 1500, 1500, 1500, 1500,
;                             1500, 1500, 1500, 20000 };
;   unsigned char Shadow = 1;
;
;   void isr_hi ()
;   { LATB = Shadow;              // output new Servo pulse
;
;     CCPR1 += Servo[n];          // update "match" period value
;
;     PIR1bits.CCP1IF = 0;        // clear CCP1 interrupt flag
;
;     Servo[8] -= Servo[n];       // adjust end-of-period time
;     Shadow <<= 1;               // prep for next channel
;     n++;                        // increment array index
;
;     if (n = 9))                 // if end-of-cycle
;     { n = 0;                    // reset array index
;       Servo[8] = 20000;         // reset the 20 msec period
;       Shadow = 1;               // reset Shadow to '00000001'
;     }
;   }
;
 
Last edited:
If it will help you that's my control programm in picBASIC :)
works for 877a @ 20mhz
raw code, it's many ways to speed it up :)



a var byte
b var word
s0 var word
s1 var word 's0-s5 variables for servo position, usually 50-250, but can be 0-255
s2 var word ' for fast control chip must run at 20mhz, but command PULSOUT
s3 var word 'adjusted for 4mhz xtal, so we need to multiply a value by 5.
s4 var word 'that's why we need a WORD variable (0-65535)
s5 var word

DEFINE OSC 20 'xtal at 20mhz, have effect for HSERIN, but not pulsout
DEFINE HSER_RCSTA 90h 'Enable transmit register
DEFINE HSER_TXSTA 24h 'high baudrate, 115.2kbps
DEFINE HSER_CLOERR 1 'automatically clear overrun buffer
DEFINE HSER_BAUD 115200
s0 = 1250: s1 = 715: s2 = 750: s3 = 750: s4 = 750: s5 = 750 'start values of servo positions (*5!!!)
low portc.0
low portc.1
low portc.2 'all of it can be 'portc = 0'
low portc.3
low portc.4
low portc.5
au: 'START

pulsout portc.0, s0'*5 'pulse on pin C.0 for s0 time (already multiplied by 5)
pulsout portc.1, s1'*5
pulsout portc.2, s2'*5
pulsout portc.3, s3'*5 'on all of them... with it's value
pulsout portc.4, s4'*5
pulsout portc.5, s5'*5

auNEW:
hserin 50, au, [a,b] 'receive two characters serially, place them in a and b variables
'if not received within 50msec, goto AU
rcsta.4 = 0 'turn off receiver
rcsta.4 = 1 'then turn it back on, like clearing the buffer
b = b * 5 'a - number of servo, b position (0-255!), for our purpose we have to multiply it :)

if a = "1" then s0 = b: pulsout portc.0, s0 'you need to send serially just two characters, first, number of
if a = "2" then s1 = b: pulsout portc.1, s1 'servo, second, position
if a = "3" then s2 = b: pulsout portc.2, s2 'example, send "2" then send "150", then "1" and "50" and go on
if a = "4" then s3 = b: pulsout portc.3, s3 '
if a = "5" then s4 = b: pulsout portc.4, s4
if a = "6" then s5 = b: pulsout portc.5, s5

goto auNEW

it's much time to send programm again to AU
for every pulsout again, possibly a new values of
a and b already in the buffer, we need to get them
fast, preventing buffer overflow :)
------------------------------------------------------------
here is the whole device at work :)
https://uk.youtube.com/watch?v=8sWki9Y8S8Y
 
Last edited:
Mike said:
Airrr,

Nice video. Code could use some comments though.

Regards, Mike
and [ code ] at top and [/ code ] at bottom ;)

EDIT: Nice video for sure. Nice work. I would like one of those (my cats and dogs would fear me for a change ;D ).
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top