{"id":22,"date":"2025-04-12T07:03:46","date_gmt":"2025-04-12T07:03:46","guid":{"rendered":"http:\/\/sunun.top\/wordpress\/?p=22"},"modified":"2025-04-12T07:03:46","modified_gmt":"2025-04-12T07:03:46","slug":"using-a-flow-sensor-with-esp32","status":"publish","type":"post","link":"https:\/\/sunun.top\/wordpress\/index.php\/2025\/04\/12\/using-a-flow-sensor-with-esp32\/","title":{"rendered":"Using a flow sensor with esp32"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>#include &lt;WiFi.h>\n#include &lt;PubSubClient.h>\n#include &lt;time.h>  \/\/ \u0e44\u0e25\u0e1a\u0e23\u0e32\u0e23\u0e35\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e14\u0e36\u0e07\u0e40\u0e27\u0e25\u0e32\u0e08\u0e32\u0e01 NTP\n#include \"esp_adc_cal.h\"\n\nextern \"C\" {\n  uint8_t temprature_sens_read();\n}\n\n\/\/ WiFi Credentials\nconst char *ssid = \"xxx\";  \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e0a\u0e37\u0e48\u0e2d WiFi \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\nconst char *password = \"xxx\";   \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e23\u0e2b\u0e31\u0e2a\u0e1c\u0e48\u0e32\u0e19 WiFi \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\n\n\/\/ MQTT Broker Settings\nconst char *mqtt_server = \"xxx\"; \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19 mqtt server \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\nconst int mqtt_port = 1883;\nconst char *mqtt_user = \"\";\nconst char *mqtt_pass = \"\";\n\n\/\/ Sensor Settings\nconst int SENSOR_PIN = 4; \/\/ GPIO4 \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d flow sensor\nvolatile long pulse;\n\n\/\/Restart\nunsigned long startMillis = 0;  \/\/ \u0e40\u0e27\u0e25\u0e32\u0e40\u0e23\u0e34\u0e48\u0e21\u0e15\u0e49\u0e19\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e08\u0e31\u0e1a\u0e40\u0e27\u0e25\u0e32\nconst unsigned long rebootInterval = 300000; \/\/ 5 \u0e19\u0e32\u0e17\u0e35 = 300,000 ms \u0e15\u0e31\u0e49\u0e07\u0e40\u0e27\u0e25\u0e32\u0e23\u0e35\u0e1a\u0e39\u0e15 MCU\n\nconst char *DISPENSOR_ID = \"xxx\"; \/\/ \u0e15\u0e31\u0e49\u0e07\u0e0a\u0e37\u0e48\u0e2d ID \u0e02\u0e2d\u0e07\u0e2d\u0e38\u0e1b\u0e01\u0e23\u0e13\u0e4c\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\n\n#define SEND_LED 25 \/\/ \u0e02\u0e32\u0e17\u0e35\u0e48\u0e15\u0e48\u0e2d \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a led \u0e41\u0e2a\u0e14\u0e07\u0e01\u0e32\u0e23\u0e2a\u0e48\u0e07\u0e02\u0e48\u0e49\u0e2d\u0e21\u0e39\u0e25\n#define WIFI_LED 13 \/\/ \u0e02\u0e32\u0e17\u0e35\u0e48\u0e15\u0e48\u0e2d \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a led \u0e41\u0e2a\u0e14\u0e07\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d wifi\n#define MQTT_LED 14 \/\/ \u0e02\u0e32\u0e17\u0e35\u0e48\u0e15\u0e48\u0e2d \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a led \u0e41\u0e2a\u0e14\u0e07\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d mqtt\n\nWiFiClient espClient;\nPubSubClient client(espClient);\nunsigned long lastMsg = 0;\n#define MSG_BUFFER_SIZE (256)\nchar msg&#91;MSG_BUFFER_SIZE];\n\n\/\/ \u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 Timezone \u0e40\u0e1b\u0e47\u0e19 GMT+7 (\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28\u0e44\u0e17\u0e22)\nconst char* ntpServer = \"pool.ntp.org\";\nconst long  gmtOffset_sec = 7 * 3600; \/\/ UTC+7\nconst int   daylightOffset_sec = 0;\n\nvoid IRAM_ATTR increase() {\n  pulse++;\n}\n\n\/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d WiFi\nvoid setup_wifi() {\n  Serial.print(\"Connecting to WiFi: \");\n  Serial.println(ssid);\n  digitalWrite(WIFI_LED, LOW);\n  WiFi.mode(WIFI_STA);\n  WiFi.begin(ssid, password);\n\n  int attempt = 0;\n  while (WiFi.status() != WL_CONNECTED &amp;&amp; attempt &lt; 20) {\n    delay(1000);\n    Serial.print(\".\");\n    attempt++;\n  }\n\n  if (WiFi.status() == WL_CONNECTED) {\n    Serial.println(\"\\nWiFi Connected!\");\n    Serial.print(\"IP Address: \");\n    Serial.println(WiFi.localIP());\n    Serial.print(\"MAC Address: \");\n    Serial.println(WiFi.macAddress());\n    Serial.print(\"WiFi Status: \");\n    Serial.println(WiFi.status());\n    digitalWrite(WIFI_LED, HIGH);  \/\/ \u0e15\u0e34\u0e14 LED \u0e17\u0e35\u0e48 IO1 \u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21 WiFi \u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\n    \/\/ \u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 NTP\n    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);\n    delay(2000); \/\/\u0e01\u0e48\u0e2d\u0e19 MQTT 2 \u0e27\u0e34\n  } else {\n    Serial.println(\"\\nWiFi Connection Failed!\");\n    digitalWrite(WIFI_LED, LOW);  \/\/ \u0e14\u0e31\u0e1a LED \u0e17\u0e35\u0e48 IO1 \u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21 WiFi \u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\n  }\n}\n\n\/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19 Callback \u0e40\u0e21\u0e37\u0e48\u0e2d\u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a MQTT Message\nvoid callback(char *topic, byte *payload, unsigned int length) {\n  Serial.print(\"Message arrived &#91;\");\n  Serial.print(topic);\n  Serial.print(\"] \");\n  \n  for (int i = 0; i &lt; length; i++) {\n    Serial.print((char)payload&#91;i]);\n  }\n  Serial.println();\n\n  \/\/ \u0e40\u0e0a\u0e47\u0e04\u0e04\u0e48\u0e32\u0e08\u0e32\u0e01 Payload (0 \u0e2b\u0e23\u0e37\u0e2d 1) \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e04\u0e27\u0e1a\u0e04\u0e38\u0e21 LED\n  if ((char)payload&#91;0] == '1') {\n    digitalWrite(SEND_LED, LOW);\n  } else {\n    digitalWrite(SEND_LED, HIGH);\n    digitalWrite(MQTT_LED, LOW);\/\/\u0e14\u0e31\u0e1a mqtt\n  }\n}\n\n\/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d MQTT\nvoid reconnect() {\n  while (!client.connected()) {\n    Serial.print(\"Attempting MQTT connection...\");\n    String clientId = String(DISPENSOR_ID) + \"-\" + String(random(0xffff), HEX);\n\n    if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {\n      Serial.println(\"Connected to MQTT Broker!\");\n      digitalWrite(MQTT_LED, HIGH);  \/\/ \u0e15\u0e34\u0e14 LED \u0e17\u0e35\u0e48 IO3 \u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d MQTT \u0e44\u0e14\u0e49\n      digitalWrite(WIFI_LED, LOW); \/\/ \u0e14\u0e31\u0e1a Wifi-LED\n      client.subscribe(\"KMITL\/water\");\n    } else {\n            int retryCount = 0;\n            while (!client.connected()) {\n              Serial.print(\"Failed, rc=\");\n              Serial.print(client.state());\n              Serial.println(\" Try again in 5 seconds...\");\n              delay(2000);\n              retryCount++;\n\n              if (retryCount >= 5) {\n                Serial.println(\"Failed to connect 5 times. Restarting...\");\n                digitalWrite(MQTT_LED, LOW);\n                ESP.restart();\n              }\n            }\n    }\n  }\n}\n\n\/\/ \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e14\u0e36\u0e07\u0e40\u0e27\u0e25\u0e32\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\nString getTimeString() {\n  struct tm timeinfo;\n  if (!getLocalTime(&amp;timeinfo)) {\n    Serial.println(\"Failed to obtain time\");\n    return \"N\/A\";\n  }\n  \n  char timeStr&#91;20];\n  strftime(timeStr, sizeof(timeStr), \"%Y-%m-%d %H:%M:%S\", &amp;timeinfo);\n  return String(timeStr);\n}\n\nvoid setup() {\n  pinMode(SEND_LED, OUTPUT);\n  pinMode(WIFI_LED, OUTPUT);  \n  pinMode(MQTT_LED, OUTPUT);  \n  Serial.begin(115200);\n\n  pinMode(SENSOR_PIN, INPUT);\n  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), increase, RISING);\n\n  setup_wifi();\n  client.setServer(mqtt_server, mqtt_port);\n  client.setCallback(callback);\n\n  startMillis = millis();\n}\n\nvoid loop() {\n  if (!client.connected()) {\n    reconnect();\n  }\n  client.loop();\n\n  unsigned long now = millis();\n  if (now - lastMsg > 20000) { \/\/ \u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e38\u0e01 30 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35 \/ \u0e2b\u0e31\u0e01\u0e44\u0e1f\u0e01\u0e23\u0e30\u0e1e\u0e23\u0e34\u0e1a 10 \u0e27\u0e34\n    lastMsg = now;\n    float volume = pulse * 1.25;\n    pulse = 0;\n\n    \/\/ \u0e23\u0e31\u0e1a\u0e40\u0e27\u0e25\u0e32\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\n    String timestamp = getTimeString();\n\n    Serial.print(\"Volume: \");\n    Serial.print(volume);\n    Serial.println(\" ml\");\n\n  uint8_t temp_farenheit = temprature_sens_read();\n  float temp_celsius = ( temp_farenheit - 32 ) \/ 1.8;\n  \n  Serial.print(\"Internal Temperature (\u00b0C): \");\n  Serial.println(temp_celsius);\n\n    \/\/ \u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 MQTT \u0e1e\u0e23\u0e49\u0e2d\u0e21 Timestamp\n      snprintf(msg, MSG_BUFFER_SIZE, \"{\\\"id\\\":\\\"%s\\\",\\\"volume\\\":%.2f,\\\"timestamp\\\":\\\"%s\\\",\\\"ip\\\":\\\"%s\\\",\\\"Gateway ip\\\":\\\"%s\\\",\\\"MCU\\\":%.2f}\", \n      DISPENSOR_ID, volume, timestamp.c_str(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str(), temp_celsius);\n\n    Serial.println(msg);\n    client.publish(\"KMITL\/water\", msg);\n    \/\/\u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e44\u0e1f\u0e01\u0e23\u0e30\u0e1e\u0e23\u0e34\u0e1a 50 \u0e04\u0e23\u0e31\u0e49\u0e07 10 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35 10,000\/50\/2\n    for (int i = 0; i &lt; 50; i++) {\n      digitalWrite(SEND_LED, LOW);\n      delay(100);\n      digitalWrite(SEND_LED, HIGH);\n      delay(100);\n    }\n  }\n\n    \/\/ \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e48\u0e32\u0e04\u0e23\u0e1a 5 \u0e19\u0e32\u0e17\u0e35\u0e2b\u0e23\u0e37\u0e2d\u0e22\u0e31\u0e07\n    if (millis() - startMillis >= rebootInterval) {\n    Serial.println(\"Rebooting MCU...\");\n    delay(100);  \/\/ \u0e2b\u0e19\u0e48\u0e27\u0e07\u0e40\u0e25\u0e47\u0e01\u0e19\u0e49\u0e2d\u0e22\u0e43\u0e2b\u0e49\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01\u0e01\u0e48\u0e2d\u0e19\n    ESP.restart();  \/\/ \u0e2a\u0e31\u0e48\u0e07\u0e43\u0e2b\u0e49\u0e23\u0e35\u0e1a\u0e39\u0e15\n  }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-22","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=22"}],"version-history":[{"count":1,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22\/revisions"}],"predecessor-version":[{"id":23,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22\/revisions\/23"}],"wp:attachment":[{"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sunun.top\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}