I’m going to head to radioshack later and pick up those capacitors, the problem only occurred when servo(s) were connected. Also I had to use a float for the scaling factor instead of a long int, since I needed access to decimals between zero and one. With no load everything works just fine, at the min and max positions, the servo sits with no noise. Once load was placed and it had to work against gravity, the servo is insanely load when it idles at either of these positions. I have seen some videos where servos only make noise when changing position but not necessarily when holding a position. I could be mistaken though. Although it could always be our linkage system not lining up with the rotation of the servo perfectly and causing the servo to fight for a position. Either way it is insanely loud. But it works which is more important to me right now.
I’ve gone ahead and made two 5 cell batteries form the one 10 cell that I had and it seems to be working fine. I haven’t run any endurance tests but I’ll get around to it. there doesn’t seem to be any noticeable change in performance or length, other then the fact that it isn’t nearly as hot as it use to be. But I can assume that we never got these errors before since we were getting a constant (and very hot) 6V through the line. Now its 6V or below, which might be causing the spikes or noise that you mentioned.
I went ahead and sodlered three of those 0.1uF capacitors to each power/ground for the baby-o, servo controller, and servo power. I still managed to get the same failures I was getting before, possibly more often then before, and set servo positions have changed. instead of stopping at its programed 4000 position it could be going as far at 5400 now. Whats worse is that it is now randomly choosing between stopping at 4000 and stopping at 5400.
Is it possible the capacitors can alter/increase/decrease the range of values the servo recognizes? I didn’t think the capacitors could hurt or hinder the setup, but unless I soldered them wrong, they seem to be making things worse. Any thoughts? Should I remove them one at a time and then see were the problem may be coming from?
No, the capacitors shouldn’t be having any effect on the motion of the servos. Where exactly did you put the capacitors? Unless you’re stripping your motor wires (which you probably don’t want to do at this point, for warranty-voiding reasons) you should have them between power and ground at the individual servo ports on the servo controller.
Another quick test you could do is for wired electrical noise vs airborne electrical noise. Try powering the Baby O and the servo controller from a separate battery (an alkaline 9V would work fine just for the test) and see if you can reproduce the problem. If not, this might just be your solution. If so, your super-servos are going to need to be farther away from your electronics, and twisting their wires could also help.
-Adam
I had all the capacitors at the power and ground for the baby-o, servo controller, and servo power. I moved them to the pins on the individual servo ports, like you said and noticed no change in performance. The code still randomly fires up the yellow warning led, and then finally either a fatal error led light show, or baud rate light show. All this is occurring on the servo controller. The baby-O continues to show operation leds normal. I eventually took out all the capacitors and again noticed no significant change in the consistency of errors. If I bend the sensor too slow, they go on, if I bend too fast, they go on. If I refresh the code, they go on. All at random intervals. I have to turn it all off, and then turn it back on before I can use it again. You can tell the situation is getting very frustrating for me.
I changed my val1 to a float, and my bend1 to a long int. to eliminate the possibility for decimals. I delayed the bend sensor read time to delay(30). Then I registered only averages of every ten values, then I tried only taking every 20th, 10th, and even value. None of these seemed to make a difference in determining were the error was coming from. The battery is on a cable about 3 feet long, and is generally always that far away from the electronics. The bend sensor is on a cable about just as long, and the servo is on a 24" extension cable. The only two electronics that are near each other are the baby-O and the servo controller, they are practically touching being as they are on a “project board” right now.
I’m so angry with it right now, I haven’t a clue as to why this is happening or how to control it. I’ll try and plug in a separate power source for the controllers tomorrow.
Sorry you’re having all this trouble, it really sounds like you’re doing everything right though (which probably makes it worse).
My only other thought at this point is that the servo extension cables (which, yes, I suggested a post ago) might actually be acting as antennae, broadcasting your motor noise. You could try putting your capacitors at the servo-end of the extension cables, or just removing them and running the servos straight from the controller. It’s worth a shot anyway.
If NOTHING will stop this problem and you need it working ASAP, there is a workaround. You can connect the reset pin of your servo controller to an I/O pin on your Baby O, and reset the servo controller before each command you send. I haven’t tested these servos specifically, but in my experience digital servos like yours usually hold their positions when they stop getting position signals from the servo controller, which will happen after you reset. It’s not pretty, but it should work.
-Adam
Well I narrowed down the problem. I’m getting either a short or a massive amount of electrical noise from the bend sensors. I figured it out by accident. But I can basically shake the wire and the quick disconnect that the bend sensor is wired through and I get a fatal error every time. I added a capacitor to the end of my extension line from the servo, and one between my ground and my power on my bend sensor. It made no difference. I took out the capacitor for the bend sensor and tried to re-solder everything. Somewhere along the line I must have screwed up because that line doesn’t work at all now. After three attempts to fix, re-solder, re-heat shrink, and re-wire the entire line, I got so fed up with it that I had to walk away.
I plan on coming back to this tomorrow and getting it at least back to the way it was in “working” condition. In the mean time, any ideas on what would cause such a problem. Is it that the power and signal lines are parallel, or that my 10KOhm resister on the power line isn’t enough? or do I just have bad connections. I also considered that the 20k-50k range might be too sensitive and the signal gets wacky as it travels through everything.
I have another sensor laying around I might just make a new line from scratch with no funny business and see if that makes a difference. the quick disconnecters that I’m using might be the problem.
I made a direct line with a spare bend sensor I had lying around and there was zero change in performance. I’m still getting fatal errors all over the place. I disconnected the servo again and I could not fail the controller. I have a capacitor on the servo end of an extension cord and it didn’t seem to help. I took a multimeter to all the connections. My battery is putting out around 6.5V before the regulator. After the regulator I’m getting a fairly smooth 5.96V signal from all the pins in some voltage input. The servo itself is ranging somewhere between 5.98 and 4.88V depending on what its doing. The bend sensor is getting around 4.98 at VCC and the signal is around the same.
Could it be a problem with amperage? I didn’t check for that at the time. I’m planning on buying this type of bend sensor later today. I’ll have to order it, but I’m hoping it might help. Any thoughts on what could be the cause?
Still sounds like electrical noise from the motors to me, but there should be a way to mitigate it. My two thoughts right now are to try shortening all of your wires temporarily (plug servos straight into the controller, shorten sensor wires if possible) and also try powering the Orangutan and servo controller logic from a separate battery. If either of those helps at least you have a point to work from.
That bend sensor from sparkfun looks like it only changes resistance in one direction, is that okay for your project?
-Adam
It should be. It’s going in a glove to be used by the index finger. So I need to eliminate the pressure sensitivity that these have. But yes bending in one direction should be just fine.
I plugged the servos directly into the port using just the 10cm cable it came with. I used my current bend sensor on a wire about 20" long. The performance improved but did not eliminate the problem. I’m going to try the brute technique you suggested of resetting the servo controller for every set period of time. I’ll also change the resolution to 10bit, as well as taking less values. Hopefully it’ll smooth out.
The ACC134 voltage regulator states its rated for 10 watts of power dissipation, and can handle up to 10A of current. Our batteries are 1600mA could this be part of the problem? The servos are drawing more power then the regulator can put forth and it’s failing. It makes sense since I can’t fail the system unless a servo is plugged in.
Your batteries have a capacity of 1600mAH, or milliamp-hours. So, theoretically you could draw 1.6 amps from them for 1 hour on a fresh charge, or 0.8 amps for two hours, etc… The capacity of the battery doesn’t make much difference here.
How many did you say you were running, three? Those are some torque-normous servos, so it’s possible they’re trying to draw more than the 10-amps of current that the regulator can source. You might try checking it with an ammeter. As for power dissipation, your regulator is only dropping the battery voltage by 1V. At 1V, it will need to dissipate 10 watts when it’s sourcing 10 amps, so you’re back to the same constraint. You might try running only one or two servos to see if that fixes things.
Actually, now that you’re using 5-cell packs, if you suspect the regulator is the source of the trouble you can try just eliminating it and running battery power straight to the servos. At full charge your pack will sit at 7V, and that will start dropping very quickly.
-Adam
Currently I’m only running one servo when all of these problems occur. I will be running three when its done which is why I wanted to do the battery life testing early. Today for whatever reason I had problems with my serial port or something. The baby-O will blink leds and function normally. And the servo controller will sit with a yellow led idle. But once I program them, the green led flashes a couple times and then all the leds go out. I cleaned up all the lines, re-ran and re-soldered them, but no dice. I hope I didn’t blow something again.
I’ll take out the regulator and see what happens. (once I get everything worked out)
I took the regulator out and everything manages to work fine. I did a bit a code tweaking to get everything the way I wanted it. I’m posting a more generic version of the code for anyone interested in doing something similar. It’s currently set up for 2 bend sensors and 3 servos. Thanks for all the help, I couldn’t have done it without you.
#define F_CPU 20000000//Baby Orangutan CPU clock
#define BAUD 9600//baud rate for UART
#define MYUBRR 129//(F_CPU/16/BAUD-1)//baud rate variable for UART hardware
#include <pololu/orangutan.h>
#include <avr/io.h>
void USART_Init(unsigned int ubrr){//Initialize USART hardware & settings for Serial Radio
UBRR0H=(unsigned char)(ubrr>>8);//set buad rate
UBRR0L=(unsigned char) ubrr;
UCSR0B=(1<<TXEN0);//enable transmitter
UCSR0C=(3<<UCSZ00);//Set frame format for 8bit with 1 stop
}
void USART_Trans (unsigned char data){//Transmit a byte of data over USART
while(!(UCSR0A&(1<<UDRE0)));//wait for transmition to complete
UDR0=data;
}
void put(unsigned char servo, unsigned long int angle){
//servo is the servo number (typically 0-7)
//angle is the absolute position from 500 to 5500
//Send a Pololu Protocol command
USART_Trans(0x80); //start byte
USART_Trans(0x01); //device id
USART_Trans(0x04); //command number
USART_Trans(servo); //servo number
//Convert the angle data into two 7-bit bytes
USART_Trans(((angle>>7)&0x3f)); //data1
USART_Trans((angle&0x7f)); //data2
}
void servoOff(unsigned char servo){//turns off a servo
//(servo will go limp until next position command)
//servo is the servo number (typically 0-7)
//Send a Pololu Protocol command
USART_Trans(0x80);//start byte
USART_Trans(0x01);//device id
USART_Trans(0x00);//command number
USART_Trans(servo);//servo number
USART_Trans(0x0f);//data1 (turn servo off, keep full range)
}
void servoSetSpeed(unsigned char servo, unsigned char speedcmd){
//servo is the servo number (typically 0-7)
//speed is servo speed (1=slowest, 127=fastest)
//set speed to zero to turn off speed limiting
speedcmd=speedcmd&0x7f;//take only lower 7 bits of the speed
//Send a Pololu Protocol command
USART_Trans(0x80);//start byte
USART_Trans(0x01);//device id
USART_Trans(0x01);//command number
USART_Trans(servo);//servo number
USART_Trans(speedcmd);//data1
}
void mirror(unsigned char servo, unsigned char servoMirror, unsigned long int angle){
put(servo,angle);
put(servoMirror,(6000-angle));
}
float val1; //servo 0 & 1
long int bend1;
float val2; //servo 2
long int bend2;
long int servo1_open; //declared variables
long int servo1_close;
long int servo2_open;
long int servo2_close;
long int servo2_neutral;
int main(){
set_analog_mode(MODE_10_BIT);
start_analog_conversion(0); //PC0 (servo 0 & 1)
start_analog_conversion(1); //PC1 (servo 2)
USART_Init(MYUBRR);
servoSetSpeed(0,0); //Set Servo Speed (no limiting)
servoSetSpeed(1,0);
servoSetSpeed(2,0);
servoOff(0);
servoOff(1);
servoOff(2);
//================ Set Soft Limits ================
servo1_close = 1800; //set soft limits (for servo 1 not servo 0)
servo1_open = 3800;
servo2_open = 1490; //set servo 2 soft limits
servo2_neutral = 3000;
servo2_close = 4485;
//================ Start While Loop ================
while(1){
val1 = (float) analog_read(0); //read PC0 (servo1)
val2 = (float) analog_read(1); //read PC1 (servo2)
bend1 = (long int)((((float)(val1)*5500)/1024));
bend2 = (long int)(((float)(val2)*5500)/1024);
//================ Servo 0 & 1 Soft Limit ================
if(bend1 <= servo1_close){ //stop once fully closed
bend1 = servo1_close;
}
if(bend1 >= servo1_open){ //stop once fully open
bend1 = servo1_open;
}
//================ Servo 2Soft Limit ================
if(bend2 <= (servo2_neutral + 500) && (bend2 >= (servo2_neutral - 200))){ //stay neutral in this range
bend2 = servo2_neutral;
}
if(bend2 < (servo2_neutral - 200)){ //jump to fully open
bend2 = servo2_open;
}
if(bend2 > (servo2_neutral + 500)){ //jump to fully closed
bend2 = servo2_close;
}
//================ Go-To Positions ================
mirror(1,0,bend1); //set servo 0 & 1 angle as bend1
put(2,bend2); //set servo 2 angle as bend2
delay_ms(30);
}
return(0);
}
Fantastic, I’m glad you got everything working (and thanks for posting the code).
Any chance of posting some pictures and/or videos of your project in action?
-Adam
Thanks for all your help, this wont be the last time I get an opportunity to use the Pololu products, once I get some money there are some ideas floating around that I had that are much more tangible now then they were.
Unfortunately The school project was funded by a private company that made the group members, myself included, sign nondisclosure agreements, and I’m contractually bound, not to post anything, (I asked.) Considering my grade and graduation are on the line, I’d rather be safe than sorry. I saddens me because I would really have liked to post some videos and picture (which we do have). In truth there is no reason that in the future I couldn’t make a very similar (but non related) rig and post pictures of those.
Thanks for all the help.