#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
int analogPin = 0; // подключен к аналоговому выводу 0
unsigned long timer1 = millis();
float FlowANval = 0; // переменная для хранения считанного значения
int ExtraDiapason = 21; //= (FlowHigh - FlowLow)*DiapasonP[10] = (1023-204)*0.0256=21
//int FlowLow = 204 - ExtraDiapason; // 204 - 21 - Shift for Extra diapason
//Real fon = 201(U=10V) // fon = 182 (U=9,11V)
//08.10.2024 True Data
int FlowLow = 204 - ExtraDiapason; // 204 + 21 - Shift for Extra diapason
int FlowHigh = 1023 - ExtraDiapason; // 1023-21 (max+(FlowPoints[10]-FlowPointst[9]) - is a Extra diapason
int FlowCurrent = 0; //
int FlowStep = 100; //шаг сетки по горизонтали. 10 шагов от 0 до 1000 + 1 шаг экстра = 1100
boolean FlowOver = false; // переполнение и выход в экстра
boolean DispBlinc = false; //
//boolean XnAutoSend = false; //
//boolean XnINTEG = true; //
//boolean XnINTEG = false; //
//int XnINTEGindex = 0;
//float FlowPoints[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float FlowPoints[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //P0 -- P10, P11-ExtraDiapason
//float FlowPoints[12] = {183.00, 448.93, 583.90, 675.87, 759.82, 833.78, 882.75, 931.73, 960.72, 980.71, 1002.00, 1023.00}; //P0 -- P10, P11-ExtraDiapason
//08.10.2024 True Data At FlowLow = 225
//float FlowPoints[12] = {204.00, 463.11, 594.62, 684.24, 766.03, 838.09, 885.81, 933.53, 961.78, 981.25, 1002.00, 1023.00}; //P0 -- P10, P11-ExtraDiapason
//DiapasonP - процентное отношение между точками гафика по вертикали,
//по горизонтали линейно от 0 до 1000 с шагом 100
float DiapasonP[11] = {0, 0.3247, 0.1648, 0.1123, 0.1025 , 0.0903, 0.0598, 0.0598, 0.0354, 0.0244 , 0.0256};
unsigned long dddd1;
void setup() {
analogReference(DEFAULT);// INTERNAL =1.1V; DEFAULT =5V (3V3); EXTERNAL: вывод AREF (от 0 до 5В)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Serial.begin(9600);
display.clearDisplay();
//display.display();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(" HeXeM");
display.println(" Flow");
display.println(" Meter");
display.println(" v 1.01");
display.display();
delay(3000); //
RecountPoints();
//Read DiapasonP[i]. Start Adress = 22 (18 +4)
for (int i = 1; i < 11; i++) {
EEPROM.put(18 + i*4, DiapasonP[i]);
Serial.print("EEPROM save Flow Point ");
Serial.print(i);
Serial.print(" : ");
Serial.println(DiapasonP[i]);
}
//Read DiapasonP[i]. Start Adress = 22 (18 +4)
for (int i = 1; i < 11; i++) {
EEPROM.get(18 + i*4, DiapasonP[i]);
Serial.print("EEPROM read Flow Point ");
Serial.print(i);
Serial.print(" : ");
dddd1 = DiapasonP[i] * 10000;
Serial.println(dddd1);
}
}
void loop() {
//timer1 1s
if (millis() - timer1 >= 500) {
timer1 = millis(); //reset timer1
//timer2 = millis(); //reset timer2
RecountData();
UpdateDisplay();
}else if(millis() - timer1 >= 400) {
if (FlowOver) {
DispBlinc = true;
UpdateDisplay();
FlowOver = false;
DispBlinc = false;
/*
display.setTextSize(4);
display.setCursor(0, 0);
display.println("FFFFFFFF");
display.display();
*/
}
//timer1 = m
}
/*
// мигание при переполнении - гасим на 300 мс показания Flow
if (millis() - timer2 >= 1700) {
if (FlowOver) {
UpdateDisplay();
FlowOver = false;
}
//timer1 = millis(); //reset timer1
//RecountData();
}
*/
}
void UpdateDisplay() {
display.clearDisplay();
//display.display();
display.setTextSize(4);
display.setCursor(0, 0);
if (DispBlinc) {
display.println(" ");
} else {
display.println(int(FlowANval));
}
//display.println(int(FlowANval));
display.setTextSize(2);
display.setCursor(0, 32);
display.print("CURR: ");
display.println(FlowCurrent);
display.print("L");
display.print(FlowLow);
display.setCursor(64, 48);
display.print("H");
display.print(FlowHigh);
display.display();
}
void RecountPoints() {
int Diapason;
Diapason = FlowHigh - FlowLow;
Serial.println(Diapason);
FlowPoints[0] = FlowLow;
FlowPoints[10] = FlowHigh;
Serial.println(FlowPoints[0]);
for (int i = 1; i < 10; i++) {
FlowPoints[i] = Diapason * DiapasonP[i] + FlowPoints[i - 1];
Serial.println(FlowPoints[i]);
}
Serial.println(FlowPoints[10]);
FlowPoints[11] = FlowPoints[10] + ExtraDiapason;
Serial.println(FlowPoints[11]);
}
void RecountData() {
FlowCurrent = analogRead(analogPin);
FlowOver = false; // нет переполнения и выхода в экстра
if (FlowCurrent < FlowLow) {
FlowANval = 0;
FlowOver = true; // переполнение и выход в экстра
return;
}
if (FlowCurrent >= FlowPoints[0] && FlowCurrent <= FlowPoints[1]) {
FlowANval = map(FlowCurrent, FlowPoints[0], FlowPoints[1], 0, 100);
FlowOver = true; // переполнение и выход в экстра
return;
}
//for (int i = 1; i < 10; i++) {
for (int i = 1; i < 11; i++) {
if (FlowCurrent > FlowPoints[i] && FlowCurrent <= FlowPoints[i + 1]) {
FlowANval = map(FlowCurrent, FlowPoints[i], FlowPoints[i + 1], i * FlowStep, i * FlowStep + FlowStep);
//FlowANval = map(FlowCurrent, FlowPoints[i], FlowPoints[i + 1], i * 100, i * 100 + 100);
//Serial.println(FlowPoints[i]);
if (FlowCurrent > FlowPoints[10]) {
FlowOver = true; // переполнение и выход в экстра
}
return;
}
}
/*
if (FlowCurrent >= FlowPoints[10]) {
FlowANval = map(FlowCurrent,FlowPoints[10], FlowPoints[11], 900, 1000);
return;
}
*/
/*
if (FlowCurrent > FlowPoints[1] && FlowCurrent <= FlowPoints[2]) {
FlowANval = map(FlowCurrent,FlowPoints[1], FlowPoints[2], 100, 200);
return;
}
if (FlowCurrent > FlowPoints[2] && FlowCurrent <= FlowPoints[3]) {
FlowANval = map(FlowCurrent,FlowPoints[2], FlowPoints[3], 200, 300);
return;
}
*/
/*
// read the sensor:
XnCurrent = analogRead(analogPin);
XnANval = float(XnCurrent);
// apply the calibration to the sensor reading
XnANval = map(XnANval, XnLow, XnHigh, 0, 999);
// in case the sensor value is outside the range seen during calibration
char buffer[10]; // Выберите подходящий размер в зависимости от вашего числа
// Очищаем буфер
memset(buffer, 0, sizeof(buffer));
utoa(XnANval, buffer, 10);
// Intergation
if (XnINTEG == true) {
XnINTEGindex = XnINTEGindex + 1; //
if (XnINTEGindex == 10) {
XnINTEGindex = 0;
}
XnCurrentINTEG[XnINTEGindex] = XnCurrent;
XnANval = 0;
// Подсчет суммы элементов массива
for (int q = 0; q < 10; q++) {
XnANval += XnCurrentINTEG[q];
}
XnANval = XnANval / 10;
}
XnANval = XnANval / 10;
XnANval = constrain(XnANval, 0.0, 99.9);
*/
}