Reading wrong data with HC-SR04 in arduino using FreeRTOS on ESP32

I am currently learning FreeRTOS and I wanted to integrate as a task the code from the ultrasonic distance measure(HC SR04) example and simply print it into the serial, but at some points it measures wrong. It jumps from 8 to 25 even tho I am not moving the object at the distance, it should be like 10-12 but not 25. If I am doing the code in a loop, it works.

 //Use only one core for complexity purposes
    #if CONFIG_FREERTOS_UNICORE
      static const BaseType_t app_cpu = 0;
    #else
      static const BaseType_t app_cpu = 1;
    #endif

    // defines pins numbers
    static const uint8_t trigPin = 2;
    static const uint8_t echoPin = 4;
    
    void task_distance(void *parameter)
    {
       while(1){
         long duration;
          int distance;

            // Clears the trigPin
          digitalWrite(trigPin, LOW);
          delayMicroseconds(2);

          // Sets the trigPin on HIGH state for 10 micro seconds
          digitalWrite(trigPin, HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin, LOW);

          // Reads the echoPin, returns the sound wave travel time in microseconds
          duration = pulseIn(echoPin, HIGH);

          // Calculating the distance
          distance = duration * 0.034 / 2;

          // Prints the distance on the Serial Monitor
          Serial.print("Distance: ");
          Serial.println(distance);
    
           vTaskDelay(100 / portTICK_PERIOD_MS );
       }
        
    
    }
    
    void setup() {
    
    
      pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
      pinMode(echoPin, INPUT); // Sets the echoPin as an Input
      Serial.begin(9600); // Starts the serial communication
    
    
      xTaskCreatePinnedToCore(task_distance, "Senzor distanta", 2048, NULL, 1, NULL, app_cpu);
    }
    void loop() {
    
    }

You should post the code doing the measurement and your basic application setup (platform, other tasks created, etc.). Otherwise it’s impossible to guess what’s going on.

I just edited my post, thanks

If the timing needs to be precise (the 10 us delay) you have to disable all interrupts. Otherwise the delay can’t be guaranteed because an interrupt could kick in or even worse a task switch could happen.
With FreeRTOS you it’s usually sufficient to enclose the (short !) critical code by a critical section.

    taskENTER_CRITICAL();

          // Sets the trigPin on HIGH state for 10 micro seconds
          digitalWrite(trigPin, HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin, LOW);

    taskEXIT_CRITICAL();

Note I’m just guessing that the code above IS the measurement because I don’t know how it really is.

2 Likes

Thank you so much! I was really stuck on this and didn’t understand what was happening.