Using a flow sensor with esp32

#include <WiFi.h>
#include <PubSubClient.h>
#include <time.h>  // ไลบรารีสำหรับดึงเวลาจาก NTP
#include "esp_adc_cal.h"

extern "C" {
  uint8_t temprature_sens_read();
}

// WiFi Credentials
const char *ssid = "xxx";  // เปลี่ยนเป็นชื่อ WiFi ของคุณ
const char *password = "xxx";   // เปลี่ยนเป็นรหัสผ่าน WiFi ของคุณ

// MQTT Broker Settings
const char *mqtt_server = "xxx"; // เปลี่ยนเป็น mqtt server ของคุณ
const int mqtt_port = 1883;
const char *mqtt_user = "";
const char *mqtt_pass = "";

// Sensor Settings
const int SENSOR_PIN = 4; // GPIO4 สำหรับเชื่อมต่อ flow sensor
volatile long pulse;

//Restart
unsigned long startMillis = 0;  // เวลาเริ่มต้นสำหรับจับเวลา
const unsigned long rebootInterval = 300000; // 5 นาที = 300,000 ms ตั้งเวลารีบูต MCU

const char *DISPENSOR_ID = "xxx"; // ตั้งชื่อ ID ของอุปกรณ์ของคุณ

#define SEND_LED 25 // ขาที่ต่อ สำหรับ led แสดงการส่งข่้อมูล
#define WIFI_LED 13 // ขาที่ต่อ สำหรับ led แสดงการเชื่อมต่อ wifi
#define MQTT_LED 14 // ขาที่ต่อ สำหรับ led แสดงการเชื่อมต่อ mqtt

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (256)
char msg[MSG_BUFFER_SIZE];

// ตั้งค่า Timezone เป็น GMT+7 (ประเทศไทย)
const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 7 * 3600; // UTC+7
const int   daylightOffset_sec = 0;

void IRAM_ATTR increase() {
  pulse++;
}

// ฟังก์ชันเชื่อมต่อ WiFi
void setup_wifi() {
  Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);
  digitalWrite(WIFI_LED, LOW);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  int attempt = 0;
  while (WiFi.status() != WL_CONNECTED && attempt < 20) {
    delay(1000);
    Serial.print(".");
    attempt++;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWiFi Connected!");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());
    Serial.print("MAC Address: ");
    Serial.println(WiFi.macAddress());
    Serial.print("WiFi Status: ");
    Serial.println(WiFi.status());
    digitalWrite(WIFI_LED, HIGH);  // ติด LED ที่ IO1 เมื่อเชื่อม WiFi สำเร็จ
    // ตั้งค่า NTP
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
    delay(2000); //ก่อน MQTT 2 วิ
  } else {
    Serial.println("\nWiFi Connection Failed!");
    digitalWrite(WIFI_LED, LOW);  // ดับ LED ที่ IO1 เมื่อเชื่อม WiFi ไม่สำเร็จ
  }
}

// ฟังก์ชัน Callback เมื่อได้รับ MQTT Message
void callback(char *topic, byte *payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // เช็คค่าจาก Payload (0 หรือ 1) เพื่อควบคุม LED
  if ((char)payload[0] == '1') {
    digitalWrite(SEND_LED, LOW);
  } else {
    digitalWrite(SEND_LED, HIGH);
    digitalWrite(MQTT_LED, LOW);//ดับ mqtt
  }
}

// ฟังก์ชันเชื่อมต่อ MQTT
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = String(DISPENSOR_ID) + "-" + String(random(0xffff), HEX);

    if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
      Serial.println("Connected to MQTT Broker!");
      digitalWrite(MQTT_LED, HIGH);  // ติด LED ที่ IO3 เมื่อเชื่อมต่อ MQTT ได้
      digitalWrite(WIFI_LED, LOW); // ดับ Wifi-LED
      client.subscribe("KMITL/water");
    } else {
            int retryCount = 0;
            while (!client.connected()) {
              Serial.print("Failed, rc=");
              Serial.print(client.state());
              Serial.println(" Try again in 5 seconds...");
              delay(2000);
              retryCount++;

              if (retryCount >= 5) {
                Serial.println("Failed to connect 5 times. Restarting...");
                digitalWrite(MQTT_LED, LOW);
                ESP.restart();
              }
            }
    }
  }
}

// ฟังก์ชันดึงเวลาปัจจุบัน
String getTimeString() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return "N/A";
  }
  
  char timeStr[20];
  strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &timeinfo);
  return String(timeStr);
}

void setup() {
  pinMode(SEND_LED, OUTPUT);
  pinMode(WIFI_LED, OUTPUT);  
  pinMode(MQTT_LED, OUTPUT);  
  Serial.begin(115200);

  pinMode(SENSOR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), increase, RISING);

  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  startMillis = millis();
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 20000) { // ส่งข้อมูลทุก 30 วินาที / หักไฟกระพริบ 10 วิ
    lastMsg = now;
    float volume = pulse * 1.25;
    pulse = 0;

    // รับเวลาปัจจุบัน
    String timestamp = getTimeString();

    Serial.print("Volume: ");
    Serial.print(volume);
    Serial.println(" ml");

  uint8_t temp_farenheit = temprature_sens_read();
  float temp_celsius = ( temp_farenheit - 32 ) / 1.8;
  
  Serial.print("Internal Temperature (°C): ");
  Serial.println(temp_celsius);

    // ส่งข้อมูล MQTT พร้อม Timestamp
      snprintf(msg, MSG_BUFFER_SIZE, "{\"id\":\"%s\",\"volume\":%.2f,\"timestamp\":\"%s\",\"ip\":\"%s\",\"Gateway ip\":\"%s\",\"MCU\":%.2f}", 
      DISPENSOR_ID, volume, timestamp.c_str(), WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str(), temp_celsius);

    Serial.println(msg);
    client.publish("KMITL/water", msg);
    //ส่งข้อมูลไฟกระพริบ 50 ครั้ง 10 วินาที 10,000/50/2
    for (int i = 0; i < 50; i++) {
      digitalWrite(SEND_LED, LOW);
      delay(100);
      digitalWrite(SEND_LED, HIGH);
      delay(100);
    }
  }

    // ตรวจสอบว่าครบ 5 นาทีหรือยัง
    if (millis() - startMillis >= rebootInterval) {
    Serial.println("Rebooting MCU...");
    delay(100);  // หน่วงเล็กน้อยให้ข้อความส่งออกก่อน
    ESP.restart();  // สั่งให้รีบูต
  }
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *