Society of Robots - Robot Forum

Software => Software => Topic started by: Hasan999 on January 23, 2010, 04:53:04 PM

Title: WebbotLib for 22+ Servos
Post by: Hasan999 on January 23, 2010, 04:53:04 PM
EDIT: Just to save your time, instead of reading from here...(since some of the problems were resolved), please proceed to page 2, and start reading from my post #50 with Topic: "Servos Do Not Hold Tight !"

---------------------------------------------------------------------------------------------------

[Axon Microcontroller - Servos: HS-422]

Since I am using a lot of servos that, when run simultaneously, they exceed 20ms between pulses !

I was wondering if I connect a few servos in pairs (using Y-harness), to use 1 port instead of 2, would that decrease the processing time?

i.e. just for example:

Code: [Select]
for(;;){
servo(PORTA,1,650);
servo(PORTA,2,650); // <-- this won't be there if I use Y-harness*
delay_ms(18); }

*would it reduce overall processing time for that loop?

btw, I don't have Y-wires, i'll do it manually since I have extra extender wires... would that work fine?

Thanks !


admin edit: as requested, marked as solved - it was a painful 2 months for everyone :P
Title: Re: Y-harness on servos
Post by: z.s.tar.gz on January 23, 2010, 05:51:09 PM
It would take less processing time, but you would basically be treating two servos as one.

What I would do in your situation would be to buy a bunch of little PWM chips that can replicate the signal even after you've stopped sending it.
You would need one per servo.
Title: Re: Y-harness on servos
Post by: Soeren on January 23, 2010, 06:20:14 PM
Hi,

Or 1 I/O-line could drive up to 9 servos through a 4017 (+ glue).

Just output a signal with the PW for servo 1, then the PW for servo 2 etc. and make a longer pulse (+ a bit circuitry) for resetting to keep it synchronized.

A small µcontroller could be used as well.
Title: Re: Y-harness on servos
Post by: Admin on January 23, 2010, 09:12:59 PM
How many servos?

Look into using WebbotLib, it is better for handling 15+ servos.
(see Axon II tutorial for step-by-step instructions)
Title: WebbotLib for 22+ Servos
Post by: Hasan999 on January 24, 2010, 09:10:09 AM
[Axon Microcontroller - Servos: HS-422]

As per a lot of members' (including Admin's) advice, I started using Webbot Library...

Although it uses interrupts to control servos, I am facing the same problem again...

I'll be using 26 servos (but since I didn't calibrate the wheels yet, i'm using 22 servos for the start)

Problem: the servos jitter !

For less than 4 servos, no jitteriness (each servo is held tight)
For 12 servos, slight vibration (holding not so tight, easily movable by hand)
For 16+ servos, a lot of jitteriness !

Code: [Select]
#include "sys/axon.h"
#include "uart.h"
#include "rprintf.h"
#include "servos.h"
#include "a2d.h"

SERVO S1 = MAKE_SERVO(FALSE, J6,1500, 500);
SERVO S2 = MAKE_SERVO(FALSE, A6,1500, 500);
SERVO S3 = MAKE_SERVO(FALSE, E7,1500, 500);
SERVO S4 = MAKE_SERVO(FALSE, H2,1500, 500);
SERVO S5 = MAKE_SERVO(FALSE, C1,1500, 500);
SERVO S6 = MAKE_SERVO(FALSE, A5,1500, 500);
SERVO S7 = MAKE_SERVO(FALSE, E2,1500, 500);
SERVO S8 = MAKE_SERVO(FALSE, H6,1500, 500);
SERVO S9 = MAKE_SERVO(FALSE, C0,1500, 500);
SERVO S10 =MAKE_SERVO(FALSE, A4,1500, 500);
SERVO S11 =MAKE_SERVO(FALSE, E3,1500, 500);
SERVO S12 =MAKE_SERVO(FALSE, H5,1500, 500);
SERVO S13 =MAKE_SERVO(FALSE, C3,1500, 500);
SERVO S14 =MAKE_SERVO(TRUE,  A2,1500, 500);
SERVO S15 =MAKE_SERVO(FALSE, E4,1500, 500);
SERVO S16 =MAKE_SERVO(TRUE,  H4,1500, 500);
SERVO S17 =MAKE_SERVO(FALSE, C4,1500, 500);
SERVO S18 =MAKE_SERVO(FALSE, A1,1500, 500);
SERVO S19 =MAKE_SERVO(FALSE, E5,1500, 500);
SERVO S20 =MAKE_SERVO(FALSE, H3,1500, 500);
SERVO S21 =MAKE_SERVO(FALSE, A7,1500, 500);
SERVO S22 =MAKE_SERVO(FALSE, A3,1500, 500);
/*
SERVO W1 =MAKE_SERVO(FALSE, C2,1500, 500);
SERVO W2 =MAKE_SERVO(FALSE, C6,1500, 500);
SERVO W3 =MAKE_SERVO(FALSE, E6,1500, 500);
SERVO W4 =MAKE_SERVO(FALSE, C5,1500, 500);
*/
SERVO_LIST servos[] = {&S1,&S2,&S3,&S4,&S5,&S6,&S7,&S8,&S9,&S10,&S11,&S12,&S13,&S14,&S15,&S16,&S17,&S18,&S19,&S20,&S21,&S22};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servos);

void appInitHardware(void){
// Set UART0 to 19200 baud
uartInit(UART0, 115200);
//uartInit(UART0, 19200);
// Tell rprintf to output to UART0
rprintfInit(&uart0SendByte);

// Initialise the servo controller
servosInit(&bank1, TIMER1_COMPAREA);
//servoPWMInit(&bank1);
// Give each servo a start value of 'stop'

act_setSpeed(&S1,0);
act_setSpeed(&S2,0);
act_setSpeed(&S3,0);
act_setSpeed(&S4,0);
act_setSpeed(&S5,0);
act_setSpeed(&S6,0);
act_setSpeed(&S7,0);
act_setSpeed(&S8,0);
act_setSpeed(&S9,0);
act_setSpeed(&S10,0);
act_setSpeed(&S11,0);
act_setSpeed(&S12,0);
act_setSpeed(&S13,DRIVE_SPEED_MIN);
act_setSpeed(&S14,DRIVE_SPEED_MIN);
act_setSpeed(&S15,DRIVE_SPEED_MIN);
act_setSpeed(&S16,DRIVE_SPEED_MIN);
act_setSpeed(&S17,0);
act_setSpeed(&S18,0);
act_setSpeed(&S19,0);
act_setSpeed(&S20,0);
act_setSpeed(&S21,0);
act_setSpeed(&S22,0);

}

// The loopStart parameter has the current clock value in ìS
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0; // dont pause after
}
// This routine is called repeatedly - its your main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){

act_setSpeed(&S1,0);
act_setSpeed(&S2,0);
act_setSpeed(&S3,0);
act_setSpeed(&S4,0);
act_setSpeed(&S5,0);
act_setSpeed(&S6,0);
act_setSpeed(&S7,0);
act_setSpeed(&S8,0);
act_setSpeed(&S9,0);
act_setSpeed(&S10,0);
act_setSpeed(&S11,0);
act_setSpeed(&S12,0);
act_setSpeed(&S13,DRIVE_SPEED_MIN);
act_setSpeed(&S14,DRIVE_SPEED_MIN);
act_setSpeed(&S15,DRIVE_SPEED_MIN);
act_setSpeed(&S16,DRIVE_SPEED_MIN);
act_setSpeed(&S17,0);
act_setSpeed(&S18,0);
act_setSpeed(&S19,0);
act_setSpeed(&S20,0);
act_setSpeed(&S21,0);
act_setSpeed(&S22,0);

return 20000;
}

I tried reducing return 20000; to return 0;, but still the same jitteriness !

I have also tried making different banks, drivers etc, by grouping servos... (edit)then only a few servos work !

I tried that in this way: ...(just an example)

Code: [Select]
SERVO_LIST servo1[] = {&S1,&S2,&S3,&S4};
SERVO_LIST servo2[] = {&S5,&S6,&S7,&S8};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);

servosInit(&bank1, TIMER1_COMPAREA);
servosInit(&bank2, TIMER1_COMPAREA);

//rest same

Please help me figure out the problem... in order to operate 22+ servos without jitteriness !

Thanks !

Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 24, 2010, 12:06:41 PM
You need to use an extra SERVO_DRIVER for each multiple of 10 servos since each driver times it's assigned servos in a round-robin fashion.

In your code where you try multiple SERVO_DRIVERs it looks like you try to assign each driver to the same timer....
Code: [Select]
servosInit(&bank1, TIMER1_COMPAREA);
servosInit(&bank2, TIMER1_COMPAREA);

Try assigning each driver to a different timer.

 
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on January 24, 2010, 01:19:06 PM
Quote
Try assigning each driver to a different timer.

when I try with different Timers... only the servos using TIMER1_COMPAREA work, the others don't get any pulse !

bank1 servos work in this case:

Code: [Select]
SERVO_LIST servo1[] = {&S1,&S2,&S3,&S4,&S5,&S6,&S7,&S8};
SERVO_LIST servo2[] = {&S9,&S10,&S11,&S12,&S13,&S14,&S15};
SERVO_LIST servo3[] = {&S16,&S17,&S18,&S19,&S20,&S21,&S22};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);
SERVO_DRIVER bank3 = MAKE_SERVO_DRIVER(servo3);

servosInit(&bank1, TIMER1_COMPAREA);
servosInit(&bank2, TIMER2_COMPAREB);
servosInit(&bank3, TIMER3_COMPAREC);

Also, i was wondering, the "return 20000;" is it an additional delay? or does it mean that it will re-loop afte 20ms from the start? ...should I keep it 20000 or 0 ?

Thanks..
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 24, 2010, 02:18:56 PM
Quote
btw I re-tried for all  the servos in different banks but using same TIMER1, I notice that the jitteriness is even worse ! (slower)
You would expect performance to get worse as you are now attempting to run three conflicting code threads on one timer resource.

Code: [Select]
servosInit(servosInit(&bank2, TIMER2_COMPAREB);
servosInit(&bank3, TIMER3_COMPAREC);
The code you have tried won't work for the following reasons:

Timer2 is an 8 bit timer and these functions require a 16 bit - so use timers 3-5 instead.

Your bank3 code tries to assign a register which doesn't exist. TIMERx_COMPAREA or TIMERx_COMPAREB correspond to the two compare registers associated with each timer so use A or B but not C.

Try:
Code: [Select]
servosInit(&bank2, TIMER3_COMPAREA);
servosInit(&bank3, TIMER4_COMPAREA);
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 24, 2010, 09:59:31 PM
Quote
// Give each servo a start value of 'stop'
You don't need to do this, WebbotLib starts all servos off by default at zero degrees.

Quote
servosInit(&bank1, TIMER1_COMPAREA);
servosInit(&bank2, TIMER2_COMPAREB);
servosInit(&bank3, TIMER3_COMPAREC);
You can run all servos from the same timer, no need to use multiple timers. Its actually better just to use one.
That being said, on my 20-servo robot fish, I run half my servos using PWM, the other half using a single timer interrupt.

As hopslink said, your servo timer must be 16 bit (check ATmega640 manual, or Axon II datasheet, to determine which is which).

Also, are all your servos HS-422? Is torque constantly being applied to them? How much jitter? Do the servos overheat while they jitter?


ps - Hasan999, keep your related posts together. I just merged your last two posts. ;D
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 25, 2010, 03:58:31 AM
Quote
You can run all servos from the same timer, no need to use multiple timers. Its actually better just to use one.
While that is possible by writing your own servo driver code I am not sure that the Webbotlib servo functions work in that manner (though I may well be wrong...).
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 25, 2010, 04:20:07 AM
Quote
You can run all servos from the same timer, no need to use multiple timers. Its actually better just to use one.
While that is possible by writing your own servo driver code I am not sure that the Webbotlib servo functions work in that manner (though I may well be wrong...).
My ERP uses 12 servos, all running from:
servosInit(&bank2, TIMER3_COMPAREA);

My 20 servo robot fish uses all of the PWM pins, and a timer for the remaining servos:
Code: [Select]
SERVO rib1_left = MAKE_SERVO(TRUE, E3, 1500, 500);
SERVO rib2_left = MAKE_SERVO(TRUE, E4, 1500, 500);
SERVO rib4_left = MAKE_SERVO(FALSE, E5, 1500, 500);
SERVO rib5_left = MAKE_SERVO(FALSE, E6, 1500, 500);
SERVO bulk_left = MAKE_SERVO(TRUE, E7, 1500, 1000);

SERVO rib1_right = MAKE_SERVO(FALSE, A7, 1500, 500);
SERVO rib2_right = MAKE_SERVO(FALSE, J6, 1500, 500);
SERVO rib4_right = MAKE_SERVO(TRUE, C7, 1500, 500);
SERVO rib5_right = MAKE_SERVO(TRUE, A6, 1500, 500);
SERVO bulk_right = MAKE_SERVO(FALSE, C5, 1500, 1000);

SERVO rib1_left_back = MAKE_SERVO(FALSE, H2, 1500, 500);
SERVO rib2_left_back = MAKE_SERVO(FALSE, H3, 1500, 500);
SERVO rib4_left_back = MAKE_SERVO(TRUE, H4, 1500, 500);
SERVO rib5_left_back = MAKE_SERVO(TRUE, H5, 1500, 500);
SERVO bulk_left_back = MAKE_SERVO(TRUE, H6, 1500, 1000);

SERVO rib1_right_back = MAKE_SERVO(TRUE, C4, 1500, 500);
SERVO rib2_right_back = MAKE_SERVO(TRUE, C3, 1500, 500);
SERVO rib4_right_back = MAKE_SERVO(FALSE, C2, 1500, 500);
SERVO rib5_right_back = MAKE_SERVO(FALSE, C1, 1500, 500);
SERVO bulk_right_back = MAKE_SERVO(FALSE, C0, 1500, 1000);

SERVO_LIST servos[] = {&rib5_left,&bulk_left,&rib1_right,&rib2_right,&rib4_right,&rib5_right,&bulk_right,&rib1_left_back,&bulk_left_back,&rib1_right_back,&rib2_right_back,&rib4_right_back,&rib5_right_back,&bulk_right_back};
SERVO_LIST servos_PWM[] = {&rib1_left,&rib2_left,&rib4_left,&rib2_left_back,&rib4_left_back,&rib5_left_back};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servos);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servos_PWM);

servosInit(&bank1, TIMER1_COMPAREA);
servoPWMInit(&bank2);
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 25, 2010, 05:31:23 AM
You would know better than me, but this was my reasoning...

From Webbot's documentation:
Quote
Most servos require a pulse that is between 1ms and 2ms to control them. These pulses need to be sent every 20ms or so - some servos are more tolerant and are happy with every 40ms or so.
Given the longest pulse time of 2ms then this code could drive anywhere between 10 or 20 servos depending on the repeat pulse timing required by the servos.

So it is possible that Webbotlib can handle up to 20 tolerant servos with one driver, however if the servos are not tolerant you can only guarantee that 10 will work.  

Quote
My ERP uses 12 servos, all running from:
servosInit(&bank2, TIMER3_COMPAREA);
Quote
My 20 servo robot fish uses all of the PWM pins, and a timer for the remaining servos:

12 and 14 servos on one driver...

...Hasan999 wants to drive 26 servos, and from his testing...
Quote
For 12 servos, slight vibration (holding not so tight, easily movable by hand)
For 16+ servos, a lot of jitteriness !

It is very possible there are other factors at play here. However assuming that 26 servos will be stretching things for one driver seemed reasonable.

Webbotlib documentation suggests:
Quote
Note that if you have lots of servos you can break them down into separate lists each with their own driver and timer.

EDIT - '9' (Sorry Hasan)
  
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 25, 2010, 07:19:43 AM
He wants 26 servos . . .

Axon II has 15 hardware PWM pins. Then he uses a timer interrupt driver for the other 11. So even at 2ms per servo, thats 22ms delay tops between servo pulses.

For the original Axon, with 7 PWM, so 19 using the timer interrupt. Thats still ~38ms per servo, so still acceptable, although it really depends on each servo. I've done 20 servos on the Axon using WebbotLib without a problem.

Probably not the problem, so going to hopslink's other point . . . which I think is the real problem . . .

Quote
For 12 servos, slight vibration (holding not so tight, easily movable by hand)
For 16+ servos, a lot of jitteriness !
Hasan999, if I had to guess, you:
1) aren't using a proper battery. With 26 servos, each draining 0.5A average, thats 13A (a lot). What is your battery rated for? Did you measure the voltage with everything running? A drop in voltage means a drop in torque.
2) aren't reducing cross interference. Wiggle the servo wires, and I bet you'll see increased jittering.

 ;D
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 25, 2010, 09:19:00 AM
Quote
I've done 20 servos on the Axon using WebbotLib without a problem.
I kind of stand corrected then... that's me over there in the corner with the pointy hat on :-[ . But I'm learning all the time :)

Although...
Quote
...no need to use multiple timers
Quote
Axon II has 15 hardware PWM pins.

Who's suggesting using multiple timers now? :P

Horses for courses, there's more than one way to skin a cat??? etc. Either way Axon is more than capable of driving 26 servos.
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 25, 2010, 09:32:03 AM
Quote
Who's suggesting using multiple timers now?
The hardware PWM pins don't use timer interrupts, so thats why I used them. :P
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on January 25, 2010, 11:54:54 AM
Lets get back to my problem... shall we  ;D

Quote
your servo timer must be 16 bit (check ATmega640 manual, or Axon II datasheet, to determine which is which).
I'm using Axon1...
so it should be: 0 and 2 of 8-bit, and 1,3,4,5 of 16-bit

Quote
What is your battery rated for?

I bought this one (by mistake - before buying the microcontroller)

Code: [Select]
http://www.lynxmotion.com/Product.aspx?productID=67&CategoryID=48
BUT, I cut the pack, removed 1 cell, to make it a 6V battery. (seems fine - being using it since months now)

Quote
Did you measure the voltage with everything running?
yea I tried just now, the voltage directly from the battery (fully charged) = 7.24V and once running, the voltage across the (servo) ports = 6.1V

Quote
if I had to guess, you aren't reducing cross interference.
I have no idea what you mean't by that :P but, please read on... I think the problem is not an electrical one*

-------------------------------------------------------------------------

I tried Admin's code of Robot Fish, i.e. using PWM and TIMER1 (2 banks)

Code: [Select]
SERVO_LIST servo1[] = {&S1,&S2,&S4,&S5,&S6,&S7,&S8,&S9,&S10,&S11,&S13,&S14,&S15,&S17,&S18,&S21,&S22};
SERVO_LIST servo2[] = {&S12,&S16,&S20,&S3,&S19 };

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);

servosInit(&bank1, TIMER1_COMPAREA);
servoPWMInit(&bank2);

Result: the Servos do not jitter anymore !... BUT they are not holding tight either ! (i.e. they do not get pulses every after 20ms, definately beyond 40ms or something - I can drag the running servos easily with my hand !)

Quote
For the original Axon, with 7 PWM, so 19 using the timer interrupt. Thats still ~38ms per servo, so still acceptable
I have already built the 4-legged robot, it is too heavy !.. and that is the reason I need the servos to remain TIGHT otherwise, the whole robot collapses (because of the gap in ms when the servos do not get signal) - I really need the  servos to get signal within 20ms throughout. (if not 26 servos, then at least 20 - because I 'can' pair some to single ports)

*What I have observed is that, if I use only 1 servo, it gets signal every after 20ms accurately (it holds its position so tight that I cannot move it manually ! - this is what I want !) ...but apparently that "20ms" keeps increasing as I add more and more (act_setSpeed) servos !

I don't understand why does it increase the delay when it is all running on "interrupts" !  :-\
Title: Re: WebbotLib for 22+ Servos
Post by: paulstreats on January 25, 2010, 12:52:51 PM
Try running your program for all 26 servos BUT only plug 1 servo in. If it holds tight then it is likely to be a power problem, if not then a programming problem.

You battery is rated for MAX discharge 10~16 amps. 16 amps would likely be for a brand new battery, used straight after a full charge. I would look at a more conservative estimate at being 10~12 amps. Bearing in mind that you have already removed 1 cell, this will affect its performance to some degree from the original specs. Remember admin saying above that your 26 servos will be drawing 13amps - and that doesnt include anything else that you have plugged in to them. This could be where the basis of your problem is, maybe the code does need sharpening up a bit, but if your batteries are struggling then you will always get uneven results making perfecting the code even harder.
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 25, 2010, 01:16:32 PM
Also, if the time between servo updates affects how tightly they hold you should see a marked difference in holding power between the hardware pwm servos and those on the software pwm bank.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on January 25, 2010, 02:39:44 PM
@paulstreats...
Quote
Try running your program for all 26 servos BUT only plug 1 servo in. If it holds tight then it is likely to be a power problem, if not then a programming problem.

I tried... removed all the ports leaving 1, and I had the program to run all the servos... but that servo was not held tight while running ! (again, I could drag the position - not 20ms !)
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on January 25, 2010, 03:02:21 PM
Observation: When I tried making a bank having only 1 servo (using TIMER1_COMPAREA) along with another bank having the rest of the servos (using TIMER3_COMPAREA), I noticed that the single servo was held tight ! (however, others were not)...

Hence I tried making maximum number of banks possible (that depends on the maximum number of TIMERS available). So apparently I can all use 12 (16-bit)Timers (i.e. TIMER,1,3,4,5 with COMPARE,A,B,C)

Assuming lesser servos in a bank makes it hold tight, I made my own banks according to the servos that I needed to be 100% tight (i.e. 20ms), and those that could tolerate slight weakness. (i.e. 20ms to 25ms maybe)

Code: [Select]
SERVO_LIST servo1[] = {&S1};
SERVO_LIST servo2[] = {&S2};
SERVO_LIST servo3[] = {&S3};
SERVO_LIST servo4[] = {&S4};
SERVO_LIST servo5[] = {&S5,&S6};
SERVO_LIST servo6[] = {&S7,&S8};
SERVO_LIST servo7[] = {&S9,&S10,&S11,&S12};
SERVO_LIST servo8[] = {&S13,&S14};
SERVO_LIST servo9[] = {&S15,&S16};
SERVO_LIST servo10[] = {&S17};
SERVO_LIST servo11[] = {&S18};
SERVO_LIST servo12[] = {&S19,&S20,&S21,&S22};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);
SERVO_DRIVER bank3 = MAKE_SERVO_DRIVER(servo3);
SERVO_DRIVER bank4 = MAKE_SERVO_DRIVER(servo4);
SERVO_DRIVER bank5 = MAKE_SERVO_DRIVER(servo5);
SERVO_DRIVER bank6 = MAKE_SERVO_DRIVER(servo6);
SERVO_DRIVER bank7 = MAKE_SERVO_DRIVER(servo7);
SERVO_DRIVER bank8 = MAKE_SERVO_DRIVER(servo8);
SERVO_DRIVER bank9 = MAKE_SERVO_DRIVER(servo9);
SERVO_DRIVER bank10 = MAKE_SERVO_DRIVER(servo10);
SERVO_DRIVER bank11 = MAKE_SERVO_DRIVER(servo11);
SERVO_DRIVER bank12 = MAKE_SERVO_DRIVER(servo12);

servosInit(&bank1, TIMER1_COMPAREA);
servosInit(&bank2, TIMER1_COMPAREB);
servosInit(&bank3, TIMER1_COMPAREC);
servosInit(&bank4, TIMER3_COMPAREA);
servosInit(&bank5, TIMER3_COMPAREB);
servosInit(&bank6, TIMER3_COMPAREC);
servosInit(&bank7, TIMER4_COMPAREA);
servosInit(&bank8, TIMER4_COMPAREB);
servosInit(&bank9, TIMER4_COMPAREC);
servosInit(&bank10, TIMER5_COMPAREA);
servosInit(&bank11, TIMER5_COMPAREB);
servosInit(&bank12, TIMER5_COMPAREC);

Result: Worked as I supposed ! ...the servos are tight...finally  ;D

I gtg, I'll resume messing around with the same after 12 hour...

BTW, I didn't try but I think there could be another bank controlled using servoPWMInit(&bank13);   ;)

umm... 1 of my question remained unanswered: "what about the return 20000; ?...what if I reduce it? or make it 0;  ???

Thanks.....
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 25, 2010, 08:47:05 PM
Yea, I suggest doing just 3 drivers, then. PWM, and the other servos evenly divided between two timer interrupt drivers.

The reason is that all these interrupts will slow down your main code significantly. Also, you might get extra servo jitter if interrupts interfere with other interrupts.

Quote
what about the return 20000; ?...what if I reduce it? or make it 0
It can be whatever you want. But usually I make it high for open source code made for beginners - it'll reduce various problems caused by a super fast processor on hardware that can't move at light speed . . . Try reducing it, and if nothing breaks, then you are fine. But it really depends on what the rest of your code is doing!
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on January 26, 2010, 05:50:53 PM
Quote
what about the return 20000; ?...what if I reduce it? or make it 0
It wont make any difference, depending on what else your main loop does, since the servo commands are happening under interrupts.
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on January 26, 2010, 09:29:56 PM
The servo timing is a complex thing (not an excuse - just a statement!).
My original code did the following:-
Code: [Select]
total = 0
for each servo
  pulse = calc servo pulse
  total += pulse
  emit pulse
next servo
pause 20ms - total
This code makes sure that the pulse to the first servo starts 20ms after its last pulse started.

But bad news. Take a pen'n'paper and assume that for the first pass all the servos need a 2ms pulse and on the next pulse they all need a 1ms pulse. Now look at each servo in turn. The first servo is fine but as you move through the list of servos you will see that they progressively get less and less of 20ms.

Admin said it fried his servos and this is bad (mainly coz I owe him some servos).

So with Admins advise I changed it to:
Code: [Select]
total = 0
for each servo
  pulse = calc servo pulse
  total = pulse
  emit pulse
next servo
pause 20ms - total

A subtle change - but means that the loop repeats 20ms after the starting pulse to the last servo.

So as you add more servos - then the pulse frequency to a given servo increases. ie if you have 20 servos each taking 2ms then it takes 19*2ms + 20ms = 38ms to repeat. So each servo gets a pulse about every 38ms.

This is probably why you get 'floppy' servos.

And its a beggar to change! Heres why...

Assume all servos on the first pass have a pulse of 2ms and that on the next pass the first few are also 2ms and subsequent ones are 1ms. Then the order of sending out pulses needs to change. ie for pass 2 you may need to do servo 8,9,10 then 1,2,3 in order to keep each one on their own '20ms anniversary'.

The limiting factor will be the number of servos in the bank. ie if there are 15 and they are all issuing 2ms pulses then the duration is 30ms. So its impossible to refresh them all every 20ms.

So the current work around is to use hardware PWM where you can, and split the remainder into as many banks as you can afford in timer compare channels.

In the meantime I need to think if its possible to come up with a solution that keeps servos 'tight' but without 'frying them' !!!

Any sensible suggestions (and yes I've Googled), but bearing in mind this is all under interrupts so no code that includes a delay statement please, then PM me.


Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 26, 2010, 10:40:02 PM
To be honest, I think your code now is 'good enough'. I say that because different servos act differently, and I think we are in the sweet spot average of all of them (subjectively tested).

One day all servos will become digital, and when that happens, we can come back to this. ;D

(although the WebbotLib manual might want to point out typical problems and recommend solutions for very large numbers of servos)
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 27, 2010, 03:27:53 AM
You could get some extra precision quite easily by doing:
Code: [Select]
total = 0
for each servo
  pulse = calc servo pulse
  total = pulse
  emit pulse
next servo
pause (20-(No_Of_Servos_In_Bank - 1))ms - total

Working on the assumption that each servo has a minimum 1ms delay.

Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 27, 2010, 03:36:32 AM
Quote
Working on the assumption that each servo has a minimum 1ms delay.
I've used servos that have a 0.5ms to 2.5ms range (normal is 1ms to 2ms).
Title: Re: WebbotLib for 22+ Servos
Post by: hopslink on January 27, 2010, 03:45:38 AM
Quote
I've used servos that have a 0.5ms to 2.5ms range (normal is 1ms to 2ms).

Never assume.... (picks up pointy hat and heads back to his corner ;D)

That said you define the minimum pulsewidth for each servo as you declare it in Webbotlib so you could sum those to give a Bank_Minimum_Delay and use that.

Title: Re: WebbotLib for 22+ Servos
Post by: Ro-Bot-X on January 27, 2010, 06:28:46 AM
What if you make an array of servos and sort the pulse for all servos to be ascending in the array. Then you turn high all the servos at once and start counting, then turn low the servos that have the shortest pulse first (let's say 1ms...) and keep going through the array until the last servo pulse is low (let's say 2ms...), then reset the counter when it reaches 20ms (during this time you may do whatever else in the code...)? I guess a timer interrupt can be used for this.

Would that work better?
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on January 27, 2010, 10:00:22 AM
Actually, Ro-Bot-X, I've had that idea for years. And you know, it might still be worth trying it.

I never implemented in the past because I never needed to. And I was a bit worried about what would happen if the servos all required the same position.

But still, I think it might be worth looking into. Webbot, thoughts?
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on January 27, 2010, 02:04:01 PM
Well thats the sort of thing that dedicated Servo boards do. But since they don't have anything else to do then they can do it in the foreground.
I've got to do it under interrupts.

So heres the challenge....

Once you've set all the pins high and you've worked out the sorted list. Then you may have a number of servos that need to be turned off at 'roughly' the same time - but not at 'exactly' the same time - lets say 20us apart.

So you've set a compare interrupt for the earliest, the interrupt happens and you've stopped the pulse to that servo. You now realise that you've got 20us before you turn off the next one. First you have to subtract the amount of time you've just spent processing the previous servo. So you come up with a new value for the timer compare register but if the timer counter has actually passed that value just before you set the new compare value then you will have to wait until the timer wraps all the way around to that value again.

You can't use delay_us etc as the last thing you want to do in an ISR is to 'pause' as the whole board (UARTs, Timers, everything) is dead during that time.

------
Here is a way I am thinking about solving it. Instead of 1 timer compare per bank I will use 2 timer compares.
Compare 1 will be used to measure the pulse length and to turn the pin off again
Compare 2 will be used to measure the time when the next servo pin should be turned high

When processing a servo:
Set the pin high (start of pulse)
Set Compare1 to the time when the pulse will turn off
Set Compare2 to the maximum possible pulse length for the servo (ie always >=Compare1).
Idling
Compare 1 fires and turns off the pulse. Servo done.
Idling
Compare 2 fires and we now process the next servo.

The total time for a bank is therefore controlled by Compare 2 and is the sum of all the longest possible pulses (but constant once calculated).
Since Compare2 times the start of a pulse and always takes the pessimistic case then the start of a pulse of any servo will always happen every 20ms. (Although if you have say 20 servos in one bank then each servo may fire every 40ms). But it will be consistent. Note that you don't get time for nothing so having summed all the longest values for the servos in the bank then this may exceed 20ms. In which case I would need to add a few ms extra - otherwise your foreground task, and other servo banks, would never get serviced - the cpu would just become a servo driver !

I don't have enough servos to try it myself. Other than setting it up and then moving a single servo to each pin and see what happens. So I can test the pins individually but not all together.

If anyone wants to be a guinea-pig then let me know. I could ship an 'h' file to put into your project directory.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on January 31, 2010, 03:32:02 PM
After days of banging my head with the programming....I cannot get it working perfectly...

I just hope i can describe the problem....

I am running 26 servos using 12 banks (i.e. all 12 16bit Timers+Compares)...

I distributed the servos corresponding to specific Timers, (after a lot of trials) because (I don't know why) some servos hate some timers? ...they do not take pulses every after 20ms (maybe above 30ms)

However, I could eventually end up producing a combination of all the servos, so that they all hold tight, here's the code:

Code: [Select]
#include "sys/axon.h" // I am using an Axon
#include "uart.h"
#include "rprintf.h"
#include "servos.h"
#include "a2d.h"

SERVO S1 = MAKE_SERVO(FALSE, C7,1500, 500);
SERVO S2 = MAKE_SERVO(FALSE, A6,1500, 500);
SERVO S3 = MAKE_SERVO(FALSE, E7,1500, 500);
SERVO S4 = MAKE_SERVO(FALSE, H2,1500, 500);
SERVO S5 = MAKE_SERVO(FALSE, C1,1500, 500);
SERVO S6 = MAKE_SERVO(FALSE, A5,1500, 500);
SERVO S7 = MAKE_SERVO(FALSE, E2,1500, 500);
SERVO S8 = MAKE_SERVO(FALSE, H6,1500, 500);
SERVO S9 = MAKE_SERVO(FALSE, C0,1500, 500);
SERVO S10 =MAKE_SERVO(FALSE, A4,1500, 500);
SERVO S11 =MAKE_SERVO(FALSE, E3,1500, 500);
SERVO S12 =MAKE_SERVO(FALSE, H5,1500, 500);
SERVO S13 =MAKE_SERVO(FALSE, C3,1500, 700);
SERVO S14 =MAKE_SERVO(TRUE, A2,1500, 700);
SERVO S15 =MAKE_SERVO(FALSE, A3,1500, 700);
SERVO S16 =MAKE_SERVO(TRUE, H4,1500, 700);
SERVO S17 =MAKE_SERVO(FALSE, C4,1500, 500);
SERVO S18 =MAKE_SERVO(FALSE, A1,1500, 500);
SERVO S19 =MAKE_SERVO(FALSE, E5,1500, 500);
SERVO S20 =MAKE_SERVO(FALSE, A0,1500, 500);
SERVO S21 =MAKE_SERVO(FALSE, E4,1500, 500);
SERVO S22 =MAKE_SERVO(FALSE, A7,1500, 500);
SERVO W1 =MAKE_SERVO(FALSE, C2,1480, 500);
SERVO W2 =MAKE_SERVO(FALSE, C6,1480, 500);
SERVO W3 =MAKE_SERVO(FALSE, E6,1480, 500);
SERVO W4 =MAKE_SERVO(FALSE, C5,1480, 500);

SERVO_LIST servo1[] = {&S1};
SERVO_LIST servo2[] = {&S17};
SERVO_LIST servo3[] = {&S18};
SERVO_LIST servo4[] = {&S2};
SERVO_LIST servo5[] = {&S3};
SERVO_LIST servo6[] = {&S4};
SERVO_LIST servo7[] = {&S5,&S6,&S14,&S21};
SERVO_LIST servo8[] = {&S7,&S8,&S15,&S22};
SERVO_LIST servo9[] = {&S19};
SERVO_LIST servo10[] = {&S20};
SERVO_LIST servo11[] = {&W1,&W2,&W3,&W4,&S9,&S10,&S11,&S12};
SERVO_LIST servo12[] = {&S13,&S16};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);
SERVO_DRIVER bank3 = MAKE_SERVO_DRIVER(servo3);
SERVO_DRIVER bank4 = MAKE_SERVO_DRIVER(servo4);
SERVO_DRIVER bank5 = MAKE_SERVO_DRIVER(servo5);
SERVO_DRIVER bank6 = MAKE_SERVO_DRIVER(servo6);
SERVO_DRIVER bank7 = MAKE_SERVO_DRIVER(servo7);
SERVO_DRIVER bank8 = MAKE_SERVO_DRIVER(servo8);
SERVO_DRIVER bank9 = MAKE_SERVO_DRIVER(servo9);
SERVO_DRIVER bank10 = MAKE_SERVO_DRIVER(servo10);
SERVO_DRIVER bank11 = MAKE_SERVO_DRIVER(servo11);
SERVO_DRIVER bank12 = MAKE_SERVO_DRIVER(servo12);
//#define threshold 8

void appInitHardware(void){
// Set UART0 to 19200 baud
uartInit(UART0, 115200);
//uartInit(UART0, 19200);
// Tell rprintf to output to UART0
rprintfInit(&uart0SendByte);

// Initialise the servo controller
servosInit(&bank1, TIMER3_COMPAREB);
servosInit(&bank2, TIMER1_COMPAREA);
servosInit(&bank3, TIMER1_COMPAREB);
servosInit(&bank4, TIMER1_COMPAREC);
servosInit(&bank5, TIMER5_COMPAREB);
servosInit(&bank6, TIMER3_COMPAREC);
servosInit(&bank7, TIMER5_COMPAREA);
servosInit(&bank8, TIMER3_COMPAREA);
servosInit(&bank9, TIMER4_COMPAREA);
servosInit(&bank10, TIMER4_COMPAREB);
servosInit(&bank11, TIMER4_COMPAREC);
servosInit(&bank12, TIMER5_COMPAREC);

// Give each servo a start value of 'stop'
}
// The loopStart parameter has the current clock value in ìS
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0; // dont pause after
}

// This routine is called repeatedly - its your main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){

act_setSpeed(&S1,0);
act_setSpeed(&S2,0);
act_setSpeed(&S3,0);
act_setSpeed(&S4,0);
act_setSpeed(&S5,0);
act_setSpeed(&S6,0);
act_setSpeed(&S7,0);
act_setSpeed(&S8,0);
act_setSpeed(&S9,0);
act_setSpeed(&S10,0);
act_setSpeed(&S11,0);
act_setSpeed(&S12,0);
 
act_setSpeed(&S13,DRIVE_SPEED_MIN);
act_setSpeed(&S14,DRIVE_SPEED_MIN);
act_setSpeed(&S15,DRIVE_SPEED_MIN);
act_setSpeed(&S16,DRIVE_SPEED_MIN);

act_setSpeed(&W1,0);
act_setSpeed(&W2,0);
act_setSpeed(&W3,0);
act_setSpeed(&W4,0);
act_setSpeed(&S21,0);
act_setSpeed(&S22,0);

act_setSpeed(&S17,0);
act_setSpeed(&S18,0);
act_setSpeed(&S19,0);
act_setSpeed(&S20,0);

return 0;
}

I have already built my 4-legged robot (assembled using Servo brackets, etc). So once I switch ON, all the servos hold (their given) positions tightly, but when I apply a small force on one bracket (tend to change its position*), it "does" withstand that small force, BUT, not for very long... it would lose its grip suddenly any time, and the whole Loop will "restart", i.e. ALL the servos will lose power, and go back to their initial positions, and try to attain their initial positions again.

*not forcing it to change the position, it's like a small continuous torque that the servo "can" withstand.

So, technically speaking,

Problem #1: Servos do not continuously hold themselves at XmS for very long, they have a few ms break randomly after some seconds !? (where X is probably between 20ms to 25ms - assuming it from my experience of torturing servos, lol)

Problem #2: If one servo fails to get back in its position once disturbed, ALL the servos lose power, and the TICK_COUNT appControl loop restarts !

Problem #3: I have a few weeks remaining to get it working, I never expected it to be so hard to program only 26 servos (giving each of them pulses at exactly 20ms) while Axon Microcontroller can control upto 29 servos  ???

Need Help  :(

Thanks
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on January 31, 2010, 04:06:31 PM
Ok there are a couple of things going on here:-

Quote
Problem #2:  If one servo fails to get back in its position once disturbed, ALL the servos lose power, and the TICK_COUNT appControl loop restarts !

I think you have a major batter/supply problem. Servo location, forces etc have nothing to do with the code. You are stressing the servos, the current requirement goes up and I'll bet that you are using the same batteries to power the Axon itself. With the increased current used by the servos the battery voltage drops, the regulator fails, and the whole Axon reboots. ie nothing to do with software.

Quote
Problem #3: I have a few weeks remaining to get it working, I never expected it to be so hard to program only 26 servos (giving each of them pulses at exactly 20ms) while Axon Microcontroller can control upto 29 servos  Huh
So you have successfully done it in some way before on an Axon - right? If so then your deadline isn't a problem. Or have you just 'read it somewhere'.

Problem #1: Well 22 servos running at say 1ms pulse per servo = 22ms out of every 20ms. So its VERY busy even under interrupts. I am gonna create an alternative servo driver to see if it helps but its going to take me some time - these things aren't quick/easy. I don't feel bad about that - trying to run 22 servos whilst also reading other things like, say, compass, gps, uarts etc, etc - let alone running your main program is asking a lot from a single 16MHz cpu.
In the meantime - if you're short on time then I would suggest adding a slave board - a servo controller. Very easy to make,buy,build since they don't have anything else to worry about.

Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on February 01, 2010, 08:01:49 AM
I would suggest adding a slave board - a servo controller. Very easy to make,buy,build since they don't have anything else to worry about.

I (and others) have suggested this in at least two other of his threads about this problem.
Title: Re: WebbotLib for 22+ Servos
Post by: paulstreats on February 01, 2010, 03:41:44 PM
Both Admin and myself have mentioned the power issue in this topic (You cant expect to get any consistent results from your code unless you fulfill the power requirements of your setup.)

Quote
So you have successfully done it in some way before on an Axon - right? If so then your deadline isn't a problem. Or have you just 'read it somewhere'.

 He did read this. Its in the Specification list of the Axon (presumably as a selling point).

http://www.societyofrobots.com/axon/ (http://www.societyofrobots.com/axon/)

now is the time to prove it is possible :)
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on February 01, 2010, 04:52:25 PM
now is the time to prove it is possible :)

A little googling can prove it. :-p

Of course it's possible. You just can't do that much else at the same time. There is RoboRealm that controls 29 servos fine using an Axon.
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on February 01, 2010, 07:41:24 PM
Agree with everything madsci1016 has said,

I'm also perfectly happy to recognise there may be room for improvement in WebbotLib - but it IS driving 22+ servos - its only 'torque' that has been the issue. Again this could be related to the fundamental power supply issue:- if the battery draw is high, and voltage is dropping, then the servos may not be getting enough 'oomph' for the expected torque.

So whatever the solution is - it will require a suitable power supply. Without that solved we are all 'guessing'.
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on February 01, 2010, 08:01:55 PM
I think the best approach for that many servos on a multi-limb robot is to have a dedicated servo controller, a cheap one or a nice one that lets you program gaits. That way you have a master controller that can make all the decisions and process input without being brought down by the daunting task of generating that many PWM channels.

Sure, since you only need to send PWM between 0 and 2ms of a 20ms cycle, you could program it to pause everything for the first 2 ms and only handle the PWM generation, but then you uC is ignoring everything else, like bytes being sent over Uart. (I think) this is why the RoboRealm code has a 'sync' byte in it's serial coms to the computer, so the computer only sends new data when the Axon is ready to accept it, or else it will come in when it is busy generating PWM and be ignored.

I think many people gain a better appreciation for uC and programming them after they take a university course on micro-processors and the assembly language. When you have a AVR with 50 something I/O and 4 uarts BUT can only ever handle one thing at a time, timing becomes a very important thing. Webbot is very good at what he does for being able to build a library that runs as smoothly as Webbotlib does.
Title: DETAILS OF THE PROBLEM !
Post by: Hasan999 on February 21, 2010, 04:04:06 AM
Problem (same as before): The servos cannot take any load !..


I think you have a major batter/supply problem. Servo location, forces etc have nothing to do with the code. You are stressing the servos, the current requirement goes up and I'll bet that you are using the same batteries to power the Axon itself.

After trying with a 6V battery of 3200mAh, still did not solve the problem...

so I tried with a powerful DC Power Supply Unit (that can go upto 10A).

If I have all the 25 servos in the banks (12 banks, using all 16-bit Timers), then the microcontroller doesn't get enough power to even get the servos to their initial positions, they fluctuate (as in trying to get into position, but loses power - its like a reset every second)....and that is when I have kept Current to (max) 5A.. and it shows 0.3A something on the Unit's display. <-- Note: this is when the servos are not able to get in the initial positions - because it requires a small load, since its a 4-legged robot

(with the battery, they'd get into the intial positions once switched ON, "only" when the battery is fully charged !)

Anyway, I tried with different number of servos.... starting with 1 servo !

Any 1 Servo works fine !...holds firm enough and if I drag its position forcefully, it can take the load (maybe 1.5A+)

similar case with around 4 servos, when I drag all 4 servos (to check the load), it goes upto 2A.

BUT, when I try with up to 11 servos, they can take a load up to (around) 2.6A, and then loses power (and resets).
[although should have been more, when I have the max Current set to 5A+]

And beyond 11 servos, it can not even get into the initial positions, (unless I help the servos, if so then they hold "almost" firm) and can take load up to (around) 1.8A, and dies again.

Now since it works (almost) fine for less than 11 servos, I have already tried with replacing those 11 with other 11 servos (to see if some servos are causing problem, but not), it still works with 11 servos.

Hence, it doesn't work when I use "many" servos simultaneously. (they don't even get pulses exactly after 20ms, I'm sure about that)


Again this could be related to the fundamental power supply issue:- if the battery draw is high, and voltage is dropping, then the servos may not be getting enough 'oomph' for the expected torque.

So whatever the solution is - it will require a suitable power supply. Without that solved we are all 'guessing'.


I have set the voltage to 6V, and also tried measuring from one of the empty ports, it shows a little fluctuations but average ~ 6V (5.9V to 6.2V)

Here's the code:

Code: [Select]
// Place any #define statements here before you include ANY other files
// You must ALWAYS specify the board you are using
// These are all in the 'sys' folder e.g.
#include "sys/axon.h"
#include "uart.h"
#include "rprintf.h"
#include "servos.h"
#include "a2d.h"
#include "Sensors/Distance/Sharp/GP2D12.h"
#define P 100//107
#define N 120//113
#define time(x) if(clockGetus()>((x*1000000)-1000) && clockGetus()<((x*1000000)+1000))
//Sharp_GP2D12 sensor = MAKE_Sharp_GP2D12(F7);

//+107 | 113-
int ss1=-14;
int ss2=0;
int ss3=8;
int ss4=0;
int ss5 = 3;
int ss6 = 5;
int ss7 = 10;
int ss8 = 8;
int ss9 = -7;// -120;
int ss10 = 7;// +120;
int ss11 = 0;// -127;
int ss12 = -7;// +131;
int ss13 = -18;
int ss14 = -29;
int ss15 = -10;
int ss16 = -27;
int ss17 = -22;
int ss18 = -14;
int ss19 = -14;
int ss20 = -8;
int ss22 = -60;
int ww1 = 13;
int ww2 = 13;
int ww3 = 7;
int ww4 = 13;

SERVO S1 = MAKE_SERVO(FALSE, C7,1500, 880);
SERVO S2 = MAKE_SERVO(FALSE, A6,1500, 880);
SERVO S3 = MAKE_SERVO(TRUE, E7,1500, 880);
SERVO S4 = MAKE_SERVO(FALSE, H2,1500, 880);
SERVO S5 = MAKE_SERVO(FALSE, C1,1500, 880);
SERVO S6 = MAKE_SERVO(FALSE, A5,1500, 880);
SERVO S7 = MAKE_SERVO(FALSE, E2,1500, 920);
SERVO S8 = MAKE_SERVO(FALSE, H6,1500, 900);
SERVO S9 = MAKE_SERVO(FALSE, C0,1500, 960);
SERVO S10 =MAKE_SERVO(FALSE, A4,1500, 930);
SERVO S11 =MAKE_SERVO(FALSE, E3,1500, 880);
SERVO S12 =MAKE_SERVO(FALSE, H5,1500, 880);
SERVO S13 =MAKE_SERVO(FALSE, C3,1500, 880);
SERVO S14 =MAKE_SERVO(TRUE, J6,1500, 880);
SERVO S15 =MAKE_SERVO(FALSE, E6,1500, 880);
SERVO S16 =MAKE_SERVO(TRUE, H4,1500, 880);
SERVO S17 =MAKE_SERVO(FALSE, C4,1500, 1000);
SERVO S18 =MAKE_SERVO(FALSE, A1,1500, 1000);
SERVO S19 =MAKE_SERVO(FALSE, E5,1500, 1000);
SERVO S20 =MAKE_SERVO(FALSE, A0,1500, 1000);
//SERVO S21 =MAKE_SERVO(FALSE, E4,1500, 880);
SERVO S22 =MAKE_SERVO(FALSE, A7,1500, 880);
SERVO W1 =MAKE_SERVO(FALSE, C2,1480, 500);
SERVO W2 =MAKE_SERVO(FALSE, C6,1480, 500);
SERVO W3 =MAKE_SERVO(FALSE, H3,1480, 500);
SERVO W4 =MAKE_SERVO(FALSE, C5,1480, 500);

SERVO_LIST servo1[] = {&S1};
SERVO_LIST servo2[] = {&S14,&S17};
SERVO_LIST servo3[] = {&S18};
SERVO_LIST servo4[] = {&S2};
SERVO_LIST servo5[] = {&S3};
SERVO_LIST servo6[] = {&S4};
SERVO_LIST servo7[] = {&S5,&S6,&S22};
SERVO_LIST servo8[] = {&S7,&S8};
SERVO_LIST servo9[] = {&S15};
SERVO_LIST servo10[] = {&W1,&W2,&W3,&W4,&S19};//
SERVO_LIST servo11[] = {&S9,&S10,&S11,&S12,&S20};//
SERVO_LIST servo12[] = {&S13,&S16};

SERVO_DRIVER bank1 = MAKE_SERVO_DRIVER(servo1);
SERVO_DRIVER bank2 = MAKE_SERVO_DRIVER(servo2);
SERVO_DRIVER bank3 = MAKE_SERVO_DRIVER(servo3);
SERVO_DRIVER bank4 = MAKE_SERVO_DRIVER(servo4);
SERVO_DRIVER bank5 = MAKE_SERVO_DRIVER(servo5);
SERVO_DRIVER bank6 = MAKE_SERVO_DRIVER(servo6);
SERVO_DRIVER bank7 = MAKE_SERVO_DRIVER(servo7);
SERVO_DRIVER bank8 = MAKE_SERVO_DRIVER(servo8);
SERVO_DRIVER bank9 = MAKE_SERVO_DRIVER(servo9);
SERVO_DRIVER bank10 = MAKE_SERVO_DRIVER(servo10);
SERVO_DRIVER bank11 = MAKE_SERVO_DRIVER(servo11);
SERVO_DRIVER bank12 = MAKE_SERVO_DRIVER(servo12);

#define threshold 64

void appInitHardware(void){
uartInit(UART1, 115200);
rprintfInit(&uart1SendByte);
//distanceInit(sensor);
// Initialise the servo controller
servosInit(&bank1, TIMER3_COMPAREB);
servosInit(&bank4, TIMER1_COMPAREC);
servosInit(&bank5, TIMER5_COMPAREB);
servosInit(&bank2, TIMER1_COMPAREA);
servosInit(&bank3, TIMER1_COMPAREB);
servosInit(&bank6, TIMER3_COMPAREC);
servosInit(&bank7, TIMER5_COMPAREA);
servosInit(&bank8, TIMER3_COMPAREA);
servosInit(&bank9, TIMER4_COMPAREA);
servosInit(&bank10, TIMER4_COMPAREB);
servosInit(&bank11, TIMER4_COMPAREC);
servosInit(&bank12, TIMER5_COMPAREC);

// Give each servo a start value of 'stop'

/* If i disconnect some banks to leave around 11 servos connected, they can take load
servosDisconnect(&bank1);
servosDisconnect(&bank2);
servosDisconnect(&bank3);
servosDisconnect(&bank4);
servosDisconnect(&bank5);
servosDisconnect(&bank6);
servosDisconnect(&bank7);
servosDisconnect(&bank8);
servosDisconnect(&bank9);
servosDisconnect(&bank10);
servosDisconnect(&bank11);
servosDisconnect(&bank12);
*/
}
// The loopStart parameter has the current clock value in uS
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0;
}

// This routine is called repeatedly - its your main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){
//distanceRead(sensor);
//clockGetus();

act_setSpeed(&S1,ss1);
act_setSpeed(&S2,ss2);
act_setSpeed(&S3,ss3);
act_setSpeed(&S4,ss4);
act_setSpeed(&S5,ss5);
act_setSpeed(&S6,ss6);
act_setSpeed(&S7,ss7);
act_setSpeed(&S8,ss8);
act_setSpeed(&S9,ss9);
act_setSpeed(&S10,ss10);
act_setSpeed(&S11,ss11);
act_setSpeed(&S12,ss12); 

act_setSpeed(&S13,ss13);
act_setSpeed(&S14,ss14);
act_setSpeed(&S15,ss15);
act_setSpeed(&S16,ss16);

act_setSpeed(&W1,ww1);
act_setSpeed(&W2,ww2);
act_setSpeed(&W3,ww3);
act_setSpeed(&W4,ww4);

act_setSpeed(&S17,ss17);
act_setSpeed(&S18,ss18);
act_setSpeed(&S19,ss19);
act_setSpeed(&S20,ss20);

act_setSpeed(&S22,ss22);
//act_setSpeed(&S21,ss21);

//rprintf("%u \r\n",sensor.distance.cm);

return 0;
}


Summary:

1) Servos can't take enough load even when supplied sufficient power and current !
2) Servos do not hold tight enough when I increase the number of servos

Have been struggling, since 2 months, to program 25 servos simultaneously (while holding tight)....need Help !

Thanks  :(
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on February 21, 2010, 05:04:44 AM
When you say
Quote
Any 1 Servo works fine !...holds firm enough and if I drag its position forcefully, it can take the load (maybe 1.5A+)

Are you :

1. Leaving the code the same, ie all 25 servos, but only physically connecting one servo (in which case it would be a hardware/supply issue) coz the code doesn't care if the servos are actually there or not; or

2. Are you changing the code so that it is only using one servo (in which case its a timing issue) - in which case:- see previous reponses from lots of people about having dedicated servo controllers.

 
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on February 21, 2010, 05:21:10 AM
Depending on the servo you are using, it can use an average 0.5A and up to 1A peak.

22+ servos means 22A+ peak.

A single battery, assuming you are using NiMH, is likely to not handle more than about 10A.

Do the math, and you'll see that 2 or 3 batteries need to be put in parallel to power your system.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on February 21, 2010, 06:51:17 AM
@Webbot ... Im doing it through programming... using servosDisconnect(bank) code, leaving only 1 servo...

@Admin ... hmm but, that won't affect the microcontroller right?... because, its datasheet says, it can handle up to 5A only?... but yea.. i'll try to add another battery in parallel then.
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on February 21, 2010, 06:58:48 AM
@Admin ... hmm but, that won't affect the microcontroller right?... because, its datasheet says, it can handle up to 5A only?... but yea.. i'll try to add another battery in parallel then.
A '6V battery' is a misnomer. Despite the name, its almost never 6V. When fully charged, it could be 7V. When fully drained, it can be 5V.

And when you suck huge amounts of current from a battery all at once, the voltage will temporarily drop. So lets say you suck 10A out of a battery with a voltage measured at 6V. That voltage could temporarily drop to 4V - but the Axon requires at least 5.3V to operate - causing a reset. A high quality battery can hold the voltage steady better than cheap batteries, and different battery types act differently.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on February 21, 2010, 08:11:00 AM
no no no nooo....

with Fully charged (6V - ~3200mAh) battery,that voltmeter measures as 7.24V, it actually works for some time without reseting (until I apply some torque on servos - OR - it's drained enough)...

HOWEVER, as i said, I have been using a DC Power Supply lately, keeping 6.1V constant, and varying the current (that can go upto 10A) but I was surprised that it turned out to be worse than the battery !? ...I have no idea why !
Title: Re: WebbotLib for 22+ Servos
Post by: KurtEck on February 21, 2010, 09:13:49 AM
Hi,
So far with my Brat with the Axon2, I have had no power issues with the 7 servos using 1 1600mah lynxmotion NIMH battery.

Also I do run my Lynxmotion CHR-3 hex robot that has 18 HS-645MG servos on one 2800mah 6v battery.  The servos are all plugged into an SSC-32, which is controlled by Basic Atom Pro BAP28 plugged into a Lynxmotion Bot Board 2.  However the reason this works is on both of these boards, there are two power inputs (VS and VL).  The 2800mah battery is only connected to VS.  When the servo are working it can and does pull the voltage below 5.x volts which would reset the processor(s).  So I have a second battery, which currently is another 1600mah NIMH.  On others I have used simply a 9v battery to run VL.  I know on the Axon2 you can unsolder some bridge to allow 2 batteries, but I have not looked yet to see if this separates the power going to the processor from the servo power.  If so I would strongly suggest that you take this route.

Edit: Side note: actually the SSC-32 has possible 3 battery inputs: VL/VS1/VS2.  This allows you to have a seperate battery for each of the 16 servo connections.  I have not used this capablity yet, but I believe others have...

Good Luck
Kurt
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on February 21, 2010, 10:59:35 AM
no no no nooo....

with Fully charged (6V - ~3200mAh) battery,that voltmeter measures as 7.24V, it actually works for some time without reseting (until I apply some torque on servos - OR - it's drained enough)...

This is still in-line with what Admin said.

When you think of the electrical characteristics of a battery, you have to imagine a resistor connected in series.

---| +     - |----/\/\/\-----   

This is called the battery's 'internal resistance'. This is the problem with drawing too much load, as the current out of the battery goes up, the voltage drop across the 'imagined' resistor goes up, so the voltage out of the battery goes down.

Now, the load (current) from the servos trying to move is going to be a 'noisy' or fast changing load. A regular volt meter is going to have a hard time measuring voltage or current accurately, as they have a very slow sample rate. The same goes for your bench power supply, it may be 'reporting' it's only sourcing 6 Amps, but it may be getting spikes higher then it's rated load, and droping out voltage.

 If you really want to see if the servo's are drawing too much and the voltage drop (from the batteries internal resistance) is resetting the Axon, you need to use a decent Oscilloscope to measure voltage or current, as a o-scope would be fast enough to give you a better idea of what's happening.
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on February 21, 2010, 03:06:05 PM
@Webbot ... Im doing it through programming... using servosDisconnect(bank) code, leaving only 1 servo...

Ok so as far as WebbotLib is concerned then the full number of 25 servos are still present. Whether they are 'connected' or not makes no difference to the library - it only effects whether the I/O pin has a pulse.
So if you've defined all 25 and use 'disconnect' to remove some - it makes no difference to the code. The code is still running all 25.

Therefore: it's NOT a software issue.
Title: Re: WebbotLib for 22+ Servos
Post by: dunk on February 21, 2010, 04:31:44 PM
Hasan,
what happens when you leave the program set up for all 25 servos but only physically plug one servo in?

if the servo works fine then the problem is the power bus.
if the servo exhibits problems then the problem is the program.


dunk.
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on February 22, 2010, 10:28:04 PM
Quote
I know on the Axon2 you can unsolder some bridge to allow 2 batteries, but I have not looked yet to see if this separates the power going to the processor from the servo power.
Yeap, you can separate mcu and servo voltages by removing the bridge.


and varying the current (that can go upto 10A) but I was surprised that it turned out to be worse than the battery !?
I repeat:
22+ servos means 22A+ peak.
;D
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on March 07, 2010, 06:38:41 AM
Sorry for the late reply...

@Dunk and Webbot, yes, 1 Servo connected would work perfectly fine, as it doesn't require enough load, even after external torque is applied. (yes, I do agree that "that" problem was because of the power supply)

As Admin also said, I need even higher current supply in order to let the servos take the load.
(I have changed the robot design a bit, and reduced the servos to "21" now - so I need up to 21A current)

I am having a hard time in getting more batteries (budget problem) and hence, in the meantime, I was trying to solve the other problem. That one is a software problem:

As already mentioned, (you guys must be fed up of hearing this actually, but) the servos do not hold tight... the reason as I could figure out was because of using more than 1 servo in 1 bank of Webbot Library.

The effect might not be noticable on 2 naked servos, but for my Robot, each servo is under some load, and it simply rotates if I use 2 or more servos in 1 bank. [I would request someone to try a large number of servos in 1 bank, and compare the servos' grip for 1 servo per bank]

For that reason, I asked a question in another* thread, about how to use 8-Bit Timers on Webbot Library in order to increase number of banks, (*since I assumed that I am just making a programming mistake - as I'm new to Webbot library).

Anyway, for the power problem, I will inform as soon as I buy more batteries, and plug in parallel to the existing 3200mAh 6V battery (that, btw, is also a combination of two packs).

Apart from the 8-bit Timer question, I do have a few more quick noob electronics questions:
1) How much in "mAh" would I require for around 20A Supply?
2) Wouldn't that damage the Axon uC, as it can support max ~5A?

Thanks Admin, Webbot, and others.

Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on March 07, 2010, 12:32:08 PM
@Dunk and Webbot, yes, 1 Servo connected would work perfectly fine, as it doesn't require enough load, even after external torque is applied. (yes, I do agree that "that" problem was because of the power supply)
Hasan999. I want you to think very carefully about that answer  :o. 
Our question was phrased very carefully - ie your code should be written as if ALL the servos were present - ie loads of them. But physically unplug all the servos except for one. After all - the software will still generate the pulses for all of the servos as it doesn't know or care if you've actually plugged them in or not.
If you are saying that is what you have done - then it is definitely NOT a software problem and more timers wont help. It is PURELY a supply problem.

However: if all you have done is to change your code so that it only knows about one servo - then thats a different story.


Quote
1) How much in "mAh" would I require for around 20A Supply?
Its kinda the wrong question. The "mah" suggest how long your battery will last ie a 3300mah battery can supply 3.3 amps for an hour. This suggests you could draw 20 amps for around 10 minutes.
But don't be fooled! If your battery is measured at 7.2V when fully charged and under no load then it DOES NOT mean it can provide 20 amps at 7.2V. If you draw a large load then the actual voltage will drop - and the more Amps you require then the more it will drop. This is why your Axon resets when you put a load on the servo as the current increases and the voltage drops.
Think of your battery as having a resistor on the power lead. And knowing that Volts=Amps * Resistance then as the Amps increases the Volts drop across the resistor also increases and hence you see a lower voltage at the input to your Axon.

You may have to do it by trial and error. ie start with one servo, put it under stress and measure how much the battery voltage falls. Try it again with two servos, etc.
Then add another battery and repeat your readings for 1,2,3 etc servos. The voltage drop will be less.
You will then get a better idea of how many batteries you need so that the voltage drop is not significant.






Title: Servos Do Not Hold Tight !
Post by: Hasan999 on March 07, 2010, 01:14:28 PM
ummm...  :-\

Webbot, there are 'two' different problems,

1) Battery Problem (thanks again, to You, Admin and Dunk, to help me figure out) - I will buy more batteries soon.

2) The Servo_not_holding_tight problem.

Unless you skipped the part where I described the 2nd problem's cause, I can actually prove (via a practical example) that both problems are not linked with each other.

Everything below is what I have tried (again) just now to illustrate the problem through observations :

I used 12 servos in 12 different banks:

Code: [Select]
SERVO_LIST servo1[] = {&S1};
SERVO_LIST servo2[] = {&S2};
SERVO_LIST servo3[] = {&S3};
SERVO_LIST servo4[] = {&S4};
SERVO_LIST servo5[] = {&S5};
SERVO_LIST servo6[] = {&S6};
SERVO_LIST servo7[] = {&S7};
SERVO_LIST servo8[] = {&S8};
SERVO_LIST servo9[] = {&S9};
SERVO_LIST servo10[]= {&S10};
SERVO_LIST servo11[]= {&S11};
SERVO_LIST servo12[]= {&S12};

Hence, using all 16-bit Timers, and when I run the problem, All the servos hold extremely tight.

When I still try to apply external torque (such that I actually drag like 6 servos by 90º against their will), the battery can resist that load (no axon reseting) ! (Point is: the power from my battery is more than sufficient for 12 servos)

So, there is no battery problem, in fact, no problem, in this case !

--> Now, I change the code to use 1 bank for all 12 servos:
Code: [Select]
SERVO_LIST servo1[] = {&S1,&S2,&S3,&S4,&S5,&S6,&S7,&S8,&S9,&S10,&S11,&S12};

Hence, using only (any) one 16-bit Timer, when I run the problem,

==> The servos do not hold tight at all... I can easily turn the position of the servos ! (it is same like, having at least 50ms delay between pulses, you can imagine !) ...btw, the battery can again, of course, resist any load here.

I really beg you, or anyone else, to try this !..

For my robot, I need all 21 servos to remain as tight as they are when I put them alone in each bank. Therefore, I need to use 8-bit Timers (as well) to have more banks.

Thanks  :(


Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on March 07, 2010, 03:41:00 PM
Lol Webbot, I already tried explaining internal resistance in this thread.


When you think of the electrical characteristics of a battery, you have to imagine a resistor connected in series.

---| +     - |----/\/\/\-----   

This is called the battery's 'internal resistance'. This is the problem with drawing too much load, as the current out of the battery goes up, the voltage drop across the 'imagined' resistor goes up, so the voltage out of the battery goes down.

Hasan,

Have you found the number of servo's where they start failing? You said 1 was fine but 12 is too much per bank, have you tried increasing up from one to see how many servo's per bank you can do before it starts delaying too long to keep the servo's powered?
Title: Re: WebbotLib for 22+ Servos
Post by: dellagd on March 07, 2010, 05:45:09 PM
um, I apoligize but I really tried to understand your problem.
Why cant you just use 12 banks for 12 servos (yes I am familiar with WebbotLib)?
does it make your code to slow?
to me it seems like you solved your problem but obviously you havent :P
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on March 07, 2010, 09:07:24 PM
Quote
2) Wouldn't that damage the Axon uC, as it can support max ~5A?
It can safely support up to ~13A (calculated, not tested). Thats per trace, however, so if you evenly distribute your batteries across the unregulated power bus you can safely keep the current below that value.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on March 08, 2010, 01:38:27 AM
Have you found the number of servo's where they start failing?

Yea, for only 1 servo in 1 bank, it holds tight as it is supposed to. For 2 servos in 1 bank the grip (of each servo) becomes slightly looser, and would keep getting looser as I add more and more servos in the same bank.

Why cant you just use 12 banks for 12 servos (yes I am familiar with WebbotLib)?

Sorry, you're familiar with WebbitLib, but you're not familiar with my problem :P ...I actually need to control 21 Servos (all should hold tight) - WebbotLib, apparently, works perfectly with up to 12 servos (and thats why I showed the observations while using 12 servos for an example, and also to make sure the battery is not the cause of the problem)

It can safely support up to ~13A (calculated, not tested).


Thanks, I think I'll be the first one to test that lol... you owe me an Axon uC if something bad happens  :P ;D

Still awaiting Webbot's reply...

Title: Re: WebbotLib for 22+ Servos
Post by: waltr on March 08, 2010, 11:16:30 AM
Quote
Tongue ...I actually need to control 21 Servos (all should hold tight) - WebbotLib, apparently, works perfectly with up to 12 servos (and thats why I showed the observations while using 12 servos for an example, and also to make sure the battery is not the cause of the problem)

I've been following this thread and have a thought.
Have you considered that you have just run into the limits of what the processor/code can do? It is very likely that 12 servos is the limit and still maintain the required refresh timing for the servos to hold position.

Could you consider using a second processor and splitting half (or less) the servos to this processor?
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on March 08, 2010, 05:43:00 PM

I've been following this thread and have a thought.
Have you considered that you have just run into the limits of what the processor/code can do? It is very likely that 12 servos is the limit and still maintain the required refresh timing for the servos to hold position.

Could you consider using a second processor and splitting half (or less) the servos to this processor?

This horse has been effectively beaten to death in this venture. We have all suggested a dedicated servo controller at one point in the many threads Hasan started on this topic.

There is no pretty way to run this many servos with a microcontroller AND be able to do everything else Webbot's lib can do; Webbot is facing an up-hill battle trying to support as many as he can. I think if anything comes of this, Webbot will be able to figure out the hard limit of servos he can support with his library; and only allow that number to be defined without getting a new Webbot error code.

As far as helping Hasan,

I think his only options are to write his own code for the Axon that 'concentrates' on running that many servos with little overhead much like the servo control software that he tried before,

 or get a dedicated servo controller and end his troubles.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on March 08, 2010, 11:34:10 PM
Have you considered that you have just run into the limits of what the processor/code can do? It is very likely that 12 servos is the limit and still maintain the required refresh timing for the servos to hold position.

Could you consider using a second processor and splitting half (or less) the servos to this processor?


We have all suggested a dedicated servo controller at one point in the many threads Hasan started on this topic.

There is no pretty way to run this many servos with a microcontroller AND be able to do everything else Webbot's lib can do;

Are you saying, indirectly, that the Admin has provided a false claim on the main Axon website when he mentioned that the servo can control up to '29 servos' with no conditions mentioned.

If an additional servo controller is required, Admin should provide it with the Axon itself (oh wait, then what is the point of Axon and its small size, and the 29 servo ports).

I do agree it would solve my problem, but it is not easy for me to buy one (I'm not in UK/USA etc) and waste another month making it work together with Axon.

Thanks for the tip anyway,

I still awaiting Admin's and Webbot's response.
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on March 09, 2010, 06:53:14 AM
Are you saying, indirectly, that the Admin has provided a false claim on the main Axon website when he mentioned that the servo can control up to '29 servos' with no conditions mentioned.

If an additional servo controller is required, Admin should provide it with the Axon itself (oh wait, then what is the point of Axon and its small size, and the 29 servo ports).

There is no false claim, you have proven that. You tried that computer controlled servo software (whose name i can't remember) and it was able to control your servos just fine. As far as the hardware of the Axon is concerned, you can run that many servos. It's not the Admin's fault that you have failed to write code efficient enough to provide control signals for that many servos.

It's nice that people like Webbot write software for the Axon to make it easier to use, but it's not a given that you will get software that does everything you need just because you bought a piece of hardware that says it's capable of doing it.
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on March 12, 2010, 03:40:04 AM
@Webbot, please reply to my post #50 ... and kindly let me know if it is possible? (to implement 8 bit Timers)...

Thanks.
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on March 13, 2010, 01:28:08 PM
I won't be implementing the 8 bit timers for now - for a whole number of reasons.

But rather I will try to come up with a new servo driver. Think I know what the problem may be (and it was introduced to stop frying Admins servos when originally testing WebbotLib!). If you PM me with your preferred contact details then I can send you something to test once I've done it - but it won't be quick as I've got a number of other things I'm working on and trying to complete.


Title: Problem Solved !
Post by: Hasan999 on March 14, 2010, 07:34:57 AM
@Webbot, your updated Library solved the problem !!

All servos holding tight + no Vibrations !

Thanks a lot !
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on March 14, 2010, 11:14:14 AM
I still stand by my claim for max servos on Axon. And that the problem here is poor power management, not code.

for example, this beast of a robot is controlled by the Axon:
http://www.lynxmotion.net/viewtopic.php?p=52438&sid=9405a421f585a32620e59ac69d4c25a5 (http://www.lynxmotion.net/viewtopic.php?p=52438&sid=9405a421f585a32620e59ac69d4c25a5)

It has at least 21 servos on it (rough count).

(http://lh6.ggpht.com/_b1-391vCRLM/SkqjTGkzO8I/AAAAAAAAAIY/zs7ZsJciiV4/s800/P6303436.JPG)
Title: Re: WebbotLib for 22+ Servos
Post by: Hasan999 on March 14, 2010, 11:34:29 AM
Yes Admin... it sure does  ;D

Me and Madsci were arguing about maximum num of servos 'while each holding tight' ...

When I used to use the normal AVR library, (since it doesn't use Interupts) I had this problem of "Servos loose and jitter".

Hence, I changed to WebbotLib, but unfortunately, I had the same problem again !.

Now, Webbot has modified his library, (added another servo driver - am not sure what exactly did he do), but all the servos (I tried 22, even 29 would) hold tight with no jitteriness !

PS. Admin, I can't re-modifiy the first post of this thread, can you please change the 'icon' to 'solved'?..thnx
Title: Re: WebbotLib for 22+ Servos
Post by: madsci1016 on March 14, 2010, 12:14:39 PM
Remember Hasan, you bought a piece of hardware from Admin. That piece of hardware can do many things, but it all depends on how it's programmed. You seemed to approach your questions with a sense of expectation for software to be already written to have the hardware you bought do what you want.

That's not the case.

You should be very grateful (as am I) that someone like Webbot donated his time to write software for your hardware, and that Admin did provide a base library for the hardware he sells.

Admin, if you read through all the pages of this thread, there was a power problem, as well as a code problem. Hasan managed to isolate both issues from each other. I'm assuming now he fixed the power problem with a few extra batteries.

Webbot, I'm curious to hear how you changed your servo drivers. Care to explain? Or i could wait to the next lib release.
Title: Re: WebbotLib for 22+ Servos
Post by: Admin on March 14, 2010, 12:19:06 PM
Oops sorry didn't see page 3 of this thread. I marked it as solved.


Webbot often sends betas off to certain people before making it official. I've been AWOL lately, taking a vacation off from my vacation, but I'm sure we'll see a new WebbotLib version soon.
Title: Re: WebbotLib for 22+ Servos
Post by: Webbot on March 14, 2010, 02:29:29 PM
Admin, ....  as well as a code problem.......

Well its not really a bug. The released code copes with a 'certain' number of servos. Hassan pushed this limit and got practical problems. My new code (unreleased as of yet) just increases this 'certain' number to make his problem 'go away'ish. But if anyone believes than they could drive 40, 60 etc servos - then they will get the same problem. There's only so much liquid that goes into a pint glass!!

So I haven't 'fixed' the code - I've just 'improved' it to cope with more.

Quote
Webbot, I'm curious to hear how you changed your servo drivers. Care to explain?

Ok - but its a bit complex. Maybe needs timing diagrams but I dont have time!

Version 1 (prior to release of WebbotLib - but just for the history)
Set the pin for the first servo in the bank.
Set timer callback for 'end of pulse'.
When called it cleared the pin.
Repeat for all servos in the bank.
Add a callback to be (20ms - (sum of all pulses)) - so that it repeats every 20ms.
This fried servos!
Heres why. Think of a bank of 8  servos and thing only about servo#6.
In the 20ms frame then its start time is effected by the length of the pulses for servos #1- #5
So if servos #1 to #5 now have a smaller pulse then the pulse for #6 will start sooner. Compare this to the start time for #6 on the previous frame then it can be less than 20ms.
This technique guarantees servo #1 getting a pulse every 20ms but the further down the bank you go then the pause between frames is effected more and more by the earlier servos.
Hence the later servos could 'fry' - as they may get pulses every 12ms say.

Version 2 - for first release and up until current release
Uses the same technique except that at the end of a bank it would pause for (20ms - the duration of the last servo pulse).
This guarantees a min delay of 20ms for all servos - so no frying!!
But it also means that the length of a frame is no longer '20ms' but is 'sum of all pulses + 20ms - last pulse'.
So as you add more servos then the frame time changes from 20ms upwards.
Hence Hassans problem of servos going floppy.

Version 3 - for next release and what Hassan is using.
For each servo in a bank we know the max pulse time (the center parameter + the range parameter for each servo MAKE) as well as the currently required pulse time.
So we will overcome the problem of Version 1 by making sure that each servo gets the start of its pulse every 20ms.
I do this by using one Timer Compare to start each pulse at which time it adds two callbacks: one clears the pulse after the required duration, and the other is called after the max pulse time to repeat for the next servo.
Once all servos are done then we pause for the rest of the 20ms (if any) since we did the first servo.
So the pulse start for ANY servo always happens every 20ms since it is always made up of a HIGH and a LOW phase where HIGH+LOW is constant.
The number of servos is constant and so the time for one pass is also constant
So the pause (if any) before repeating is always constant.
So I am now using 2 compare units for each servo bank rather than one.

I hope that makes sense (but it's not for newbs!).

And if you are just a user of WebbotLib then 'dont worry' - its just techno garb.