Go Down

Topic: unreliable measurment using an uno with parallax ping sensor and servo (Read 474 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