Go Down

Topic: unreliable measurment using an uno with parallax ping sensor and servo (Read 485 times) previous topic - next topic

cappyjack

Hello! I am using a ping sensor with an arduino uno board. I bought a kit with ping sensor, servo motor and mount. I am sweeping the servo back and forth ~180 deg. and pinging between moves. I have tried two approaches with differing unreliable output. I describe the unreliable output below.  The sketch is very small so I will post the whole thing.


Code: [Select]
        //   sketch to move servo and ping a distance//   two different ways with different results


        #include <ServoTimer2.h> 
        const int pin6 = 6;   //attaches servo to pin 6
        const int ping1 = 7;  //attaches ping sensor to pin 7


        long duration1;      // used in ping function
        long cm1;             // distance value
        int num1;             // direction value out of servo1
        int dir;                // var for switch to sweep servo back & forth in move


        ServoTimer2 servo1;    // declare objects for servos


        void setup() {
          Serial.begin(9600);      // initialize serial communication:
          servo1.attach(pin6);    // attach pins to the servos
          dir = 0;                     // set initial direction of switch statement
          int num1 = 0;            // initialize servo movement var
          duration1 = 0;           // initialize ping var
        } 


        long ping()   // function to drive the ping sensors
        {
          pinMode(ping1, OUTPUT);   
          digitalWrite(ping1, LOW);
          delayMicroseconds(4);  //was 2
          digitalWrite(ping1, HIGH);
          delayMicroseconds(10);   //was 5
          digitalWrite(ping1, LOW);
          pinMode(ping1, INPUT);
          duration1 = pulseIn(ping1, HIGH);
          cm1 = microsecondsToCentimeters(duration1);
          return cm1;
        } 


        long microsecondsToCentimeters(long microseconds)
        {
          // The speed of sound is 340 m/s or 29 microseconds per centimeter.
          // The ping travels out and back, so to find the distance of the
          // object we take half of the distance travelled.
          return microseconds / 29 / 2;
        }  // end of ping


        long out()           
        {
          Serial.print(cm1);
          Serial.println("  cm1  ");
        }


        int move_another(){     // this gets good distance values from i = 45 down to i = 12 then bad distance
          int count = 0;
          int i;
          for ( i = 1; i != 60; i++){     // servo starts in the middle so for the first loop it hangs from i = 30  until i = 60
            if ( i <= 30 ){                  // then it sweeps back and forth ~180 deg correctly
              num1 = (servo1.read() - 50);
              delay(5);     
              servo1.write(num1);
              delay(400);
              ping();
              out();
              count = count + 1;
              Serial.print(i);
              Serial.println("  i < 15  ");
            }
            else{
              num1 = (servo1.read() + 50);
              delay(5);
              servo1.write(num1);
              delay(400);
              ping();
              out();
              count = count + 1;
              Serial.print(i);
              Serial.println("  i > 15  ");
            }
          }
        }


        int move(){        // This one gets 29 good distances  then 29 bad ones ( always 15 cm)
          switch (dir) {
          case 0:
            ping();
            out();
            num1 = (servo1.read() + 50);
            delay(5);     
            servo1.write(num1);
            delay(250);     
            if (num1 >= 2250){
              dir = 1;
            }
            break;
          case 1:
            ping();
            out();
            num1 = (servo1.read() - 50);
            delay(5);
            servo1.write(num1);
            delay(250);
            if (num1 <= 800){
              dir = 0;
            }
            break; 
          }
        }


        void loop()
        {
          move();
        //  move_another(); 
        }

  /code]

   
        The servo moves as expected, back and forth for ~180 deg. The ping sensor works when the servo is off.

        the function  move_another gets good distance values from i = 45 down to i = 12 then bad distance
        Now a good distance is the maximum range- 350 cm and the bad distance is 15 cm. Oddly enough, if I hold
        my hand in front of the bad reading, it gives me a good reading under 15 cm.

        The function move gets 29 good distances then 29 bad ones ( always 15 cm)
        It measures good values, i.e 350 cm, which I can influence with my hand to give different accurate values. The bad values start
        in the middle of a sweep, i.e. num1 < 1550 go down to 750 and back up to 1650 then get good again.

        I wrote another function which has good and bad readings and a few dodgy reading, i.e. 120 cm when it should be 350.
        I am trying to keep the sketch as simple as possible in order to understand why ping works sometimes and not others.
        I thought perhaps the servo motor gives an interference sound and I tested another servo motor with the same result.
        I also tested another ping sensor with the same results.

        Thanks for having a look. Any suggestions are welcome!

        Regards,
        Cappy


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy