Servo movement

Hey y'all,

Working on a project to move a servo with an ultrasonic range finder (HC-SR04). I have movement, but it's repeated and I only want it to move once (from 00-1800-00). Any help is greatly appreciated. Thanks!

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

#include <Servo.h> 
 
Servo servo;  // create servo object to control a servo 
int pos =0;
int maximumRange = 100; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() {
 Serial.begin (9600);
 servo.attach(2);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop() {
/* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 //Calculate the distance (in cm) based on the speed of sound.
 distance = duration/58.2;
 
 if (distance >= maximumRange || distance <= minimumRange){
 /* Send a negative number to computer and Turn LED ON 
 to indicate "out of range" */
 Serial.println("-1");
 digitalWrite(LEDPin, LOW);
 for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
   {                                // in steps of 1 degree 
     servo.write(pos);              // tell servo to go to position in variable 'pos' 
                                    // waits 15ms for the servo to reach the position 
   } 
   for(pos = 99; pos>=1; pos-=1)    // goes from 180 degrees to 0 degrees 
   {                                
     servo.write(pos);            // tell servo to go to position in variable 'pos' 
     delay (5);                     // waits 15ms for the servo to reach the position 
   } 
 }
 else {
 /* Send the distance to the computer using Serial protocol, and
 turn LED OFF to indicate successful reading. */
 Serial.println(distance);
 digitalWrite(LEDPin, HIGH);
 for(pos = 0; pos < 180; pos += 1)   // goes from 0 degrees to 180 degrees 
   {                                 // in steps of 1 degree 
     servo.write(pos);               // tell servo to go to position in variable 'pos' 
                                     // waits 15ms for the servo to reach the position 
   } 
   for(pos = 99; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
   {                                
     servo.write(pos);             // tell servo to go to position in variable 'pos' 
     delay(5);                     // waits 15ms for the servo to reach the position 
   } 
 }
 
 //Delay 50ms before next reading.
 delay(500);
}

Perhaps if you aligned your code with the comments it would work?

At least it would make more sense to me.

...R

Your comments don't match your code. You say you are waiting for the servo to reach position, but you don't.

How do you know your servo will actually go to 180 ?
Why do you go to 180, and then start counting back down again, from 100 ?

You don't do anything while the servo is moving, so you why you tell it to move one degree at a time ?
And without any delay, you won't even accomplish one PWM cycle to the servo, before you start telling
it to go one degree more. Why not just tell it to go straight to 180, or zero, and let it go there ?

Dividing a long by a float, to get a long result, will probably work, but it is dodgy.

Your manipulation of Ledpin seems to be bogus.

You seem to have unecessarily duplicated the code, which makes unnecessary movements of the servo. It is not clear what your algorithm is actually trying to accomplish. Don't you want to point the servo in several different directions, and then use the ultrasound to see if anything is there ? Your code is always going to point the servo in direction 0, and then take a measurement there. Is that what you actually want to do ?

I have movement, but it's repeated and I only want it to move once (from 00-1800-00).

You do realise, do you, that the arduino will execute the loop( ) function, over and over and over again, don't you ?

Yes, I am well aware of the looping that is the purpose of the loop() function. I am looking to interrupt the loop. I found a couple ways and haven't had a chance to try it. The use of the LEDPin informs me that the ping is working properly. The comments are where they need to be. I have the movement necessary, I just need to interrupt the loop.

I just need to interrupt the loop

Well, then you might make the desired loop conditional upon some condition where the looping is desired.

What I said in Reply #1 was meant seriously and could go a long way to solving your problem.

But it's up to you ...

...R

PS, to avoid any confusion, I meant that you should align your code with the comments, NOT align the comments with your code.

Your insights have been helpful. I've changed things around a bit and I have the single movement I'm looking for but I can't get the board to reset to the specified conditions. Any suggestions?

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

 #include <Servo.h> 
 
 Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created
 int resetPin = 12;          
 
 int pos = 0;    // variable to store the servo position 
 
 int maximumRange = 10; // Maximum range needed
 
 int minimumRange = 0; // Minimum range needed
 
 long duration, distance; // Duration used to calculate distance

 
 void setup() 
 { 
   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  
 
 
  pinMode(trigPin, OUTPUT);
 
  pinMode(echoPin, INPUT);
 
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required) 
  
 
 
 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' 
                            // waits 15ms for the servo to reach the position 
   } 
   for(pos = 99; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
   {                                
     myservo.write(pos);              // tell servo to go to position in variable 'pos' 
     delay(5);                       // waits 15ms for the servo to reach the position 
   } 
 } 
 
 
 void loop() 
 { 
   digitalWrite(trigPin, LOW); 
   delayMicroseconds(2); 

   digitalWrite(trigPin, HIGH);
   delayMicroseconds(10); 
 
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH);
 
   //Calculate the distance (in cm) based on the speed of sound.
   distance = duration/58.2;
 
   if (distance >= maximumRange || distance <= minimumRange){
   /* Send a negative number to computer and Turn LED ON 
   to indicate "out of range" */
   digitalWrite(resetPin, LOW);
   digitalWrite(LEDPin, LOW);
    }
   else {
   /* Send the distance to the computer using Serial protocol, and
   turn LED OFF to indicate successful reading. */
   digitalWrite(resetPin, HIGH);
   digitalWrite(LEDPin, HIGH);

 }
 }

Thnaks

It's figured out! My code is successful. The problem wasn't the code but my physical setup. Thanks all for giving me things to ponder.

Your code is still not consistent with your comments.

In that situation comments are a waste of time and just add to the confusion when you try to remember what it all meant in 6 months time.

...R

Robin 2, Would you be able to give me an example? The only part of the comments that seem out of place to me is when the serial protocol is referred to. It's key to have the comments clear when asking for help.
Thanks

There are at least 4 examples in this. One of them probably results in the code not working as expected. With another, it's not clear whether the code would work better with the value in the comment. A third one will confuse the reader and a fourth one is just sloppy.

 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' 
                            // waits 15ms for the servo to reach the position 
   } 
   for(pos = 99; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
   {                                
     myservo.write(pos);              // tell servo to go to position in variable 'pos' 
     delay(5);                       // waits 15ms for the servo to reach the position 
   } 
 }

...R