Pages: [1]   Go Down
Author Topic: Controlling servo without needing to use delay  (Read 837 times)
0 Members and 1 Guest are viewing this topic.
Wales
Offline Offline
Full Member
***
Karma: 0
Posts: 244
Don't take things too seriously
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is an excerpt from my loop. I would prefer to have as few as possible uses of delay in my sketch. I would prefer to "detach" the servo to cause it to return to its original position (the servo arm is connected to a spring so the power of the (now) unresisted spring should enable a return). However, this doesn't seem to work.

Code:
if (bedroomVoltsRead < 100)
  {
    if (currentMillis-bedroomTriggeredTime > debounce) 
    {
      bedroomTriggeredTime = currentMillis;

      if (bedroomState == OFF)
      {
        bedroomState = ON;
        if (bedroomLEDState == OFF)
        {
          bedroomLEDState = ON;
          if(value3) 
          {
            BellControlServo.attach(6);
            BellControlServo.writeMicroseconds(2300);
            delay(200);              // wait for a bit
          }
          bedroomLEDTimeStamp1 = currentMillis;
          Serial.println();
        }
        else if (bedroomLEDState == ON)
        {

          bedroomLEDState = FLASH;
          if(value3) 
          {
            BellControlServo.attach(6);
            BellControlServo.writeMicroseconds(2300);
            delay(200);              // wait for a bit
          }
          bedroomLEDTimeStamp1 = currentMillis;
        }
      }
    }
    else
    {
      bedroomState = OFF;
      BellControlServo.attach(6);
      BellControlServo.writeMicroseconds(600);
      delay(200);              // wait for a bit
      BellControlServo.detach();
    }
  }
  if (bedroomLEDTimeStamp1 + LEDOnDuration < currentMillis)
  {
    bedroomLEDState = OFF;
  }
 

In particular I understand each time the arduino goes through the loop this bit is executed. So I have a delay of 1.2seconds every time the loop is executed even if nothing is happening because I have six of these in my loop. If something is happening the delay is potentially 7.2 seconds!

Code:
    else
    {
      bedroomState = OFF;
      BellControlServo.attach(6);
      BellControlServo.writeMicroseconds(600);
      delay(200);              // wait for a bit
      BellControlServo.detach();
    }

Any ideas?

Thanks!
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34152
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
(the servo arm is connected to a spring so the power of the (now) unresisted spring should enable a return).
Not a good idea. The servo normally goes through a worm gear and it is not a good idea to try and drive those backwards.

Quote
Any ideas?
Use the blink without delay method to write your program.
Logged

Wales
Offline Offline
Full Member
***
Karma: 0
Posts: 244
Don't take things too seriously
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
(the servo arm is connected to a spring so the power of the (now) unresisted spring should enable a return).
Not a good idea. The servo normally goes through a worm gear and it is not a good idea to try and drive those backwards.
Oh? I thought it was possible to move a servo manually through its range of rotation (for example to test its limits)? Didn't realise it was damaging...
Quote
Any ideas?
Use the blink without delay method to write your program.
OK...was hoping to avoid that as it's going to be quite complicated for my sketch.
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Any ideas?

Not really, as you talk of code that doesn't work for you without explaining what you are actually trying to do. If you are using "hobby" servos, I've never seen one containing worm gears. Having a servo strain against a spring might not be a good idea unless the spring is used as a counter balance for some type of a load. You should also describe what function a delay in your code serves.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Wales
Offline Offline
Full Member
***
Karma: 0
Posts: 244
Don't take things too seriously
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Any ideas?

Not really, as you talk of code that doesn't work for you without explaining what you are actually trying to do. If you are using "hobby" servos, I've never seen one containing worm gears. Having a servo strain against a spring might not be a good idea unless the spring is used as a counter balance for some type of a load. You should also describe what function a delay in your code serves.

Sorry.

If I don't include a delay after each instruction to the servo, the servo doesn't move. It doesn't seem to have time to complete the task required of it and the arduino seems to continue onin the loop and forget the command to the servo. If I include a delay the servo moves.

The delay after a command to move to Microseconds(2300) is manageable. It's the delay after Microseconds(600) that I'm keen to eliminate because this is encountered ALL the time in my sketch.

I had hoped to be able to use "detach" to return the servo to a default position given that the bell cord is lightly sprung.

Basically my  servo pulls a string which is attached to and thus rings a bell. It's important that for the bell to ring just once per request that the back and forth movement of the servo arm is conflated into one as far as the bell is concerned.

I can attach a YouTube video if this is still unclear.
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You may need to revisit your mechanical setup for ringing a bell with a servo. Servos move slowly, which may require a mechanical setup different from what you have to be successful. 
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Northern California (by San Francisco)
Offline Offline
Sr. Member
****
Karma: 3
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I can attach a YouTube video if this is still unclear.

A video would help.
Logged

Wales
Offline Offline
Full Member
***
Karma: 0
Posts: 244
Don't take things too seriously
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You may need to revisit your mechanical setup for ringing a bell with a servo. Servos move slowly, which may require a mechanical setup different from what you have to be successful. 

The bell rings just fine - it's just this darned delay I want to eliminate. smiley-wink
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 67
Posts: 3694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Post the whole sketch. I suspect that it's overriding the bell ringing commands on each iteration of loop. Delay would mask that. As ever, can't tell without seeing the code.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34152
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
it's just this darned delay I want to eliminate
The problem is that the servo produces mechanical movement and that takes time. So you are using delay to make the processor wait until the servo has had time to move. I suspect that the code is operating so fast that it is commanding the servo to move back before it has even set off. This is why you think it is ignoring the command. Software does not ignore anything.

You can get round this in two ways:-
1) Have some sort of sensor that detects when the servo has reached the correct position and don't command the servo to move again until the sensor has been triggered.

2) Have a value set by millis() when the servo is first commanded to move, then don't command it to move again until that value plus a delay constant is less than the current value of millis()
Logged

Pages: [1]   Go Up
Jump to: