Society of Robots - Robot Forum
Software => Software => Topic started by: Canabots on May 07, 2009, 06:41:49 PM
-
Hey Guys.
I'm trying to make my servo turn for a specified amount of time, then turn in the opposite direction for the same amount of time. I am using the Axon.
Here is my code sofar:
void scan(void)
{
int i=0;
int j=5000;
long int wheel_left=500;
for(i=0;i<j*500;i++)
{
wheel_left=850;
}
for(i=j*500;i>j*499;i--)
{
wheel_left=500;
}
wheel_left(wheel_left);
delay_ms(20);
}
For some reason, the servo will move in pulses until it reaches a certain point, then it just stays there...
Any input or ideas as to what might be wrong with my code?
-
Any input or ideas as to what might be wrong with my code?
first, this is impossible:
int j=5000;
int only goes to 255 . . . make it a long int . . .
same for i
-
So I changed it. I removed the variable "j" since I didn't end up needing it and changed "i" to a long int.
Here's the code:
void scan(void)
{
long int i=0;
long int wheel_left=500;
for(i=0;i<65535;i++)
{
wheel_left=850;
}
for(i=65535;i>65535;i--)
{
wheel_left=500;
}
wheel_left(wheel_left);
delay_ms(20);
}
But it does the same as before...
-
for(i=65535;i>65535;i--)
should be
for(i=65535;i>0;i--)
-
for(i=65535;i>65535;i--)
should be
for(i=65535;i>0;i--)
I think that makes it worst :-[ Now, the servo doesn't move or do anything at all, as if no commands are being sent.
Thanks for all your help sofar Admin
-
Instead of using the variable wheel_left, I decided to try commanding the servos with "servo(PORTx,Pin,position)"
This made it work...like the first post.
-
Throw in some rprintf statements and see what it's doing with hyperterminal.
Also, check your voltages.
-
I'm fairly certain it's not voltage, since when I use the Roborealm software for controlling servos, they respond with no problems. I'll check anyway.
I will add a couple rprintf statements, though don't expect to hear from me until next week, as I am busy this weekend.
Thanks! :)
-
I think the problem is that you update the servo position at the end of the scanning loops. You must update it inside the loop.
Can you post the code you are running now ? I'm a bit lost with your modification :)
BTW:
Any input or ideas as to what might be wrong with my code?
first, this is impossible:
int j=5000;
int only goes to 255 . . . make it a long int . . .
same for i
int a 16 bits, so it's between -32768 and 32767.
char are 8 bits, long int are 32 bits and long long int are 64bits. Assuming you are using AVR GCC / Win AVR (and probably other compilers but I'm not sure).
Chelmi
-
Try changing both your variables from 'long' to 'unsigned long'
-
I think the problem is that you update the servo position at the end of the scanning loops. You must update it inside the loop.
Can you post the code you are running now ? I'm a bit lost with your modification :)
I think you may be on to something. I modified the code to update servo positions at the end of each FOR loop, though no way of determining if it's the problem until I can test it later. Though I think that may be it. :)
This is my change in the servo code:
instead of doing this:
wheel_left(850);
I would use this:
servo(PORTE,6,850);
It is currently irrelevant since I'm using the wheel_left commands again :P
-
Ok, so I changed and tested my code, but it still does the same thing. For some reason my rprintf statement isn't working either...
rprintf("Servo_Position=%d%d\r\n", wheel_left);
All It shows is "System Warming up" and "Initialization Complete" which is odd since I only modded it a bit from what I was using in a previous test...
Admin, what type of code did you use for those ERP and movement demos where only the arms would move and such? I just wanna see a sample so I can tell maybe what I'm doing wrong.
-
All It shows is "System Warming up" and "Initialization Complete" which is odd since I only modded it a bit from what I was using in a previous test...
Sounds like a low battery problem . . .
Admin, what type of code did you use for those ERP and movement demos where only the arms would move and such? I just wanna see a sample so I can tell maybe what I'm doing wrong.
I used the SoR Biped Engine with the latest released Axon code.
-
Just measured voltage again, looks like the level is dangerously close to the minimum at 5.6V. I'm going to swap them out and get back to you.
-
Yea, with any microcontroller, if you say to yourself 'what the heck it was just working, nothing much changed, and now suddenly its acting all strange?!', that typically means low battery. :P
Took me years to figure that out . . .
-
Ok, changed the batteries.
And for some reason it doesn't work...
I think I'm going to first try starting a completely new project, completely fresh, and ad my code to control.c This way, if it's an issue with the other code, then my problem's fixed.
Otherwise, I'll keep debugging the old one.
-
Alright! Started a new project for this some older code in AVR Studio and it is now back to working like it used to ;D which means that Hyperterminal works again!
At first, it looks like my servo controlling code would always stop at the 800 value. So I changed my code a little. Now instead of one subroutine named "scan"I have 2 named "scan1" and "scan2". Upon doing this, I think I discovered the problem. I have to declare "wheel_left(wheel_left)" inside the FOR loops, which fixes it at only one value.
As for why it moves in pulses, I don't know. Though when observing the Hyperterminal, after about a second (I think), it stops, and says "System Starting Up" and then "Initialize". Then it displays values again. When I try the default Photovore code, the transfer is continuous, so I know it's something wrong with my code. Any ideas?
So now I guess I just have to figure out how to make it not stop at the first FOR loop. Does anyone know how?
Here is my code with the 2 subroutines.
void scan2(void)
{
long unsigned int i=0;
long unsigned int wheel_left=500;
for(i=0;i<500;i++)
{
wheel_left=350;
wheel_left(wheel_left);
delay_ms(10);
rprintf("Wheel_Value=%d%d\r\n",wheel_left);
}
}
void scan1(void)
{
long unsigned int i=0;
long unsigned int wheel_left=500;
for(i=0;i<500;i++)
{
wheel_left=900;
wheel_left(wheel_left);
delay_ms(10);
rprintf("Wheel_Value=%d%d\r\n",wheel_left);
}
}
Also, here is what void control(void) looks like
void control(void)
{
scan2();
scan1();
}
-
So to make sure I could really control a servo using the Axon, I just did the following test.
PORT_ON(PORTA,7);
delay_ms(2);
PORT_OFF(PORTA,7);
delay_ms(20);
This did make the servo turn all the way.
But there is still the annoying pulse thing! It moves the servo in pulses, with the exact same timing as the System start up and initialization in Hyperterm.
-
for(i=0;i<500;i++)
{
wheel_left=350;
wheel_left(wheel_left);
delay_ms(10);
rprintf("Wheel_Value=%d%d\r\n",wheel_left);
}
I see in your code that you are allowing only 10ms between servo pulses. Some servos will spass out if you do that, so increase that delay to 20ms. What servo are you using?
-
Yes, I've noticed that and changed the ms pulse to 20. I was just trying out different pulse values and forgot to change it back :P
As for the servos, they are HS-311 servos
-
I'm kinda stuck on this . . .
Get out an oscilloscope and take measurements of the PWM.
-
I don't have an oscilloscope...unless you mean the Axon :P But I don't know how to run my program at the same time as the O-scope program...
I decided to try using a system very similar to that you used on your old ERP robot with the $50 board. Sofar it's gotten rid of the wierd movement of the servos in pulses, though all the servos do now are twitch :D Still working on it.
Code in my .h file (for the servo motions)
long int i=0;
long int j=0;
void servo1(signed int position)
{
PORT_ON(PORTA,7);
delay_ms(position);
PORT_OFF(PORTA,7);
}
void servo2(signed int position)
{
PORT_ON(PORTE,6);
delay_ms(position);
PORT_OFF(PORTE,6);
}
void scan(void)
{
for(j=0;j<500;j++)
{
for(i=500;i>0;i++)
{
servo1(2);
servo2(1);
delay_ms(20);
}
}
for(j=0;j<500;j++)
{
for(i=500;i>0;i++)
{
servo1(1);
servo2(2);
delay_ms(20);
}
}
}
In control.c
void control(void)
{
while(1)
{
scan();
}
}
-
An idea . . . rprintf any and all variables (especially the ones that change) in your FOR loop.
Also, maybe you mentioned this before but, what is your battery voltage and type?
-
My batteries are Alkaline batteries.
I just popped them in and their voltage is at 6V.
So rprintf i and j and all that?
Thanks
-
My batteries are Alkaline batteries.
Dude thats your problem (well plus your earlier code mistakes)! Alkaline just can't supply enough current.
Go by some NiMH or NiCad batteries and move on, lol. :P
-
If it can't supply enough current, why do the servos work fine with the servo controller? Unless it uses less power because of the pc connection...
Also, what type of current rating should I looks for? I suppose I'd plan to use this for around 10 servos atleast (I plan on making a Quadruped robot).
-
If it can't supply enough current, why do the servos work fine with the servo controller?
hmmmm good point lol . . .
Also, what type of current rating should I looks for? I suppose I'd plan to use this for around 10 servos atleast (I plan on making a Quadruped robot).
allow for 0.5A per HS-311 servo, then just look up the max current rating of the servo
-
If it can't supply enough current, why do the servos work fine with the servo controller?
hmmmm good point lol . . .
So does this mean that the battery is the problem? Or still just some stupid error in the code that everyone has missed? Lol I'm becoming totally confused :D
Thanks
-
Can you explain exactly what you servos are doing wrong in more detail? (assuming it's changed from the first post)
-
Ok
Can you explain exactly what you servos are doing wrong in more detail? (assuming it's changed from the first post)
With the latest code I posted the servos will "twitch" continuously. There are no breaks while twitching. The motion is going side-to-side, always at the same rythm. It also seems like the motor changes direction each twitch.
I'm going to try some testing without the FOR loops to see if they are the problem.
-
Is it big twitches or little twitches? Does the servo at least move to the right spot before twitching?
-
The servos will turn to their first specified point (for servo1, it's all the way to the left, and servo2 is all the way to the right). After this, the twitches are about 2-3* to the right and left.
To me, it looks like the program is not going to the second command. I think I'll try shortening the FOR loops, perhaps they are too large...
-
Haha! I made it work (sort of).
I decided to try it by putting a plain old FOR loop in void control(void) itself like this:
void control(void)
{
while(1)
{
for(i=0;i<40;i++)
{
servo1(1);
servo2(2);
delay_ms(20);
}
for(i=0;i<40;i++)
{
servo1(2);
servo2(1);
delay_ms(20);
}
}
}
This moved the servos just how I wanted it.
When I tried putting these loops in subroutines, I got the same twitching result as the post above.
This brings up an issue though, why can't I make it work in a subroutine? This needs to be in a subroutine as I don't want to have to program a walk gait every time it pops up when I start my quadruped. Same with the robot arm I'm currently building.
Thanks for your help Admin! ;D
-
So, does anyone know why my code doesn't work if it's put in a subroutine?
If I were to put it in a subroutine, it would be like this:
void test(void)
{
for(i=0;i<40;i++)
{
servo1(1);
servo2(2);
delay_ms(20);
}
for(i=0;i<40;i++)
{
servo1(2);
servo2(1);
delay_ms(20);
}
}
But on the Axon, it won't work :(...Any ideas?
-
...I don't mean to be pushy, but does anyone have any ideas for this?
-
Here our some 'off the top of my head' thoughts...
1. Your subroutine uses the variable 'i'. IMHO it ought to be defined as a local variable in the the 'test' routine - just in case its upsetting the global variable which may(?) be used elsewhere in your main. - ie the 'test' function may be ok but now you are trashing something else in main.
2. Are you compiling with all optimizations disabled - just in case the compiler is trashing your code.
-
Awesome! it works now! Thanks Webbot! ;D
-
lol yea I always keep optimizations off. Axon memory is ginormous, so no need to optimize for memory.
As for optimizing for speed, unless you have some crazy intensive algorithm (lots of trig, SLAM, vision, etc), you don't need that either.