Help with sculpture

Hi,
I need help with a sculpture I'm working on.

There are 3 guitar strings. On each string is a servo actuated pick and 2 robot pinchers that are also actuated by a servo. So 9 servos all together.

The picker servo can pick the full string, a half string, and a quarter string this way - so string octaves.

I want all 9 servos to pick/pinch at random. There are 9 sequences possible - with 27 possible combinations. I want the timings to be random.

When a person presses a button on the sculpture the sequences fire off randomly for about 2 minutes total, and then the sculpture stops - goes back to waiting for the button to be pressed again.

I need help getting the servos to move randomly i.e. pauses between sequences to be random.

I want the 3 strings to possibly be picked / pinched at the same time - an octave on all three strings at the same time; or to have some some be picked at various time differences - so some get picked/pinched at short or long intervals. These intervals are from 0 - 45 seconds.

I would like to do all this with 1 Arduino - is that possible? How can I best get this random timing?

I'm using an Uno and a servo shield from Adafruit.

Here is what I have:

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN  200 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  350 // this is the 'maximum' pulse length count (out of 4096)
uint16_t servonum = 0;
const int buttonPin = 12;       // assigns pin 13 as the button pin
const int ledPin = 10;          // assigns pin 10 as the button led pin
int buttonState;                // the current reading from the input pin
int lastButtonState = LOW;      // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  Serial.begin(9600);
  Serial.println("Octaves report");
  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  delay(100);
  pinMode (buttonPin, INPUT);   // initialize the button pin as an input
  pinMode (ledPin, OUTPUT);     // initialize the button led pin as an output
}

void loop() {
  digitalWrite(ledPin, HIGH);   // turn the button led on
  int reading = digitalRead(buttonPin); // read the state of the switch into a local variable:
  if (reading != lastButtonState) {
    lastDebounceTime = millis(); // reset the debouncing timer
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
        digitalWrite(ledPin, LOW);        // turn the button led off
        // Full String - Drive servo 0: move servo for string pick
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(0, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(0, 0, pulselen);
        }
        delay(10000);
        // Half String - Drive servo 1: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(1, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(1, 0, pulselen);
        }
        delay(10000);
        // Quarter String - Drive servo 2: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(2, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(2, 0, pulselen);
        }
        delay(10000);
        // Full String - Drive servo 4: move servo one direction for string pick
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(4, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(4, 0, pulselen);
        }
        delay(10000);
        // Half String - Drive servo 5: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(5, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(5, 0, pulselen);
        }
        delay(10000);
        // Quarter String - Drive servo 6: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(6, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(6, 0, pulselen);
        }
        delay(10000);
        // Full String - Drive servo 8: move servo one direction for string pick
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(8, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(8, 0, pulselen);
        }
        delay(10000);
        // Half String - Drive servo 9: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(9, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(10, 0, pulselen);
        }
        delay(10000);
        // Quarter String - Drive servo 10: open and close string pinch
        Serial.println(servonum);
        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
          pwm.setPWM(10, 0, pulselen);
        }
        delay(5000);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
          pwm.setPWM(10, 0, pulselen);
        }
        delay(10000);
        servonum ++;
        if (servonum > 11) servonum = 0;
        digitalWrite(ledPin, HIGH);       // turn the button led on
      }
      lastButtonState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
    }
  }
}

OK, first things first.

You need to go and read the forum instructions so that you can go back and modify your original post (not re-post it) - using the "More -> Modify" option below the right hand corner of your post - to mark up your code as such using the "</>" icon in the posting window. Just highlight each section of code (or output if you need to post that) from the IDE and click the icon.

In fact, the IDE has a "copy for forum" link to put these markings on a highlighted block for you so you then just paste it here in a posting window. But even before doing that, don't forget to use the "Auto-Format" (Ctrl-T) option first to make it easy to read. If you do not post it as "code" it can as you now see, be quite garbled and is always more difficult to read.

It is inappropriate to attach it as a ".ino" file unless it is clearly too long to include in the post proper. People can usually see the mistakes directly and do not want to have to actually load it in their own IDE. And that would also assume they are using a PC and have the IDE running on that PC.

Also tidy up your blank space. Do use blank lines, but only between complete functional blocks.

Please edit your post to add code tags ("</>" button).

This is possible with Arduino, but you will need a separate power supply for the servos (5 to 6 Volts at 1 Ampere per servo, for as many servos that will be moving or straining at once). Be sure to connect the grounds.

Do not use delay() unless absolutely necessary. See the Blink Without Delay tutorial for how to proceed.

For randomness in your motion, look into the random() function.

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

Thanks all for the suggestions!