Servo coding hypothetical

Hi guys i had a question regarding servo android control, is there a way i could load code to ardunio such that if i wanted to change the angle to lets say 72 degrees, the servo rotates to that degree and stays there for x seconds, then has free range of motion once again

this is the code i have, its not my own but implemented

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position
int motor = 0;

void setup()
{  
  Serial.begin(9600);  // initialize serial: 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 
  Serial.print("Arduino control Servo Motor Connected OK");
  Serial.print('\n');
}

void loop()
{ 
  // if there's any serial available, read it:
  while (Serial.available() > 0) {
    
    // look for the next valid integer in the incoming serial stream:
    motor = Serial.parseInt();
   
    // do it again:
    pos = Serial.parseInt();
  
    // look for the newline. That's the end of your  sentence:
    if (Serial.read() == '\n') {
              
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(15);                       // waits 15ms for the servo to reach the position
     
      // print the three numbers in one string as hexadecimal:
      Serial.print("Data Response : ");
      Serial.print(motor, DEC);
      Serial.print(pos, DEC);
      
    }
  }
}
 
  //for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  //{                                  // in steps of 1 degree
  //  myservo.write(pos);              // tell servo to go to position in variable 'pos'
  //  delay(15);                       // waits 15ms for the servo to reach the position
  //}
  //for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  //{                                
  //  myservo.write(pos);              // tell servo to go to position in variable 'pos'
  //  delay(15);                       // waits 15ms for the servo to reach the position
  //}
 
 
  //val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  //val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  //myservo.write(val);                  // sets the servo position according to the scaled value
  //delay(15);

which works fine, but i wanted to modify it where, until i enter a degree through android, the servo has free range of motion but this code will hold the servo without range of motion.

once i change the degree, its held for x amount of seconds then free range of motion returns

What do you mean by free range motion? Do you want the servo to act like its not being given a position at all, like it has no power?

There is the .detach( servo number ); function, though im not sure it will still do what you want.

As far as timers go, you can use the Blink Without Delay method. Basically its a way of adding a delay without actually using the delay function and it does not block the code from doing anything else (like delay() does).

Try me:

const byte ledPin = 13;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW); // make sure the LED is off
  Serial.begin(115200); // you can use 9600 instead, but 115200 is much faster (that is if your android device supports it, which it should)
}

void loop()
{
  // static on these variables means, make it once with or without a value then skip over it on the next loop
  static byte ON = false; 
  static unsigned long prevTime = millis(), duration = 1000UL; // 1000(millis) = 1 second, UL = unsigned long

  if (Serial.available() )
  {
    // for this demonstration, it does not matter what we receive, this is only to show that we have received something
    Serial.read(); // empty the buffer otherwise Serial.available() will always be true
    ON = true; // if there is anything in the serial buffer at all, turn on the LED
    prevTime = millis(); //record the current millis() value and save it in prevTime
  }

  if (millis() - prevTime >= duration) // check the time
  {
    ON = false; // after 1000 or based on the value of duration, turn off the LED
  }

  digitalWrite(ledPin, ON); // if ON = true, LED will be on, else it will be off
}

HazardsMind:
What do you mean by free range motion? Do you want the servo to act like its not being given a position at all, like it has no power?

There is the .detach( servo number ); function, though im not sure it will still do what you want.

As far as timers go, you can use the Blink Without Delay method. Basically its a way of adding a delay without actually using the delay function and it does not block the code from doing anything else (like delay() does).

Try me:

const byte ledPin = 13;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW); // make sure the LED is off
  Serial.begin(115200); // you can use 9600 instead, but 115200 is much faster (that is if your android device supports it, which it should)
}

void loop()
{
  // static on these variables means, make it once with or without a value then skip over it on the next loop
  static byte ON = false;
  static unsigned long prevTime = millis(), duration = 1000UL; // 1000(millis) = 1 second, UL = unsigned long

if (Serial.available() )
  {
    // for this demonstration, it does not matter what we receive, this is only to show that we have received something
    Serial.read(); // empty the buffer otherwise Serial.available() will always be true
    ON = true; // if there is anything in the serial buffer at all, turn on the LED
    prevTime = millis(); //record the current millis() value and save it in prevTime
  }

if (millis() - prevTime >= duration) // check the time
  {
    ON = false; // after 1000 or based on the value of duration, turn off the LED
  }

digitalWrite(ledPin, ON); // if ON = true, LED will be on, else it will be off
}

So lets say i upload the code to arduino, what i want is for it to be able to not stay in place when i run the code i post, it wont move from its position even if i try to move it with my fingers. So i would like for it to be movable if i dont tell it otherwise.

the second part is when i send it a degree to be set too in the app, it should go to that degree but then it should stay at that degree for x amount of seconds

If .detach() doesn't do what you are looking for then you can use a transistor to control the v+ pin on the servo. This of course would require another arduino pin to activate or deactivate the transistor, but that is simple to do. (don't forget the resistors. Take a look at a transistor led control circuit)

the second part is when i send it a degree to be set too in the app, it should go to that degree but then it should stay at that degree for x amount of seconds

The code I posted shows just that.

which works fine, but i wanted to modify it where, until i enter a degree through android, the servo has free range of motion but this code will hold the servo without range of motion.

once i change the degree, its held for x amount of seconds then free range of motion returns

Some servo test code you can try that includes the attach/detach functions.

// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h> 
String readString; //String captured from serial port
Servo myservo;  // create servo object to control a servo 
int n; //value to write to servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
  Serial.println();
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 

      // attach or detach servo if desired
    if (readString == "d") { 
      while (digitalRead(7)) {} //delay loop until pin 7 is low
      myservo.detach(); //detach servo
      Serial.println("servo detached");
      goto bailout; //jump over writing to servo
    }
    if (readString == "a") {
      myservo.attach(7); //reattach servo to pin 7
      Serial.println("servo attached");
      goto bailout;
    }    

    n = readString.toInt();  //convert readString into a number

    // auto select appropriate value
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n); 
    }

bailout: //reenter code loop
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    Serial.println();
    readString=""; //empty for next input
  }
}

salad7, the very best you can achieve with a standard servo is Servo.detach(), as pointed out by 'HazardsMind' and 'zoomcat'.

For what you want, Servo.detach() is exactly the same as removing the power from the servo - it is no longer 'held' in place because no pulses are sent to it. It cannot be made any more 'free-moving' than the internal gearing allows.

For what you want, Servo.detach() is exactly the same as removing the power from the servo - it is no longer 'held' in place because no pulses are sent to it.

Some of the newer "digital" servos will remember the last sent control value until another control value is sent. Not a problem with the traditional analog servos.

zoomkat:
Some of the newer "digital" servos will remember the last sent control value until another control value is sent. Not a problem with the traditional analog servos.

Even after Servo.detach() is called? I wasn't aware of that.
I've only got the old-style analogue servos.
I might have to get me a modern, digital servo or two to play with, and see what the benefits are.

So it must be asked, 'salad7', do you have an analogue or digital servo?

Edit: 'zoomcat', I guess this means that a digital servo continues to use the same power and heat up even after Servo.detach() is called? That's not at all good. I like 'detaching' the servo to give it a rest. (Continuous rotation servos on a robot car.)

I just did some reading on Futaba digital servos. They, at least, don't appear to 'hold' the motor in place when no pulses are incoming. In that regard, they're the same as analog servos. (See attached pdf)

I don't know about other brands/types.

digitalservos.pdf (244 KB)