Servo control query...timing a loop function?

Is it possible to control the duration of a servo loop code, so that it will repeat for a set period of time before continuing and restarting the void loop?
I am rebuilding the sculpture "Stutter" - view in action at: www.karenscopa.com/#/kinetic/4562964559 . The movement is created by arduino servo control code, triggered by a PIR input. I've now added LEDs which interfere with the PIR readings. I could not solve this problem, so have decided to remove the PIR. Instead...

I want to programme the on/off duration of the servo control. An LED array triggered by a transistorPin will mirror the servo on duration. (I want the motor to be off then on for random periods.)

I have experimented with timer codes, interrupts, serialMonitor controls, and randomSeed, but am now very confused! If I grasp a bit of the coding principles, I invariably get lost when trying to make example codes work with my servo code, without changing the servo motion. Is there an easier way that I'm missing? Any help/advice is appreciated....

This is my original code, using for loops to create the servo 'Stutter' effect....

/*Code for new version of 'Stutter' (sep 2013). 
//A PIR sensor connected to pin 2 triggers servo motor program. 
//Servo is attached to pin 9.
//connect NPN 2N2222 transistor to pin 4 with </= 1K resistor to switch on LED array
//Servo write is mirrored by LED on pin 13.*/

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
const int servoPin = 9;
int pos = 0;    // variable to store the servo position
const int ledPin = 13;
const int transistorPin = 4;
int pirPin = 2;
int val = 0; //sets low/off as starting value

void setup() {
  myservo.attach(9);
  pinMode (servoPin, OUTPUT);//pin 9 is the servo
  pinMode (ledPin, OUTPUT);//pin 13 is the led pin
  pinMode (transistorPin, OUTPUT);//pin 4 is the transistor pin
  pinMode (pirPin, INPUT);//pin 2 reads PIR sensor like an on/off switch
}

void loop () {
 val = digitalRead(0);//read PIR - initiallly 0 until triggered by motion
  digitalWrite(13, val); // copies pirPin state on LED pin 13
  if (val == 1){
    digitalWrite(transistorPin, HIGH); //keeps transistor triggered for 20 seconds. Leds are on for this duration.
    digitalWrite(servoPin, HIGH);
    for(pos = 0; pos < 20; pos += 1)  // goes from 0 degrees to 20 degrees in steps of 1 degree
    {
      myservo.write(pos); // tell servo to go to position in variable 'pos'
      delay(5); // take 5ms for the servo to reach the position
    }
    for(pos = 20; pos > 0; pos -= 1)// goes from 20 degrees to 0 degrees in steps of 1 degree
    {
      myservo.write(pos); // tell servo to go to position in variable 'pos'
      delay(5); // waits 5ms for the servo to reach the position
    }
  } 
  else {
    digitalWrite(transistorPin, LOW);
    digitalWrite(servoPin, LOW);
  }
}

Is it possible to control the duration of a servo loop code

That depends on what you mean by "a servo loop code". That phrase will not appear in the index of any C or C++ book.

I've now added LEDs which interfere with the PIR readings

LEDs do not interfere with PIRs. Your code may have been flawed.

I want the motor to be off then on for random periods.

But, the exact time is important? I'm not understanding something here.

This is my original code, using for loops to create the servo 'Stutter' effect....

I don't see how sweeping the servo back and forth, whenever the PIR pin is high creates a stutter effect.

Sorry if I'm not explaining properly...I'm not an experienced programmer and am still learning. I'll try to clarify...

PaulS:

Is it possible to control the duration of a servo loop code

That depends on what you mean by "a servo loop code". That phrase will not appear in the index of any C or C++ book.
I mean the 'for' lines in the void loop section which makes the servo oscillate quickly...creating the 'stutter' effect. When I experimented with different timer, serial monitor, and delay coding, it always seems to adjust the oscillation effect, which is the bit I'm happy with...I just don't want it to run indefinitely.

I've now added LEDs which interfere with the PIR readings

LEDs do not interfere with PIRs. Your code may have been flawed.
I thought this must be the case too, but I experimented with different hardware and coding variations and the PIR i am using did seem to be affected by the LEDs...its hard to see in the video, but I'm using a miniPIR which is embedded in the centre of the moving bit of the sculpture, so it is also shaking quite fast. Also, in my new version, the centre section is further back inside the round structure, with 16 really strong red leds shining straight on it. I could get the PIR to trigger the motor and LEDs but couldn't get them to go off again. I check the readings using the serial monitor and the PIR was reading constantly triggered, even though it is pre-programmed to trigger for only 20 seconds at a time.

I want the motor to be off then on for random periods.

But, the exact time is important? I'm not understanding something here.
I'm thinking off for long periods and on for short durations - say 20secs to 3min bursts - I don't want to burn out the motor as I know I'm using it unconventionally. I would prefer it to be human activated through PIR but I've been at it for months and can't resolve the PIR triggering issue.

I'm hoping that there may be a coding solution, but am also considering using a 555 timer. I'd prefer to find a software solution though.

I'm hoping that there may be a coding solution, but am also considering using a 555 timer. I'd prefer to find a software solution though.

I'm sure that that is possible. I just don't understand what the problem is. You can read the PIR sensor. You know when it is HIGH. You can move the servos. So, what is the problem?

Actually, I suspect that the issue is that you don't want to know when the PIR sensor IS high. You want to know when the PIR sensor BECOMES high. Look at the state change detection example.

Then, you want to wave the servo around for a defined period of time (random or fixed). That is simply a variation on the blink without delay example. Record when the PIR sensor becomes HIGH. Then, on each pass through loop, determine if now minus then is less than the interval of interest. If it is, move the servo from beginning to end and back ONCE. You can even incorporate moving the servo one step at a time using the blink without delay philosophy, so that the servo stops at the correct time, wherever it is, without the need to complete a circuit. But, one step at a time.

Essentially, my problem is making the 'for....servo.write' function run (repeat) for a set period, before continuing the rest of the void loop and returning to the beginning again... How can I make these 'For' lines repeat for X times, or X seconds within the void loop. I've tried variations with brackets and delay or millis like this...
{
for(pos = 0; pos < 20; pos += 1) // goes from 0 degrees to 20 degrees in steps of 1 degree
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // take 5ms for the servo to reach the position
}
for(pos = 20; pos > 0; pos -= 1)// goes from 20 degrees to 0 degrees in steps of 1 degree
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 5ms for the servo to reach the position
}
}
delay(20000);
}

...but these don't work either. I have tried adapting the blink without delay example, and tried using state change when using the PIR. Everything I have tried, including some timer functions, seems to either a) make the for lines run once only and then look for an input or state change; or b) triggers the servo to run continuously....it doesn't know when to stop unless there is some input or other state change. Having removed the PIR completely, I'm now trying to incorporate the on/off/timing triggers within the void loop code. I've looked at masses of servo code examples, but can't find anything that is controlling the duration of the 'for' loop within the code. It seemed to me to be a simple task, but is proving very frustrating and difficult.

I appreciate your suggestions and will look again at the state change and the blink without delay again as I might have missed something or not understood how to use the interval functions properly. I've been able to get them to work before, but could only get them to run through the 'for...servo.write' lines once before pausing to wait for another trigger/reading.

Thanks for your help....p.s. I like your tigger too!

Essentially, my problem is making the 'for....servo.write' function run (repeat) for a set period

unsigned long start = millis();
while(millis() - start < 10000)
{
   // The two for loops go here
}

This will perform the servo sweeping for 10 seconds, then continue with the rest of the function.

Thank you so, so much...this has been driving me bonkers! I'll give it a go.

Also, I forgot to add in response to your previous reply, that you are absolutely correct... the PIR was triggering the motor and it was going off after 20 seconds without any problems....the video clip shows it working as intended. Adding the LEDs caused new problems.

Thanks for taking the time to understand my problem and what I was trying to achieve.