3 Replies Latest reply on Dec 21, 2016 7:13 PM by marcuso

    HC-SR04 distance measurement is not working with Intel Curie

    tigikthomas

      Hi,

        I am trying to use SR04 ultrasonic sensor for distance measurement using Intel Curie (Arduino101)...

       

      Following is the code

       

      1. #define ECHOPIN 3 
      2. #define TRIGGERPIN 4 
      3. #define US_ROUNDTRIP_IN 146     
      4. #define US_ROUNDTRIP_CM 57      
      5.  
      6.  
      7. unsigned long pinStart; 
      8. unsigned long pinEnd; 
      9.  
      10.  
      11. void setup(){ 
      12.   pinMode(TRIGGERPIN, OUTPUT); 
      13.   pinMode(ECHOPIN, INPUT); 
      14.   pinMode(13, OUTPUT);   
      15.  
      16.  
      17. void loop(){ 
      18.   digitalWrite(TRIGGERPIN,LOW); 
      19.   delayMicroseconds(2); 
      20.   digitalWrite(TRIGGERPIN,HIGH); 
      21.   delayMicroseconds(10); 
      22.   digitalWrite(TRIGGERPIN,LOW); 
      23.  
      24.   while(digitalRead(ECHOPIN)==LOW){}; //INTEL CURIE HANGS HERE. THE GPIO PIN is not seeing the high pulse from the Echoline.
      25.   pinStart = micros(); 
      26.   while(digitalRead(ECHOPIN)==HIGH){};//
      27.   pinEnd = micros(); 
      28.    o
      29.  
      30.   delay(1000); 

       

      I have verified the signals from the SR04 and are working..

      I could see that Intel Curie is not see the short Echo pulse going high and gets stuck in the while loop @ line no.25.

      I could see many threads in Intel Galileo on the similar grounds and they have solved the problem by making GPIO in the OUTPUT_FAST/INPUT_FAST mode.

      However I am not seeing any such options with Intel Curie Arduino 101.

       

      What is the better option to get this common distance sensing application working...

       

      Regards

      Tigi

       

        • 1. Re: HC-SR04 distance measurement is not working with Intel Curie
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hi Tigi,

          Thank you very much for contacting us, however, this seems more related to the Arduino 101 forum, which you can access using this link https://forum.arduino.cc/index.php?board=103.0. They are the ones in charge of the Arduino 101 support, so they’ll be able to provide a more accurate answer.

          Regards,
          -Pablo

          • 2. Re: HC-SR04 distance measurement is not working with Intel Curie
            vraoresearch

            Your code snippet works for me as is. However, you could improve it by using:

            pulseIn(ECHOPIN, HIGH, 30000);

            Instead of the while loops. This method works on both Curie ODK and Arduino IDE

             

            If the sensor consistently shows ECHOPIN high then it could be a bad sensor/connection or the sensor my be out of range.

            • 3. Re: HC-SR04 distance measurement is not working with Intel Curie
              marcuso

              Hi,

               

              see here for more info :

               

              Robotics,Electronics and AI for Robots Including Blog on The Agent 390

               

              The above comment is correct, this is a problem with the Arduino side of the 101, not the really Intel side. So I'll give you a brief run down even though its nothing to do with the Intel side !

               

              There are 2 ways to wire up the HR-SR04 ultra sonic sensor. One can use a seperate cable for signal and echo, or combine the two toegther. In my experience it's better to combine them. So you have a +ve, -ve(gnd)  and a signal line back to the Arduino.

               

              If you are going to use the common signal line you will need to use this library :

               

              GitHub - PaulStoffregen/NewPing: NewPing Library (Ultrasonic Sensors)

               

              Pull the zip down and install it in the Arduino Library folders (lots of isytruction on the web for this).

               

              New Wire Arduino library is really easy to use.

               

              When you have installed the library in the Arduino IDE, you will pull in this header....

               

              #include <NewPing.h>

               

              So create an array of sensors , lets have 9 for now...

               

              #define NUM_SONICS 9

               

              I have the echo and singal for each sensor twisted together, and the first pin on the Arduino with one of these connected is pin 2

               

              #define PING_PIN 2

               

              I'm going to set the macimum distance to detect to 250 cm

               

              #define MAX_DISTANCE 250

               

              NewPing sonar[NUM_SONICS] = { // Sensor object array.

                  NewPing(PING_PIN, PING_PIN, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.

                  NewPing(PING_PIN + 1, PING_PIN + 1, MAX_DISTANCE),

                  NewPing(PING_PIN + 2, PING_PIN + 2, MAX_DISTANCE),

                  NewPing(PING_PIN + 3, PING_PIN + 3, MAX_DISTANCE),

                  NewPing(PING_PIN + 4, PING_PIN + 4, MAX_DISTANCE),

                  NewPing(PING_PIN + 5, PING_PIN + 5, MAX_DISTANCE),

                  NewPing(PING_PIN + 6, PING_PIN + 6, MAX_DISTANCE),

                  NewPing(PING_PIN + 7, PING_PIN + 7, MAX_DISTANCE),

                  NewPing(PING_PIN + 8, PING_PIN + 8, MAX_DISTANCE)

              };

               

              I want  to store the results of each of my 9 sensors in a global int array, The range is 0-500, so 0-500 centimetres

               

              int LastResults[NUM_SONICS];

               

              Now when I want to actually ping my sensors I do this using the main loop :

               

              void loop()

              {

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

                   {

                          delay(DELAY_BETWEEN_PINGS);

               

                          //US_ROUNDTRIP_CM - is defined in the Library

                          LastResults[i] = sonar[i].ping() / US_ROUNDTRIP_CM;

                               

              #ifdef DEBUG

                          Serial.print("USS#");

                          Serial.print(i);

                          Serial.print(':');

                          Serial.print(LastResults[i]);

                          Serial.println("cm");

              #endif

                      }

                   delay(LOOP_FREQUENCY);

              }

               

              I set the following configurable settings - experiment and see what works best for you :

               

              #define LOOP_FREQUENCY 50

              #define DELAY_BETWEEN_PINGS 15

               

              I have a robot with 9 sensors on, 2 ineach direction, and an extra on the front. Each sensor has a beam dispersion of 15 degrees, so I have one on the each corner of the robot so as not to hit anything. I also have some more sensors pointing to the floor to detect if Im going to drive down a hole ! I have a staircase in my apt, I dont want the robot to drive down that !

               

              So I have many separate Arduino systems, some of them connect into the main drive unit - this drive unit is responsible for handling commands to drive the robot, either manually via Bluetooth controller, or automatically via a Raspberry Pi AI system that takes voice instruction like "Go to the kitchen" etc.

               

              All of these communicate with each other via i2c, this is a 2 channel comms protocol, so to pass these signals to the drive unit I do this :

               

              .

              void sendObjectDetectionInfoToi2c(int address)

              {

                  //The length of these tokens does not include a /0

                const char *START_TOKEN = "START:";

                const char *END_TOKEN = "END:";

               

              #ifdef DEBUG

                printThisI2CAddress("Sending USs");

              #endif

               

                  sendItI2c(address, START_TOKEN);

               

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

                  {

                      delay(I2C_WIRE_DELAY);

                      int distance = LastResults[i];

                 

                      //The format is 1 decimal for sensor (as there are <9, and 3 sig places for dist as < 400

                      //So the length of this string is ok, even though there are % in it

                      char message[] = "US:%d=00%d";

                     

                      if (distance < 10)

                          sprintf(message, "US:%d=00%d", i, distance);

                      else if (distance < 100)

                          sprintf(message, "US:%d=0%d", i, distance);

                      else

                          sprintf(message, "US:%d=%d", i, distance);

               

                      sendItI2c(address, message);

               

              #ifdef DEBUG

                      Serial.print("i2c mess:");

                      Serial.println(message);

               

                      Serial.print("Pin:");

                      Serial.println(i);

                     

                      Serial.print("Obj:");

                      Serial.print(distance);

                      Serial.println("cm");

              #endif

                  }

                 

                  sendItI2c(address, END_TOKEN);

               

              #ifdef DEBUG

                  printThisI2CAddress("Sent i2c");

              #endif

              }

               

               

              And the actual function (in a common lib) that sends i2c packets is :

               

              void sendItI2c(const int address, const char *message)

              {

                   Wire.beginTransmission(address);

                   Wire.write(message, strlen(message));

                   Wire.endTransmission();

              }

               

              Where the i2c address is set on startup of the device !!

               

              So that's enough for now, all this is on my Robotics For Dreamers web site ...

               

               

              Robotics,Electronics and AI for Robots Including Blog on The Agent 390

               

              Good luck

               

              Marcus