Servo Radnomizer with easing issues

Hello everyone.

I am very new to programming and I am doing my best here, so forgive me if this is sub-standard work. Here is my issue. I am trying to set a random value for a servo, then use an ease function to chase the random value with the servo position. When the servo position value is reached, set a new random position, and lather, rinse, repeat. I have tried about four thousand variations of this and keep getting the serial port reporting lots of zeros. Does anyone see what I am doing wrong? I suspect that I will need to eventually define a zone as being close enough to the number to be seen as that number so the division doesn't go on infinitely, but I would be happy right now seeing some of the values change as they get closer to the servo position asked for by the random number.

Here is the code.

#include <Servo.h> 


Servo servo1;
float spd = 2;
float ran = random(0,180);
float ease;
float current;
float noopos;


void setup()
{
servo1.attach(2);
Serial.begin(9600);
}

void loop()
{
if (servo1.read() != ran)
{
  ease=(ran/spd);
  current = servo1.read();
  noopos = (ease - current);
  servo1.write(noopos);
  delay(10);
}

else 
{
    ran = random(0,180);
}
}

Hopefully someone will have some insight. I tried using the delay function to reduce the speed of the servo, but it was choppy and ugly, so I am hoping this is a better way to get the results I am looking for. Thanks in advance for any information/insight on this problem.

Peace,

Gumby

I see a couple of issues. The servo read function returns the last position that you sent the servo to, not the current position of the servo. While this difference is trivial when the servo is lightly loaded (or not loaded at all), there can be s significant difference for a heavily loaded servo.

You know, and can keep track of, where you sent the servo to, so reading it's position is not necessary.

You never seed the random number generator, so you will always get the same set of values from ran.

The if test reads the "position" of the servo. If it is not where is is supposed to be (ran), you read the servo "position" again. There is nothing that has happened to change the servo position, so you get the same position that you just discarded.

I have tried about four thousand variations of this and keep getting the serial port reporting lots of zeros.

There are no Serial.print statements anywhere in this code, so why you see a string of 0s in the serial monitor is a complete mystery.

When you write data to the serial port, for debugging purposes, Serial.print(ran); is a lousy bit of information.

Serial.print("Random value generated: ");
Serial.println(ran);

This will be much more useful, since you know what the value printed means.

Without knowing what you printed, it's hard to guess what the 0s mean.

Finally, random returns a long, not a float. The servo read function returns an int, not a float. The servo write function takes an int, not a float.

Using the correct variables types will help immensely.

Thank you for that input. I removed the print statements for ease of viewing on the forum. (They are all there).

First off, is there a way to get the current poition, and not the last position? I'm also confused why reading it's current position is not necessary. How do I do the math without knowing the current value for the angle of the servo?

I tried a few different types of variables and thought even if some were integers, this may be a good way to default to the heavy math and after the script was working prune the values I didn't need.

I have been thinking about the values for ran, and I know it is a pseudo-random generator, so I was wondering if there was a way to read say the system clock to generate a random seed for the number so it was more of a true "random" number.

Like I said I would have been happy to see it get through a single iteration where the the program eased into position, but no luck yet. I will look at the suggestions you made and see if that was the issue.

Lastly, I know about the oddness of having more than one call for the value of the position for the servo, but those were more of my attempts to troubleshoot the program, I thought maybe the value wasn't being passed from one set of curly braces to the next.

Sigh... I hope this starts to make sense soon...

Thanks for the input. I appreciate it. (More to follow)

Peace,
Gumby

servo.read doesn't return the exact current position of the servo, it simply returns the last value that you wrote to it.

First off, is there a way to get the current poition, and not the last position?

No. There is no feedback from the servo to the Arduino.

I removed the print statements for ease of viewing on the forum.

Doesn't help us help you if you do that.

I'm also confused why reading it's current position is not necessary.

Because you can just keep track of the value that you last sent it to.

so I was wondering if there was a way to read say the system clock to generate a random seed for the number so it was more of a true "random" number.

The millis() function returns the time that the Arduino has been running, since the last reset. It is not the same as the current time. That is something that the Arduino, without external input, does not know.

What some people do is read from an otherwise unused analog pin, to get noise, and use that value to seed the random number generator,

Print the last written servo position, the random location you are trying to achieve, and the new position you are sending it to. Because the actual values are ints, you may be jumping back and forth on either side of the desired set point.

But, it's hard to tell, because you haven't exactly said what is wrong. Does the servo get close, and then jitter? Does it never get close? How can you tell? As soon as you get to the desired point, the desired point changes.

What I want to servo to do is move from random position to random position with easing leading to the stop point. Then I want a new value and the servo to chase that value, etc.

I got random numbers for the servo to work, but the movement was too fast. It was borderline violent. So I tried some delay, but it just moved fast, then delay, fast, delay, etc. It didn't look right. So I thought a random number generator would be a good option. I also considered an array of numbers to draw from for the positions, but I haven't gone down that road yet.

What the program currently does is intialize and returns a constant stream of zeros for the values. I have tried some constants instead of random numbers, and got the same result. So I am not sure where the problem is yet.

Again, thanks for the input. I really appreciate your time. I will implement the things you said and see what I come up with.

Peace,
Gumby

If you look at the servo examples, they move the servo in 1 degree steps, with a delay between each step. Changing the length of the delay changes the apparent speed of the servo. You are still trying to move the servo in potentially large jumps. Perhaps moving the servo from one random position to another, in 1 degree steps, with a delay between each step is all you need to do. The easing thing is probably what is causing the problem.