Go Down

Topic: Sweeping servo program question (Read 1 time) previous topic - next topic

mblackwolf

Hello,

I am trying to write a program that will sweep a servo from 0 to 180 degrees. This is pretty basic but I am including a webcam that Is attached to the servo. I will be using the programmer IDE since it has an arduino library to do tracking. The video will be fed into my laptop where the programmer program will do object tracking and transmit the object location in terms of degerees to rotate the servo through serial to the arduino. I am just wondering how to i tell the arduino to stop  sweeping the servo and move X degrees from the CURRENT position. This is where my problem is seeing as in the servo library you give a 0-2400 signal to rotate the servo but I want to move a certain number from the current location in the sweep motion. Thanks for any help you can give.

zoomkat

Quote
This is where my problem is seeing as in the servo library you give a 0-2400 signal to rotate the servo


Not an accurate assumption. The servo library has a lower limit of ~500 unless you change it.
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

mblackwolf

I'm sorry your right I forgot that. The servo I am using requires it between 600-2300. I just don't know how to tell the arduino to move the servo from the current position. For instance

Start sweep>>>if(Serialinput >1), stop sweep, serial.read >>>>>>>> take serial.read number and add it to the current servo position.>>>> Turn servo to that position

PaulS

Typically, servos respond to values from ~500 to ~2500 to define speed and direction, for continuous rotation servos, and to values from 0 to 180 for standard servos.

If you want to position a servo to a specific position, you should use the angle value, and keep track of where you told the servo to go to. When you want to go 5 degrees in the positive direction, add 5 to the current position, and write a new value to the servo.

If instead you are told the new position, just go there.

Until we know something about what Serial.read() gets, any advice is really just blowing smoke.

mblackwolf

Well what I plan to do is sweep the servo back and forth to search for red objects. The camera is connected to the sweep servo. So when the camera sees the object it will track the object using blob detection. It will find the centroid of the object and retrieve the pixel info (x-pixel,y-pixel). Knowing the pixels, total resolution, and camera view angle it will calculate the ammount of degrees it needs to turn to center the object in the frame. So serial.read() will retrieve the 2 angles (pan and tilt but i am simplifying just to understand how to do it) being passed from the programmer code. Since, the servo is in a sweep the angles it needs to turn are degrees from the current location. I am just not sure how to have the arduino stop the sweep and do something like this

panangle = serial.read()
panservo.write(current/last angle + panangle);

Just not sure how to get the current/last command angle to make it work. So far the only thing I have thought of is to step the servo through certain angles in the sweep like this (syntax may not be right just writing an example)

val = 0;
if (serial.read()<1)
val = val +10
panservo.write(val)
delay(10)
else if (serial.read()!<1)
panangle = serial.read()
targetangle = val+panangle;
panservo.write(targetangle)

This just seems messy and I am hoping there is a better way.

PaulS

The value in the write() call IS the angle to turn to, so I don't understand your difficulty.

The Serial.read() function reads bytes, which can hold a value between 0 and 255. So, the simplest thing is for the PC to send the new value to go to as a byte, not a string. Then, simply call Servo.write() with the value read from the serial port. The PC app should also send an ID to define which servo the value is for.

Something like this would work on the Arduino, then.

Code: [Select]
Servo pan;
Servo tlt;

void loop()
{
   if(Serial.available() > 1) // Need two bytes ('T' & n or 'P' & n)
   {
      char which = Serial.read();
      int thePos = Serial.read();

      if(which == 'T')
         tlt.write(thePos);
      else if(which == 'P')
         pan.write(thePos);
   }
}

mblackwolf

Ok. I am gonna try to explain what I mean. I know the value in write is the angle to turn to. However, If I have the servo panning the angle sent from the serial isnt the angle needed by the servo. I am using digital servos so I can slow down the rotation speed so to sweep i can use.

myservo.write(0)
myservo.write(180)

which will sweep the full 180 degrees. Now however say the camera picks up a red object at 90 degrees. It used the pixel and view angle values to calculate the needed angle of rotation based on where the servo is now. Lets say the program determine the servo needs to rotate 15 degrees furthur from the current location. If it was to send this and use your way the byte value sent would be 15. So the servo would then rotate backward to 15 degrees when I actually intended it to go to 105 degrees. I could write the programmer code to write the actual rotation angle needed but I would need some feedback of the current servo location.

PaulS

Quote
I could write the programmer code to write the actual rotation angle needed but I would need some feedback of the current servo location.

If the PC is totally in charge of servo position, then, no, you don't need any feedback. Not that you'd get any, anyway, since if you try to read a servo's location, the value you get back is the last value you told it to go to, regardless of whether it was able to get there, or not.

mblackwolf

I think that answers my question without the feedback I am either going to have to step through the sweep so I know the approximate position or keep the camera stationary so that the exact angle of rotation needed can be found. thanks for your help. The only other option I have thought of is possibly using hacked full rotation servos and instuting some form of PID control where the programmer code will give a left or right value based on how far it need to move and give a 90 degree (no motion) value if the object is in the center. I may see how this works out. Thanks for your help though I do appreciate it.

PaulS

If actual position information is essential, a real rotary encoder would be better than hacking a servo. Much higher resolution and repeatability.

I don't understand why the actual angle is critical. If the computer is tracking something, and it appears to be moving to the left, it should be telling the servo to move to the right. If the object appears to be moving while the servo isn't, it is either because the servo is drifting (unlikely), the object being tracked is moving (likely), or because the servo is drifting. In any event, the simplest solution is simply for the PC to tell the Arduino three values, instead - which servo, which direction, and how far ('P' '+' 2), and have the Arduino figure out which angle to send the servo to. If the new position isn't right, the PC will send a new increment.

It doesn't matter which way the servo is actually pointing. It's either pointing where the computer wants or it isn't. The PC can issue corrections until the Arduino gets it right.

Go Up