How to accelerate a servo

Hi guys, I am a noob of coding and I am trying to script:
There is a robot with two sensors ir in front ultrasonic sfr02 in back. If something pass back or in front of the robot it has to accelerate from standby to the maxspeed, then do some random steers and return in standby.

here it is the code:

#include <MegaServo.h>
#include <Wire.h>
//SFRO2 ultrasonic 
#define sensorAddress 0x70
#define readCentimeters 0x51
#define readMicroseconds 0x52
#define resultRegister 0x02
//
int stdledPin = 13;        // choose the pin for the LED
int irFrontPin = 0;        // choose the input pin (for a pushbutton)
int irFrontval = 0;        // variable for reading the ir pin data
int speedLeft = 0;         // speed we want on left servo
int speedRight = 0;        // speed we want on right servo
boolean freeFront = true; // forward path
boolean freeBack = true;  // backward path
boolean standBy = true;   // standby mode 
boolean moveBack = false;  // backward mode
boolean moveForward = false;  // forward mode
unsigned long time;        // time
long interval = 1000;      // ?
long previousMillis = 0;   // ?

MegaServo left;
MegaServo right;

void setup() {
  Wire.begin();  // start I2C bus
  pinMode(stdledPin, OUTPUT);  // declare LED as output
  pinMode(irFrontPin, INPUT);  // declare pushbutton as input
  left.attach(10);
  right.attach(11);
  Serial.begin(9600);
}

void targetFront() {   // there is someone in front of RADIYOSP
      standBy = false;    // we are no longer in standBy
      freeFront = false;  // The front path isn't free
      moveBack = true;   // we are going backward
      int i = 1;         // additional val
      for (; i < 90; i++) {  
      digitalWrite(stdledPin, HIGH);  //light up stdled
      left.write(89 - i);  //from standby position substract every cycle 0.1 (the servo start to go backward)
      right.write(90 + i); //from standby position add every cycle 0.1 (the servo start to go backward) 
      delay(10);
      }
      if (i = 89) {
      left.write(random(0,180));  //from standby position substract every cycle 0.1 (the servo start to go backward)
      right.write(random(0, 180)); //from standby position add every cycle 0.1 (the servo start to go backward) 
      delay(random(100, 1000));
      standFor();
      }
}


void targetBack() {   // there is someone in the back of RADIYOSP
      standBy = false;
      freeBack = false;
      moveBack = false;   // we are no longer in standby we are going backward
      moveForward = true; 
      int i = 0.0001;
      for (; i < 90; i++) { 
      digitalWrite(stdledPin, HIGH);  //don't light up stdled
      left.write(90 - i);  //from standby position substract every cycle 0.1 (the servo start to go backward)
      right.write(0 + i); //from standby position add every cycle 0.1 (the servo start to go backward) 
      
      }
      if (i = 89) {
      left.write(random(0, 45));  //from standby position substract every cycle 0.1 (the servo start to go backward)
      right.write(random(45,135)); //from standby position add every cycle 0.1 (the servo start to go backward) 
      delay(random(100, 1000));
      standFor();
      }
     
}

/*void takeatrip() {
      standBy = false;
      moveForward = true;
      float i = 1;   // variable to add for accelerate servos
      left.write(180);  //from standby position substract every cycle 0.1 (the servo start to go backward)
      right.write(0); //from standby position add every cycle 0.1 (the servo start to go backward)*/



void standFor() {  // standby mode (no movements)
  left.write(90);  // stop servoleft
  right.write(90); // stop servoright
  standBy = true;  // we are in standby
  digitalWrite(stdledPin, LOW); // light up stdled
  freeFront = true;  // front is free we can navigate forward
  moveBack = false;     // we are in standby
  moveForward = false;
  freeBack = true;
  
  
}

void payattention() {
  irFrontval = analogRead(irFrontPin);  // read ir input value
  sendCommand(sensorAddress, readCentimeters); // send the command to read the result in centimeters:
  delay(70);  // wait at least 70 milliseconds for a result:
  setRegister(sensorAddress, resultRegister);  // set the register that you want to reas the result from:
  int sensorReading = readData(sensorAddress, 2);  // read the result:
  delay(70);
  if (irFrontval > 100) { // if irfront input is > 100
      standBy = false;
      freeFront = false;
      //delay(500  + random(100, 3000));
  }
  if (sensorReading < 60) { // if ultra (SFR 02) get something
      standBy = false;
      freeBack = false;
  }

}

  
void loop(){
 standFor();
 payattention();
 if (standBy = false) {
  if(freeFront = false) {
    targetFront();
  } 
  if (freeBack = false) {
    targetBack();
  }
  
 }
 if (standBy = true) {
    standFor();
 } 

// take a look around  
/*if (time - previousMillis > interval) {
      previousMillis = millis();
      takeatrip();
      delay(500);*/

}


//I2C COM
void sendCommand (int address, int command) {  // start I2C transmission:
  Wire.beginTransmission(address);
  Wire.send(0x00);
  Wire.send(command);
  Wire.endTransmission();
}

//SET INPUT ADDRESS
void setRegister(int address, int thisRegister) {
  Wire.beginTransmission(address);  // start I2C transmission:
  Wire.send(thisRegister); // send address to read from:
  Wire.endTransmission();
}

//READ DATA
int readData(int address, int numBytes) { //readData() returns a result from the SRF sensor
  int result = 0;        // the result is two bytes long
  Wire.requestFrom(address, numBytes); // send I2C request for data:
  while (Wire.available() < 2 )   {   // wait for two bytes to return:
  // wait for result
  }

result = Wire.receive() * 256; // read the two bytes, and combine them into one int:
result = result + Wire.receive();
return result;  // return the result:
}

I try to use For statement but i don't think it works, it don't seems accelerate.

I'm assuming the servos are modded for continuous rotation?
The range of pulse widths (==angle) in which they'll change speed is very narrow, mostly all you'll get is a fairly constant speed.

Yes are continuous rotation.
What do you mean?

I mean that you'll find a pulse width where the servo is stationary, say this is at 90 degrees.
Move away from this by +/- 1 degrees and the motor will crawl, but by the time you're at +/- 10 or even less the motor is probably running at full speed.
All the acceleration the ex-servo is capable of happens in this narrow band around the staionary point.
You may be able to get slightly finer control using the "writeMicroseconds" method, which uses actual PPM timings between about 540us and 2400us to control the servo, rather than mapping the range 0 - 180

Hi!!! Thank you for the reply!!
I wrote this code (please do not laughf I am a noob)

#include <Servo.h>

int stdledPin = 13;             // choose the pin for the LED
int irFrontPin = 0;              // choose the ir sensor input pin
int irFrontval = 0;             // variable for reading the ir pin data
boolean standBy = true;        // standby mode
boolean moveForward = false;     // forward mode
boolean targetFront = false;   // target on the front 
boolean targetBack = false;           // target behind
boolean moveBackward = false;      //moving backward
int encounters = 0;                    // ecounters with something
unsigned long randomizer;                 // trying to randomize (it seems don't working)
Servo left;                                   // attaching servos
Servo right;                                  ///////////////////
long time = 0;                                // last start time 
long interval = 5500;                        // time of stand by mode


void setup() {
  pinMode(irFrontPin, INPUT);         // declare ir as input
  left.attach(10);                    // servos
  right.attach(11);                   /////////
  Serial.begin(9600);                 // serial communication @ 9600 baud
  randomSeed(analogRead(1));          // randomSeed from analog port 1 
}

void accelerate() {
 moveForward = true;
 standBy = false;
 targetFront = false;
 int throttle = 0.001;
  for (standBy = false; throttle < 90; throttle++) {
    delay(50);
    irFrontval = analogRead(irFrontPin); 
    Serial.print(irFrontval);
     if (irFrontval > 250) { 
      encounters++;
      flip();
      break;
    }
   left.write(89 + throttle);  //from standby position add every cycle 0.1 (the servo start to go backward)
   right.write(90 - throttle); //from standby position substract every cycle 0.1 (the servo start to go backward)
    if (throttle == 89) {
      servocontinue();
      break;
    }
  }
}

void flip() {
  moveBackward = true;
  randomizer == random(0,1);
  if (randomizer == 1) {
   decelerate();
   moveBackward = false;
   left.write(180);
   right.write(180);
   delay(500);
   targetFront = false;
  } 
  if (randomizer == 0) {
   decelerate();
   moveBackward = false;
   left.write(0);
   right.write(0);
   delay(500);
   targetFront = false;
   }
 }
 
 void decelerate() {
   int z = 1;
   for (moveBackward = true; z < 90; z++) {
     delay(1);
     left.write(180 - z);
     right.write(0 + z);
     if (z == 89) {
       moveBackward = false;
       targetFront = true;
       standFor();
       break;
     }
   }
 }
   
  void standFor() {    // standby mode (no movements)
  left.write(90);       // stop servoleft
  right.write(90);       // stop servoright
  standBy = true;         // we are in standby
  if (encounters < 5) {
    if (moveForward == true) {
      if (targetFront == false) {
         servocontinue();
      }
    }
   } if (encounters > 5) {
      standBy = true;
      moveForward = false;
   } 
  }
  
  void servocontinue() {
    targetFront = false;
    standBy = false;
    moveForward = true;
    left.write(180);
    right.write(0);
    irFrontval = analogRead(irFrontPin); 
    if (irFrontval < 250) {
      servocontinue();
   } else {
     encounters++;
     flip();
     standFor(); 
   }
  }
  
  void loop() {
  if (standBy = true) {  
    standFor();
   if (millis() - time > interval) {
     time = millis();
     interval = random(5500,15000);
     encounters = 0;
     accelerate();
    }
  }
  if (standBy = false) {
    if (targetFront = false) {
      servocontinue();
    }
  }
}

NOW IT WORKS, I clean code at all to have some chance to understand what change and why.
do you have some advise to improve it?

In my opinion I have to fix the problem that you say... after adding 10/15 points servos are already at full speed. I have to change values in my acceleration and deceleration functions.

Microseconds sounds good, it gives better results?

Microseconds sounds good, it gives better results

It potentially gives finer control.
Instead of calling "Servo.write" with an "angle" value of 0 to 180, you can call it with pulse widths in microseconds, from 544 to 2400, so giving you over 1800 steps, instead of 180.
The 90 degree point corresponds to a pulse width of 1500 microseconds, I think.

For exact details, look at hardware/libraries/Servo/Servo.cpp and Servo.h.

there is a writeMicroseconds() method that does the same thing as Groove's suggestion but make your intentions more explicit in the source code.

90 degrees is midway between the min and max pulse widths. The default value of these are 544 and 2400 so 90 degrees is actually 1472 microseconds.

Most servos will not resolve down to 1 microsecond, so in practice the number of actual steps is less

unsigned long randomizer;                 // trying to randomize (it seems don't working)``randomizer == random(0,1);

"random" here will always zero, which I'm guessing is not what you want.

"Returns
long - a random number between min and max - 1 "

so:randomizer == random(0,[glow]2[/glow]);

Thank you I hit my desktop all night long for this mistake :-[ :stuck_out_tongue:
Now I am taking a look to smoothing to get finer data from sensor and because I would like to connect:
-temp
-piezo input
-light sensor

and use this smoothed values to randomize actions and applications, like text to speech and image visualizing (interfacing arduino with eeepc laptop and processing)

The computer will be integrated in the robot structure.