Functions for Servo Speed Goes Only 1 Time per Call

What this is supposed to do is randomly call one of three functions, where each function moves the servo at a different speed for a certain amount of time, then another function is called.

It does call the functions and each moves at a different speed, where it goes wrong it only moves the servo once, stops, then after a short time calls another function. It needs to keep moving for the time I set it. I tried changing the delays in the setup the first in the loop, nothing changes.

void setup() {
  Serial.begin(9600);  // Starts routine
  randomSeed(analogRead(0));  // Start random

  servo.attach(8);
  servo.write(0);
  delay(2000);  
}

void loop() {

  randNumber = random(1, 4);

  delay(3000);  //Delay between routines

  if (randNumber == 1) {routineOne();}
  if (randNumber == 2) {routineTwo();}
  if (randNumber == 3) {routineThree();}  
           }
                   // Functions
int routineOne(){
 Serial.println("One");

  servo.write(90);
  delay(400);
  servo.write(0);
  delay(400);
}

int routineTwo(){
 Serial.println("Two");

  servo.write(90);
  delay(200);
  servo.write(0);
  delay(200); 
}

int routineThree(){
 Serial.println("Three");

  servo.write(90);
  delay(100);
  servo.write(0);
  delay(100);
}

Please post a complete sketch.

Hello
The sketch turns the servo to "0" in all cases.

No, they don't move at a different speed. They only stay at 90 degree for different times. And if this time is too short, the servo will even not reach the position until it gets back to 0 degree.

That's exactly what you programmed. Every 3 second it goes to 90 degree, stays there for a time ( if it even reaches 90 degree ) and moves back to 0.

Explain exactly what the servo is supposed to do.

where do you set that time? and where do you repeatedly call that function for the duration of that time?

there's a 3 sec delay (during which nothing happens)

i think you want to only update randomNumber every 3 seconds and repeatedly call one of your 3 functions

consider

struct Servo  {
    Servo (void)   { };
    void attach (int pin)   { };
    void write  (int ang)   { Serial.println (ang); };
};

Servo servo;

unsigned long msecLst;
int           randNumber;

void loop() {
    unsigned long msec     = millis ();

    if ((msec - msecLst) > 3000)  {
        msecLst = msec;
        randNumber = random(1, 4);
    }

    if (randNumber == 1) {routineOne();}
    if (randNumber == 2) {routineTwo();}
    if (randNumber == 3) {routineThree();}
}

// Functions
void routineOne(){
    Serial.println("One");
    servo.write(90);
    delay(400);
    servo.write(0);
    delay(400);
}

void routineTwo(){
    Serial.println("Two");
    servo.write(90);
    delay(200);
    servo.write(0);
    delay(200);
}

void routineThree(){
    Serial.println("Three");
    servo.write(90);
    delay(100);
    servo.write(0);
    delay(100);
}

void setup() {
    Serial.begin(9600);  // Starts routine
    randomSeed(analogRead(0));  // Start random
    servo.attach(8);
    servo.write(0);
    delay(2000);
}

which is 400ms (MAX !).. then back to 0.

  servo.write(90);
  delay(400);
  servo.write(0);

Are you trying to get it to wag back and forth like a windscreen wiper, for 3 seconds, at a "speed" of 400 or 200 or 100 per sweep depending on the random number, and then switch to a new "speed" of 400, 200, 100 and so on?

Wag from 0 to 90 to 0 at one of 3 speeds chosen at random about every three seconds.

#include <Servo.h>

Servo servo;

void setup()
{
  Serial.begin(9600);  // Starts routine
  randomSeed(analogRead(0));  // Start random

  servo.attach(8);
  servo.write(0);
  delay(2000);
}

// Move from 0 to 90 to 0 in the number of milliseconds specified
void Wag(int speed)
{
  unsigned long microsecondsPerStep = (speed * 1000ul) / 182;
  
  for (int a = 0; a <= 90; a++)
  {
    servo.write(a);
    delayMicroseconds(microsecondsPerStep);
  }

  for (int a = 90; a >= 0; a--)
  {
    servo.write(a);
    delayMicroseconds(microsecondsPerStep);
  }
}

void loop()
{
  static int randNumber = 1;
  
  // Every three seconds pick a random number
  static unsigned long lastTime = 0;
  if (millis() - lastTime > 3000)
  {
    lastTime = millis();
    randNumber = random(1, 4);
  }

  switch (randNumber)
  {
    case 1: Wag(400); break;
    case 2: Wag(200); break;
    case 3: Wag(100); break;
  }
}

Are you trying to get it to wag back and forth like a windscreen wiper, for 3 seconds, at a "speed" of 400 or 200 or 100 per sweep depending on the random number, and then switch to a new "speed" of 400, 200, 100 and so on?

Yes

Thanks you very much, it works! Please tell me what the following means:

delay(2000); - What does this do?
(speed * 1000ul) / 182; - What is the ul and why divide by 182?
delayMicroseconds(microsecondsPerStep); - Is delayMicroseconds a reserved word?
millis - What is "millis"

It does nothing for 2000 milliseconds (2 seconds). You had it in your sketch so I kept it.

'ul' means 'unsigned long'. Without it, any speed over 32 would cause a integer overflow on a device with 16-bit integers. There are 91 angles in the range 0 to 90. There are 91 angles in the range 90 to 0. There are 182 angles altogether.

No. It is a function provided by the Arduino core. See:

The core function millis() returns the number of milliseconds the Arduino has been running as an 'unsigned long' integer.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.