//  Показометр давления с звуковой сигнализацией превышения заданного уровня на Ардуино Нано

// Должен работать с датчиками XGZP6899D  XGZP6847D   XGZP6857D  XGZP6859D  XGZP6869D  XGZP6877D  XGZP6887D  XGZP6858D  
// Проверен с датчиком XGZP6857D

// В теле скетча выбрать К в зависимости от верхнего предела датчика, тип зумера и значение давления для срабатывания сигнализации

// использована библиотека с поддержкой большого количества дисплеев, список: https://github.com/olikraus/u8glib/wiki/device
// Дисплей выбирать с SPI интерфейсом
// Проверен с дисплеем SSD1309, 128x64 1,54"

// Входы и выходы ардуино нано для подключения зумера и дисплея указаны в теле скетча
// Датчик давления подключен по протоколу I2C. SDA и SCL - пины ардуино А4 и А5, соответственно.

#include <U8g2lib.h>
#include <XGZP6897D.h>
/*
   K value for XGZP6897D. It depend on the pressure range of the sensor.
   Table found in the data sheet from CFSensor.com
    https://cfsensor.com/product-category/i2c-sensor/https://cfsensor.com/product-category/i2c-sensor/
  pressure_range (kPa)   K value
  131<P≤260               32
  65<P≤131                64
  32<P≤65                 128
  16<P≤32                 256
  8<P≤16                  512
  * 4<P≤8                   1024  выбран этот коэффициент для датчика -5 - +5 кPa
  2≤P≤4                   2048
  1≤P<2                   4096
  P<1                     8192
  the K value is selected according to the positive pressure value only,
  like -100～100kPa,the K value is 64.
*/

#define K 1024 // For pressure_range 5 кPa. See table above for the correct value for your sensor, according to the sensitivity.

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>+
#endif

#define SERIAL_ENABLED
#define PRESSED_BUTTON(B) (digitalRead(B)==0)

const int buzzerPin = 2; // Цифровой пин 2 для зуммера

// Пины для дисплея 9 > CS дисплей 8 > DC дисплей 7 > RES дисплей 6 > SDA дисплей 5 > SCL дисплей
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 6, /* cs=*/ 9, /* dc=*/ 8, /* reset=*/ 7);


void tft_out();

XGZP6897D mysensor(K); // create the sensor object, passing the correct K value.
float pressure, temperature;

void setup() {
  Serial.begin(9600);
  
  pinMode(buzzerPin, OUTPUT);
  
  u8g2.begin();
  u8g2.enableUTF8Print();    // enable UTF8 support for the Arduino print() function
//  u8g2.setFontDirection(0);
  
  if (!mysensor.begin())  // initialize and check the device
  {
    Serial.println("Device not responding.");
    while (true) delay(10);
  }
}

void loop()
{
  mysensor.readSensor(temperature, pressure); // read the temperature (in °Celsius), and the pressure (in Pa)
  pressure = pressure / 9.807;  // Преабразуем давление из Ра в мм.вод.ст.
  Serial.print(temperature); Serial.print(" C\t ");
  Serial.print(pressure); Serial.print(" мм.вод.ст");

                   // Для активного зумера. Если зумер пассивный закомментировать hfpltk ниже и убрать слэши в разделе "Для пассивного датчика"
  if (pressure >= 300) {
    digitalWrite(buzzerPin, HIGH); // Давление больше 300 мм.вод.ст. Захлеб колонны. Включаем зумер(подаем 5V на цифровой выход D2)
    delay(300);             // длительность сигнала 300 мс (0,3 секунды)
  }
    digitalWrite(buzzerPin, LOW);  // Выключаем (подаем 0V)

                 // Для пассивного зумера. 
  //if (pressure >= 300) 
  //  { 
  //    tone(buzzerPin, 1000); // Звук частотой 1000 Гц 
  //    delay(300);             // длительность сигнала 300 мс (0,3 секунды)
  //  // Останавливаем звук
  //  noTone(buzzerPin); 
  //  }

  tft_out();
  Serial.println();
  delay(1000); 
}

void tft_out () {    // Вывод давления и температуры на дисплей
   u8g2.clearBuffer();

  // --- СТРОКА 1: Давление ---
  int y1 = 28; // Базовая линия для первой строки
  
  // 1. Крупный шрифт цифры
  u8g2.setFont(u8g2_font_logisoso20_tr); 
  u8g2.setCursor(0, y1);
  u8g2.print(pressure,0); // Вывод давления целым числом

  // 2. Мелкий шрифр единица измерения (мм.вод.ст)
  
  u8g2.setFont(u8g2_font_unifont_t_cyrillic);
  int x_unit1 = u8g2.getStrWidth(String(pressure).c_str());
  u8g2.drawUTF8(x_unit1, y1, "мм.вод.ст"); 

  // --- СТРОКА 2: Температура ---
  int y2 = 60; // Базовая линия для  второй строки
  
  // 1. Крупный шрифт цифры второй строки
  u8g2.setFont(u8g2_font_logisoso20_tr); 
  u8g2.setCursor(0, y2);
  u8g2.print(temperature,1); // Вывод температуры с одним знаком после запятой

  // 2. Мелкий шрифр единица измерения
  int x_unit2 = u8g2.getStrWidth(String(temperature).c_str());
  u8g2.setFont(u8g2_font_9x15_tr);
  u8g2.drawStr(x_unit2, y2, "°C"); 

  u8g2.sendBuffer();
}
