12 Replies Latest reply on Oct 5, 2014 2:16 PM by gowrisomanath

    HC-SR04 Sketch

    DaAmazing1

      HI All,

      I'm attempting to find a way to hook up my HC-SR04 to Galileo and since the NewPing and Ultrasonic libraries both don't work because of either the pulseIn function not being implemented or dependencies on the AVR. I decided to try a different route and wrote up this sketch using digital read and write functions to get the reading from the HC-SR04.  The sketch works fine on the Arduino Uno, but when I transfer the sketch to the Galileo board it appears to hang if the value from the HC-SR04 changes...  I'm stuck on figuring this out any insights would be awesome.

       

      #define ECHOPIN 3
      #define TRIGGERPIN 4
      #define US_ROUNDTRIP_IN 146    
      #define US_ROUNDTRIP_CM 57     
      #define PingConvert(echoTime, conversionFactor) ((echoTime + conversionFactor / 2) / conversionFactor)
      
      
      unsigned long pinStart;
      unsigned long pinEnd;
      
      
      void setup(){
        pinMode(TRIGGERPIN, OUTPUT);
        pinMode(ECHOPIN, INPUT);
        pinMode(13, OUTPUT);  
      }
      
      
      void loop(){
        digitalWrite(TRIGGERPIN,LOW);
        delayMicroseconds(2);
        digitalWrite(TRIGGERPIN,HIGH);
        delayMicroseconds(10);
        digitalWrite(TRIGGERPIN,LOW);
      
        while(digitalRead(ECHOPIN)==LOW){}; //waiting for the pin to trigger
        pinStart = micros();
        while(digitalRead(ECHOPIN)==HIGH){};//waiting for the pin to go low
        pinEnd = micros();
      
        unsigned int echoTime = pinEnd - pinStart;
        if(PingConvert(echoTime,US_ROUNDTRIP_IN)<6){
          digitalWrite(13, HIGH);
          delay(2000);
        }
        digitalWrite(13, LOW);
        delay(1000);
      }
      
      
        • 1. Re: HC-SR04 Sketch
          Mikal.Hart

          I think I've figured this out.

           

          echoTime is the number of microseconds it took for the echo to arrive back at the source, as measured by repeated calls to digitalRead on the "echo" pin.  Unfortunately, since an ordinary digitalRead on Galileo takes between 4 and 5 milliseconds, that is, at least 4000 microseconds, the value returned by PingConvert will always be well over 6 and so the LED will never illuminate.

           

          Since your sensor is connected to pin 3, you might be able to make use of Galileo's "fast" GPIO.  See elsewhere in this forum for details.

           

          Incidentally, you could easily verify my theory with a couple of well-placed Serial.print() statements.  Try, for example, printing the value returned by PingConvert().

          • 2. Re: HC-SR04 Sketch
            AlexT_Intel

            There was some investigation done on digitalRead() duration (see here: Re: DHT11 Temperature Sensor Issue) and on average it's about 2200 us for "standard" pins and ~50 us for pins 2 and 3 in "fast" mode.

            1 of 1 people found this helpful
            • 3. Re: HC-SR04 Sketch
              DaAmazing1

              Thanks for pointing me in the right direction, by using the fast GPIO I was able to start getting reading that I can use.

              • 4. Re: HC-SR04 Sketch
                Feoras

                Glad you got it working.  Any chance you could publish the sketch?  Thanks

                • 5. Re: Re: HC-SR04 Sketch
                  gowrisomanath

                  After looking at the different helpful tips and general google search, this is what worked consistently for me

                  As of May/June 2014 release, the Timer1 interrupt seems to be working, so iused that.

                   

                  #include <TimerOne.h>

                  #define speakerPin 9

                  #define trigPin 7

                  #define echoPin2 2

                  unsigned long SEC=1000; //1sec = 10^6microsecond

                  long  pstart=0;

                  long  pstop=0;

                  boolean got=false;

                  int freq=500; //in Hz (1/sec)

                  int tt=SEC/freq/2;

                   

                  void setup() {

                    Serial.begin (9600);

                    pinMode(trigPin, OUTPUT_FAST);

                    pinMode(echoPin2, INPUT_FAST);

                   

                    Timer1.initialize(SEC);

                    //you need at least 15us + ping time. it didnt work below 1000us for me for below code

                    Timer1.attachInterrupt( pingUltra ,SEC);

                   

                  }

                  void pingUltra()

                  {

                    got=false;

                   

                    digitalWrite(trigPin, LOW); 

                    delayMicroseconds(2);

                    digitalWrite(trigPin, HIGH);

                    delayMicroseconds(10);

                    digitalWrite(trigPin, LOW);

                  // NOT checking for LOW. it seemed to hang here if i used it.

                    pstart=micros();

                    while(digitalRead(echoPin2)==HIGH){}

                    pstop=micros();

                   

                    got=true;

                  }

                   

                   

                  void loop() {

                    //DO usual other stuff

                    if(got) //if you got the ultrasonic ping back

                    {

                      got=false;

                      //DO what you would when u got a ping

                      if(((pstop-pstart)/29/2)<10)

                      {//check if distance is < 10cm (using hc sr04). If so sound a buzzer

                         for(int i=0;i<10;i++)

                       { 

                            analogWrite(speakerPin,200);

                            delayMicroseconds(tt);

                            analogWrite(speakerPin,0);

                            delayMicroseconds(tt);

                       }

                          analogWrite(speakerPin,00);

                    

                       }

                    }

                   

                  }

                  • 6. Re: HC-SR04 Sketch
                    Pezet2006

                    hi gowrisomanath,

                     

                    Can i know if you have chance to try with 2 ultrasonic. i try to your code but able to work with one Ultrasonic not 2.

                     

                    Thanks

                    • 7. Re: HC-SR04 Sketch
                      gowrisomanath

                      hey

                      INPUT_FAST is available on two pins, so make sure you connect to those, and change the code accordingly.

                      I've also used analog pins with similar logic and connected upto 5 of these.

                       

                      Can you tell me what you tried and how it failed?

                      • 8. Re: HC-SR04 Sketch
                        pezet2006.

                        // when I used 2 time timer1.attachinterrupt it will not continue to keep running the loop

                         

                        #include <TimerOne.h>

                        // value 14 is will not be used

                        #define speakerPinLeft 14 //11 is the correct one

                        #define trigPinLeft 9 //9 is the correct one

                        #define echoPinLeft 2 //2 is the correct one but if 2 and 3 pin on then result fail

                        #define speakerPinRight 11

                        #define trigPinRight 13 // 13 is the correct one

                        #define echoPinRight 3 // 3 is the correct one

                        #define ledyellowleft 14 //12 is the correct one

                        #define ledredleft 14 //10 is the correct one

                        #define ledyellowright 12

                        #define ledredright 10

                         

                        int iLeft, iRight;

                        //For Left Counter

                        unsigned long SEC=1000; //1sec = 10^6microsecond

                        long  pstart=0;

                        long  pstop=0;

                         

                        //For Right Counter

                        unsigned long SEC2=1000; //1sec = 10^6microsecond

                        long  pstart2=0;

                        long  pstop2=0;

                         

                        void setup() {

                          Serial.begin (9600);

                          pinMode(trigPinLeft, OUTPUT_FAST);

                          pinMode(echoPinLeft, INPUT_FAST);

                          pinMode(trigPinRight, OUTPUT_FAST); // ori OUTPUT_FAST

                          pinMode(echoPinRight, INPUT_FAST);  // INPUT_FAST

                          pinMode(ledyellowleft, OUTPUT); 

                          pinMode(ledredleft, OUTPUT);

                          pinMode(ledyellowright, OUTPUT);

                          pinMode(ledredright, OUTPUT);

                         

                               

                          Timer1.initialize(SEC); // ori location

                          //you need at least 15us + ping time. it didnt work below 1000us for me for below code

                        }

                         

                         

                         

                        void pingUltra()

                        {

                          digitalWrite(trigPinLeft, LOW);

                          delayMicroseconds(2);

                          digitalWrite(trigPinLeft, HIGH);

                          delayMicroseconds(10);

                          digitalWrite(trigPinLeft, LOW);

                        // NOT checking for LOW. it seemed to hang here if i used it.

                          pstart=micros();

                          while(digitalRead(echoPinLeft)==HIGH){}

                          pstop=micros();

                        iLeft = (pstop-pstart)/29/2; //testing only

                        }

                         

                        void pingUltra2()

                        {

                          digitalWrite(trigPinRight, LOW);

                          delayMicroseconds(2);

                          digitalWrite(trigPinRight, HIGH);

                          delayMicroseconds(10);

                          digitalWrite(trigPinRight, LOW);

                        // NOT checking for LOW. it seemed to hang here if i used it.

                          pstart2=micros();

                          while(digitalRead(echoPinRight)==HIGH){}

                          pstop2=micros();

                          iRight = (pstop2-pstart2)/29/2; //testing only

                        }

                         

                        void loop() {

                        Timer1.attachInterrupt( pingUltra ,SEC); // only either one of the timer is commented out then its ok

                        Timer1.attachInterrupt( pingUltra2 ,SEC); // only either one of the timer is commented out then its ok

                          Serial.print (iLeft);

                          Serial.print (" CM left     ");

                          Serial.print (iRight);

                          Serial.println (" CM right");

                        delay (500);

                        }

                        • 9. Re: HC-SR04 Sketch
                          pezet2006.

                          the result is only one time

                          0 CM left     0 CM right

                           

                          but if one of the timer is commented out then its able to get all the correct result in the loop

                          • 10. Re: HC-SR04 Sketch
                            gowrisomanath

                            Timer1 can have only one function attached to its ISR. thats why both are not working.

                            You should operate both within the same fuction, and attach that to the timer.

                            • 11. Re: HC-SR04 Sketch
                              pezet2006.

                              sorry i'm still new to this..

                               

                              are you referring that i should put both the digitalwrite for the trigPinLeft and trigPinRight on the same function like as bellow. It still does not work with as bellow. With the bellow one now i have nothing at all.   

                              mind to share you code that has 2 UltraSonic attach to it so that i can used yours as sample.

                               

                              void pingUltra()

                              {

                                digitalWrite(trigPinLeft, LOW);

                                digitalWrite(trigPinRight, LOW);

                                delayMicroseconds(2);

                                digitalWrite(trigPinLeft, HIGH);

                                digitalWrite(trigPinRight, HIGH);

                                delayMicroseconds(10);

                                digitalWrite(trigPinLeft, LOW);

                                digitalWrite(trigPinRight, LOW);

                              // NOT checking for LOW. it seemed to hang here if i used it.

                                pstart=micros();

                                while(digitalRead(echoPinLeft)==HIGH){}

                                pstop=micros();

                                pstart2=micros();

                                while(digitalRead(echoPinLeft)==HIGH){}

                                pstop2=micros();

                              iLeft = (pstop-pstart)/29/2; //testing only

                              iRight = (pstop2-pstart2)/29/2; //testing only

                              }

                              • 12. Re: HC-SR04 Sketch
                                gowrisomanath

                                You should do one at a time. In your code, you tried to trigger both left and right, and then read left twise.

                                Also from what I remember there are just two fast pins on galileo so make sure to connect the two echo pins to that

                                Here is what i'd try

                                 

                                 

                                 

                                void pingUltra()

                                {

                                //----------do the left

                                digitalWrite(trigPinLeft, LOW);

                                delayMicroseconds(2);

                                  digitalWrite(trigPinLeft, HIGH);

                                  delayMicroseconds(10);

                                  digitalWrite(trigPinLeft, LOW);

                                pstart=micros();

                                  while(digitalRead(echoPinLeft)==HIGH){}

                                  pstop=micros();

                                  iLeft = (pstop-pstart)/29/2; //testing only


                                //-----------now do the right same as above - change variables as needed



                                }