Beginners: please read this post and this post before posting to the forum.
0 Members and 1 Guest are viewing this topic.
#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 bauduartInit(UART0, 115200);//uartInit(UART0, 19200);// Tell rprintf to output to UART0rprintfInit(&uart0SendByte); // Initialise the servo controllerservosInit(&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 ìSTICK_COUNT appInitSoftware(TICK_COUNT loopStart){return 0; // dont pause after}// This routine is called repeatedly - its your main loopTICK_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; }
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 Huh
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.
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'.
now is the time to prove it is possible
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.
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'.
// 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 64void appInitHardware(void){uartInit(UART1, 115200);rprintfInit(&uart1SendByte); //distanceInit(sensor);// Initialise the servo controllerservosInit(&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 loadservosDisconnect(&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 uSTICK_COUNT appInitSoftware(TICK_COUNT loopStart){return 0;}// This routine is called repeatedly - its your main loopTICK_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; }
Any 1 Servo works fine !...holds firm enough and if I drag its position forcefully, it can take the load (maybe 1.5A+)
@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.
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)...
@Webbot ... Im doing it through programming... using servosDisconnect(bank) code, leaving only 1 servo...
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.
and varying the current (that can go upto 10A) but I was surprised that it turned out to be worse than the battery !?
22+ servos means 22A+ peak.
@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)
1) How much in "mAh" would I require for around 20A Supply?
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};
SERVO_LIST servo1[] = {&S1,&S2,&S3,&S4,&S5,&S6,&S7,&S8,&S9,&S10,&S11,&S12};
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.
2) Wouldn't that damage the Axon uC, as it can support max ~5A?
Have you found the number of servo's where they start failing?
Why cant you just use 12 banks for 12 servos (yes I am familiar with WebbotLib)?
It can safely support up to ~13A (calculated, not tested).
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?
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).