Skip to main content

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
Asked
Modified 26 days ago
Viewed 68 times
0
\$\begingroup\$

I am having a problem with my flowsensor circuit as show in the figure.

Schematics diagram

where SF800 is the flow sensor I am using. It's a pulse sensor PNP/NPN contact. Hence the pulse signal pin in pull up using a 2.2 kΩ resistor as the manufacturer says. The K - Factor of the sensor given by the manufacturer is around 5600 pulses per litre. SF800 sensor is provided with a 3/8-inch NPT male threaded connection.

// Interrupt handler
static void IRAM_ATTR flow_sensor_isr_handler(void* arg) {
  if (PULSE_TASK_FLAG) {
    PULSE_COUNTER++;
  }
}


void init_flow_sensor() {
    // Configure GPIO
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << GPIO_PULSE_SENSOR_IO),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_ENABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_NEGEDGE  // Falling edge trigger
    };
    gpio_config(&io_conf);

    // Install ISR service
    gpio_install_isr_service(ESP_INTR_FLAG_NMI);

    // Attach interrupt handler
    gpio_isr_handler_add(GPIO_PULSE_SENSOR_IO, flow_sensor_isr_handler, NULL);
}


static void pulse_task (void *arg) {
  const char * tag = "PULSE Task ";
  char packet[64];

  // Initialize flow sensor
  init_flow_sensor();
  // Initialize last time
  lastTime = esp_timer_get_time();

  while (1) {
    // ESP_LOGI(tag, "Pulse Test");
    if (PULSE_TASK_FLAG) {
      int64_t currentTime = esp_timer_get_time();
      int64_t deltaTime = currentTime - lastTime;

      if (deltaTime >= 100000) {  // Update every 1 second (in microseconds)
        uint32_t currentPULSE_COUNTER = PULSE_COUNTER;
        PULSE_COUNTER = 0;  // Reset counter

        // Calculate flow rate and total flow
        FLOW_RATE = (currentPULSE_COUNTER / (float) K_FACTOR) * 600;  // Convert pulses/sec to LPM
        TOTAL_FLOW += FLOW_RATE * (deltaTime / 60000000.0); // Add to total flow (convert us to minutes)

        // ESP_LOGI(TAG, "Delta: %lld, Flow Rate: %.2f LPM | Total Flow: %.2f L", deltaTime, FLOW_RATE, TOTAL_FLOW);

        lastTime = currentTime;
      }
      // Send FUEL Data to the HMI
      gen_packet("FUEL", "PUL", TOTAL_FLOW, packet, sizeof(packet));  // Generate packet
      sendData(tag, packet);
      vTaskDelay(pdMS_TO_TICKS(10));

      if (DEF_SET_VALUE && TOTAL_FLOW >= DEF_SET_VALUE) {
        pump_stop();
        ESP_LOGI(tag, "Set value %.2f reached! --- %.2f", DEF_SET_VALUE, TOTAL_FLOW);
      }
    } else {
      // Pause counting when the flag is not set
      //
    }
    vTaskDelay(pdMS_TO_TICKS(10));
  }
}

The problem I am facing is that when I test it for 5 litres I am getting an error of (+/-)30 ml. (Say for 5 litres I get from 4.98 to 5.10 litres. Also when I go for 10 litres the error buildup is also increasing (but no linearly). Also it varies if I decrease the flow through the sensor using a valve). Hence this error is not at all acceptable. I need the error to be minimal say 20 ml max.

I am getting a doubt that there should be some mistake in my code. SF800 is said to be an accurate sensor [No Detailed Datasheet is available for the sensor other than its connection diagram]. The code is done based on ESP IDF framework. The code block containing the pulse task is attached above. The Pulse task is a FreeRTOS Task which run independantly.

The PULSE_TASK_FLAG is set high when the motor is switched ON, which causes the water to flow through the sensor. Then the task starts calculating the TOTAL_FLOW through the sensor until the motor is Switched OFF. flow_sensor_isr_handler is an interrupt handler which counts the pulses.

I would be grateful for any recommendations of alternative sensors that you have successfully implemented in previous projects.

If there is a requirement for any more information I can provide it.

\$\endgroup\$
3
  • \$\begingroup\$ So, where is the link to where the accuracy is stated for the flow sensor? \$\endgroup\$
    Andy aka
    –  Andy aka
    2025-09-21 15:32:47 +00:00
    Commented Sep 21 at 15:32
  • \$\begingroup\$ This question is similar to: Problem Measuring with optical pulse flow meter. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. \$\endgroup\$
    Andy aka
    –  Andy aka
    2025-09-21 15:56:50 +00:00
    Commented Sep 21 at 15:56
  • \$\begingroup\$ The accuracy is 1% ... swissflow.com/sf800.html so 5L * 0.01 = 50 mL ... \$\endgroup\$
    Antonio51
    –  Antonio51
    2025-09-21 17:49:47 +00:00
    Commented Sep 21 at 17:49

1 Answer 1

2
\$\begingroup\$

When I test it for 5 litres I am getting an error of ±30 ml.

datasheet extract

1% of 5,000 ml = ±50 ml.

At ±30 ml you're doing well.

I need the error to be minimal say 20 ml max.

It looks like it is not possible with this sensor.

\$\endgroup\$

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.