Quote request for artwork project

Hi,
I need help with a sculpture I'm working on. Time is tight for me, and if the price is right I will pay to complete the code.

How much to get the below completed?

Project description:
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.

The servos need 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. I'm using an Uno and a servo shield from Adafruit.

Here is the code 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:
    }
  }
}

So:

  • 9 servos, clear.
  • from your code it seems you want them to move a certain range (200 to 350) as fast as possible. It's much easier to just write the final number than using a for loop... for the movement it won't make a difference.
  • is it that the string is plucked in both directions of servo movement? Or just one?

What I don't understand is the movement you want to get. Always three servos move at the same time to create of of the 27 patterns in your list? Move them one by one?

It can definitely be done, probably a couple hours of work, as long as you can explain very clearly what you want to be done. Some possible sequence examples could be helpful, too.

Thanks for the reply!

To be clear - End goal:
3 different strings being picked randomly - so they can be possibly picked at the same time (0 seconds duration between them) or a delay (up to 45 seconds). This is in conjunction with the string getting pinched (or not) randomly.

Each string pick / pinch is independent of the others. The duration of string picking/pinching is random. So one string sequence can pick full string wait a random amount of time between 0-45 seconds, pick again full string and wait random, pick and pinch 1/2 string and wait random, pick and pinch 1/4 string and wait random, etc. The picking/pinching is random - the duration between is random - for each string.

The servo would have to pick in both directions to get back into the proper position each time. Unless you know a fancy way to keep the pick's position in mind when servo moves randomly.

As i understand it - getting this to work would involve random() function and millis() function.

Thanks and if you're still interested PM me with quote.
-Bob

PM sent.