School Project

That worked out great. Thanks. I spent some time last night figuring out my mirrored range of values, since the servos respond to something like 1500 - 4450, so not every value worked. I think I’m limited to 1550-4450 now which makes sense. Also I ran an “endurance” test last night to see how long the battery would last. I ran four servos continuously and monitored the time with a time laps video. After 2 hours, I gave up and turned everything off. Then it only died an hour after that when I went back to coding and testing. So almost 3 hours of continuous use. That triples my required time. My only problem was that it was then that I found out my 6V regulator was only rated for 8.4V max input. Well, I’m running a 12V battery through it. Lets just say that over a 2 hour period (and probably long before that) it felt like a few degrees below on-fire.

My solution is to simply remove 3 cells form the 10 cell battery, and cut it down to 8.4 V. if the ratio is linear then 15 minutes per cell (2.5 hrs divide 10 cells) will be 1.75 hrs per 7 cells.

All I have left to do is incorporate the analog1 sample code that I got the bend sensors to work for and figure out how to stick it in this code to work. I figure I’ll need some true/false if statements to limit the range of the bend sensor so it doesn’t register values that will send my servo somewhere it doesn’t belong.

And after all the work for the mirror command, I found our linkages were not symmetrical enough and I ended up with a lot of binding, twisting, and anger servos, both fighting for position. For now we took out one, which seems faster,quieter,less drain on battery (as if that was an issue) and can handle the load without even trying. I found that when the servo is holding a position it is very loud, I know its because its on and fighting to hold a load at a set position against gravity, but is there any way to dampen the sound?

Sorry to hear that the two-servos on one linkage didn’t work out. I think when you do that for long model airplane flaps you usually have a little compliance in the flap material, or a flexible coupling between the servos and the shaft. But if you can get away with just one servo doing the work of two, that’s probably the simplest solution.

I forget if you posted this already, but what kind of servos are you using? Is the bare servo with nothing connected to it loud, or is it holding some heavy load in place? If your servos are straining under the load they’re holding, the only way I know of to quiet them down is to get better servos with a higher torque-rating.

Taking a few cells out of your battery pack sounds like a good plan, will your charger work with 7 cell packs as well? And from the product description I wasn’t sure if your big regulator was linear or switching, but if it is a linear regulator it has to dissipate a lot of energy as heat to drop the output voltage, all of which is wasted. I wouldn’t be surprised if you still got close to three hours of use out of your 7 cell pack, sine the regulator will be wasting much less energy to drop the voltage.

-Adam

I’m using Hobbico CS-170 titanium geared ultra torque dual BB. 250 oz-in @ 0.19sec 4.8V. and 333 oz-@0.15sec 6V. They are way overkill for the load (about 3 lbs max), but with the linkages the transmission of force makes a difference (but not much) I think they are just noisy in general and the linkages are all direct, so it might be trying to twist a little too and we might not notice.

The charger says it will work for anything >900 mAh, and anything in between 6 -12V. One of my group members suggested running 5 of the 10 cells in parallel and knocking down the voltage to 6V and doubling our current to around 3200mAh which sounds like the best option.

I took the shrink material off the battery and it seems the connections were all spot welded. I saw one solution online which involved snipping all of the connection and soldering wires to the ends were I need them instead, then wrapping up the battery again.

We are going to run some testing today and make a final decision whether to use one or two servos. Now that I understand that mirror command, it makes no difference to me how many we use.

Yowzer, those are some nice heavy duty servos!

You’ll probably find you have a hard time soldering directly to the NiMH cells (although it can be done), plus heat is really bad for them, which is why those spot-welded tabs are generally used. Your best bet is to cut the tabs in the middle, then try to solder to whats left of them.

In general I would recommend against hooking up batteries to charge/discharge in parallel. When you get a battery pack with cells in parallel from a manufacturer, those cells have generally been “matched,” or paired for similar charge/discharge characteristics. They also get put together when they’re brand new, and stay in parallel for every charge/discharge, so they tend to wear and age together. The problem with putting used and unmatched cells together in parallel is that they will charge and discharge at different rates. As the voltage on one gets a little higher than the other, you’ll have current flowing just between the two cells. This wastes a little energy as heat, but more importantly it wears out the battery pack significantly more quickly.

Now, that isn’t to say I haven’t done it. You do get a longer lasting battery pack for a while. With NiMH batteries it would work fine, but with some other battery chemicals like Lithium Ion or Lithium Polymer it can be downright dangerous though. Keep in mind that as long as the input voltage is higher than the regulator’s cutoff voltage, you should still get close to the same runtime out of a single-series pack.

Another thing you might consider doing is cutting this pack apart into two separate 5-cell packs. That way you can charge one while running down the other, and you won’t ever be stuck with one big dead pack when you need to run your project!

-Adam

I like that idea, worst case scenario is it doesn’t last as long as I need it too (which, like you said, it should). I have two of these batteries laying around just for that reason, charging and draining back and forth. I want to leave one battery unmolested in case something bad happens, but as long as I have one plug and 10 cells, I can make at least one battery of some configuration.

Like you said, it’s probably easiest for me to start with one 5 cell series and then add more if I need them.

So I managed to get one 5 cell battery done and working. I tried to get back to working on the bend sensor code that I need in order to get the servos to work properly. I checked out the code in this thread. I tried incorporating it into what I currently had and it compiled nicely but the bend sensors are not returning any that actually moves the servo, and half the time when I try to program the controller I get an “fatal error” or “baud rate” error LEDs on the servo controller. The other half of the time I get no errors. Hopefully its just something stupid that I missed, or the values that I used for the bend sensor might be way off. On that note I still haven’t figured out how to do any real-time debuging or datalogging so that I can actually determine the values of the bend sensor. Thanks in advance for any light you can shed on this.

    #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 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 int angle){
       put(servo,angle);
       put(servoMirror,(6000-angle));
    }

	unsigned int val1;
	unsigned int bend1;

    int main()
	{

		PORTC=0x00;
		set_analog_mode(MODE_8_BIT);
		start_analog_conversion(PORTC=0x00);
	

       	USART_Init(MYUBRR);

       	servoSetSpeed(0,0);
       	servoSetSpeed(1,0);
	
	   // mouth center = 2300
	   // mouth closed = 1700
	   // mouth open = 4000

		mirror(0,1,1700);	//close mouth
		delay(800);

		mirror(0,1,4000);	//open mouth
		delay(800);
		
		mirror(0,1,1700);	//start mouth closed
		

		while(1)
		{

		val1 = analog_read(PORTC=0x00);
	    	
		bend1 = ((val1*4000)/255);


		if(bend1 > 4000)  //stop once fully open
		{			
			bend1 = 4000;
		}
		
		if(bend1 < 1700)	//stop once fully closed
		{
			bend1 = 1700;
		}

	
		mirror(0,1,bend1);	//set mouth angle as val1	
		

		}
	   return(0);
   }

Yay 5-cell. Now you can wire power straight to your Baby-O, no problem!

Real-time debugging is quite handy. Serial debugging is probably simplest way to go on the Baby Orangutan, but the logic-level serial signals generated by the Baby O are incompatible with computer serial ports, which use an inverted serial signal at much higher voltages. To connect your Baby O to a computer for debugging you would need a USB or RS-232 to TTL serial adapter. You could also do something creative like connect LEDs and resistors to each pin of a port, and light them up to display 8-bit numbers in binary (I’ve totally done it). You could even just use the built-in LED to do a simple check, having it light up when your sensor returns greater than a certain value. This LED happens to be on the serial transmit line, so you wouldn’t be able to manipulate it while using the USART. On the other hand, you have your servo controller and servos working, which could be a decent debugging tool itself.

But first for a little offline debugging of your code. The “PORTC=0x00;” line isn’t necessary, but it also isn’t hurting anything. The line:

val1 = analog_read(PORTC=0x00);

is a little odd, you don’t need to set the PORTC register at all, just specify the number of the analog channel you want to read from. If you’re wiring hasn’t changed recently, you have your analog sensors connected to PC0, and ADC6, so you would get readings from them by calling:

val1 = analog_read(0);//Read PC0
val1 = analog_read(6);//Read AD6

In any case, the line as written should be checking the analog input value on PC0 anyway.

Another problem I can spot is your scaling function:

bend1 = ((val1*4000)/255);

Val1 is an unsigned int, which on an AVR can have values between 0 and 65535 (2^16-1). Since you just loaded it with a MODE-8-BIT ADC value, it is currently set to something between 0 and 254, which you are trying to scale to a value between 0 and 4000. The problem is that when you multiply val1 by 4000, the immediate result may be more than 65535, in which case you would loose all but the remainder. Since you’re dividing the result of that multiplication by 255, your result will always be somewhere between 0 and 257. For example, lets say val1=255:
Normaly: (2554000)/255=(1020000)/255=4000
But since the intermediate results are limited to 16 bit values: (255
4000)/255=(1020000)/255=(36960)/255=144

There’s a quick remedy for this, however, called type casting. Essentially its telling the AVR to treat (cast) a variable as if it were another type of variable. If you write the formula this way, the AVR will allocate 32 bits (0 to 4294967295) for the intermediate values of the calculation:

bend1 = (((long int)val1*4000)/255);

The only other possible problem I see is that your while(1) loop will be running very quickly. Servo position can only be updated every 20ms anyway, so you might consider adding a delay that long or longer inside your loop, just to give the servo controller some time to react to what you’ve sent it before sending it another command.

-Adam

It alive! It’s alive! It works, its a little jittery and the signals are large enough to incur the if statements setting the max and min, which also work. I added a delay(30); right after the mirror(0,1,bend1); command which seemed to help. One problem I encountered immediately was that when the sensor bends too fast I get baud rate leds on the servo controller and the whole thing fails on me. I have to turn it off and back on to get it working again. This is bad because I need this thing to go as fast as possible, which it was doing fine until I went too fast with the bends. If I have time later I’ll try and set some delays on the bend sensor to only take values every delay(30); Also when the bend sensor is unbend it registers a value less than 1700, which I expected but when it hits the “if” loop I get a done of jitter, can I correct this in the scaling function? If so I can spend some time playing with the numbers until I get something that works.

Also The sensors I bought were advertised as bi-directional but for now they read the same values in both directions. I was hoping one side would be negative and the other would be positive in values since my second bend sensor needs control a servo that will start at a set neutral position and then travel “up” and “down” as the bend sensor bend up and down.

I’ll do some more research and see if I ended up buying the right sensor. these are the ones I bought. The first one the FLX-01. I see now the second one on the list has an increase and decrease in resistance, which is probably the one I should have gotten.

Can I still make these work?

Awesome! Glad to hear that its alive and kicking!

Yeah, looking at the website I agree, if the flex sensor you have does the same thing (decreases resistance) when you bend it in either direction there really isn’t a way for your microcontroller to tell which way you’re bending it. You can scale and shift the values though, so that unbent is at one end of the servo range, and fully bent is at the other. Or you could do something really sneaky like mounting a microswitch underneath the sensor, such that it gets pressed by the bend sensor when you move it in one direction. Let me know if you want to try this, it’s also a good idea to use some smaller resistors (1K or 2K) in line with the switches.

As for the servo jitter, you’re still updating the servo position 30 times a second, which is probably more than you need to. You might try longer delays, or averaging several readings, or using 10-bit mode on the ADC (results 0-1023) just to give yourself more possible positions, or some combination thereof.

As for the servo controller being unhappy with your serial commands, I doubt it actually has anything to do with the software. With those big beefy servomotors my guess is that you’re getting electrical noise on the data lines, either directly (conducted over common wires) or indirectly (electrical charges induced through the air). I would suggest you try running everything the same way, but with the servos unplugged. Can you still get the servo controller baud-rate LEDs to come on? If not it’s electrical noise.

If this is the case, you could try moving the power connection for the servo controller electronics and the Baby O back to the battery side of your big servo power regulator (if they aren’t there already) and adding capacitors between power and ground, on the servo power bus and/or at the power input pins of your servo controller and Baby-O. Here’s a little more info.

-Adam

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