servo random direction/speed controlled by Maxsonar EZ0

The sketch is causing random movement more or less as intended. Analog input from the Maxsonar sensor should control the speed of this random movement. The closer the viewer is to the sculpture, the faster the speed. After mapping the values, I don’t understand how to write the sketch so that both the random number (pos1) and analog input (sonarVal)can be passed to the motor pins (xservo/yservo).

#include <Servo.h>

#define PIN_SERVO1 9
#define PIN_SERVO2 10
#define MIN_DELAY1 130
#define MAX_DELAY1 350
#define MIN_DELAY2 130
#define MAX_DELAY2 350

int sonarPin = A1;
int sonarVal =0;

Servo xservo;
Servo yservo;


void setup() {
  xservo.attach(9);
  yservo.attach(10);
  Serial.begin (9600);
}

void loop () {
  
    sonarVal = analogRead(sonarPin);
    sonarVal = sonarVal *4;
    sonarVal = constrain(sonarVal, 100, 300);    
    sonarVal = map(sonarVal, 300, 100, 255, 0);
   
  
    long msec1 = random(MIN_DELAY1,MAX_DELAY1);
    int pos1 = random(0,181);
    xservo.write(pos1);
    delay(msec1);
    
    long msec2 = random(MIN_DELAY2,MAX_DELAY2);
    int pos2 = random(0,181);
    yservo.write(pos2);
    delay(msec1);
    
    Serial.println(sonarVal);
}

crackle:
The closer the viewer is to the sculpture, the faster the speed. After mapping the values, I don’t understand how to write the sketch so that both the random number (pos1) and analog input (sonarVal)can be passed to the motor pins (xservo/yservo).

Just to be very clear, you don't control the speed of the servo. It goes to a position as fast as it can after it receives the command. What you (I think) want to do is have the time delay between the positions get shorter and shorter the closer the viewer gets. So I see it as a case of mapping *sonarVal* into *msec1* with the appropriate scaling and limits. The positions remain random but the time interval between the commands is not.

ie - When “far” away the position changes every 2 seconds. When close it changes every 0.2 sec (about as fast as it can).

Thanks. I thought I could actually control the speed, not the interval (but interval would be as good). I have come up with this sketch that seems to work in terms of behavior to the motors for a while but then the serial monitor locks up, prints garbage, or the works just comes to a halt. Any idea what causes this?

#include <Servo.h>

#define PIN_SERVO1 9
#define PIN_SERVO2 10
#define MIN_DELAY1 130
#define MAX_DELAY1 350
#define MIN_DELAY2 130
#define MAX_DELAY2 350

int sonarPin = A0;
int sonarVal =0;

Servo xservo;
Servo yservo;


void setup() {
  xservo.attach(9);
  yservo.attach(10);
  Serial.begin (9600);
  delay(50);
}

void loop () {
  
    sonarVal = analogRead(sonarPin);
    sonarVal = sonarVal *4;
    sonarVal = constrain(sonarVal, 100, 450);    
    sonarVal = map(sonarVal, 450, 100, 450, 0);
  
   
  
    long msec1 = random(MIN_DELAY1,MAX_DELAY1);
    int pos1 = random(0,181);
    xservo.write((pos1, sonarVal));
    delay(msec1);
    
    long msec2 = random(MIN_DELAY2,MAX_DELAY2);
    int pos2 = random(0,181);
    yservo.write((pos2,sonarVal));
    delay(msec1);
    
   Serial.println(sonarVal);
  
}

crackle:
Any idea what causes this?

No idea. I have problems with the Arduino IDE's serial monitor at "high" baud rates that I don't have when using another terminal emulator. I suspect some Java oddness is at the root of it. Perhaps something similar on your machine ?

I see 3 things to note in your recent code.

  1. I don’t understand you usage of the servo write command. I thought it took 1 argument, the position in degrees. You have :

xservo.write((pos1, sonarVal));

http://arduino.cc/en/Reference/ServoWrite

I’m surprised it compiles (it does). Could that be causing some memory issue ?

  1. While you can’t control the speed of the servo you can use software to approximate such a control. Imagine you have a servo presently at 90 degrees. You want to go to the next position, let’s say it’s 120 degrees. If you change the servo command to 120 it goes there as fast as it can. But you could divide the difference between the 2 positions into many steps and then command it, step by step with some delay between each step, to go to the desired position. So let’s say you set the step size to 1 degree. You command the servo to 91 degree and wait 25 msec. Then you command 92 degree and wait 25 msec … so on and so forth until you get to the 120 degree. Now you might not want the step size to be 1 degree and the servo commands only go out every 20 msec from the Arduino (so changing the command any quicker than that doesn’t make sense) but I’m sure you could come up with a good way to find a reasonable step size and delay time. And that’s the only way I know to slow down a servo’s speed.

  2. msec1 is still random.

So helpful! Thanks. I didn’t know the …servo.write would accept only a single argument. I was trying to command both direction and speed with this. I’ll delete one argument and see what happens. Now that I understand the problem, a search will probably come up with something useful.