// ====Ports==== #define pressure_port A0 #define relay_port 5 // ====Encoder==== #define S1 2 #define S2 3 #define KEY 4 // ====Display==== #define CLK 6 #define DIO 7 #if DEBUG #define DEBUG_MSG(x) Serial.println(x) #else #define DEBUG_MSG(x) #endif // ====Consts==== #define MIN_PRESSURE 60 #define MAX_PRESSURE 800 // ====Libs==== #include #include #include int pressure, pressure_low, pressure_high; bool is_on_pump, is_on_display, display_cur_pressure; unsigned long last_time1, last_time2, last_time3, last_time_pressure; const int NUM_READ = 3; EncButton eb(S1, S2, KEY); GyverTM1637 disp(CLK, DIO); // ограничивает нижний порог от 0 до верхнего порога int get_constrained_pressure_low(int pressure_low_local) { return constrain(pressure_low_local, MIN_PRESSURE, pressure_high-10); } // ограничивает верхний порог от нижнего порога до 800(8 атмосфер) int get_constrained_pressure_high(int pressure_high_local) { return constrain(pressure_high_local, pressure_low+10, MAX_PRESSURE); } // растянутое среднее арифметическое int midArifm2(int newVal) { static byte counter = 0; // счётчик static int prevResult = 0; // хранит предыдущее готовое значение static int sum = 0; // сумма sum += newVal; // суммируем новое значение counter++; // счётчик++ if (counter == NUM_READ) { // достигли кол-ва измерений prevResult = sum / NUM_READ; // считаем среднее sum = 0; // обнуляем сумму counter = 0; // сброс счётчика } return prevResult; } void setup() { #if DEBUG Serial.begin(9600); #endif DEBUG_MSG("pressure"); DEBUG_MSG(','); DEBUG_MSG("low"); DEBUG_MSG(','); DEBUG_MSG("high"); DEBUG_MSG(','); DEBUG_MSG("status"); pinMode(relay_port, OUTPUT); // загрузить пороги из памяти EEPROM.get(0, pressure_low); EEPROM.get(2, pressure_high); disp.clear(); disp.brightness(5); // яркость, 0 - 7 (минимум - максимум) disp.clear(); } void loop() { eb.tick(); if (eb.turn()) { disp.clear(); if (eb.right()) { pressure_low = get_constrained_pressure_low(pressure_low+10); disp.displayInt(pressure_low); disp.displayByte(0, _L); } if (eb.left()) { pressure_low = get_constrained_pressure_low(pressure_low-10); disp.displayInt(pressure_low); disp.displayByte(0, _L); } if (eb.rightH()) { pressure_high = get_constrained_pressure_high(pressure_high+10); disp.displayInt(pressure_high); disp.displayByte(0, _U); } if (eb.leftH()) { pressure_high = get_constrained_pressure_high(pressure_high-10); disp.displayInt(pressure_high); disp.displayByte(0, _U); } is_on_display = true; display_cur_pressure = false; last_time2 = millis(); } // нажать на энкодер - показать текущее давление if (eb.click()) { display_cur_pressure = true; is_on_display = true; last_time2 = millis(); } // Если энкодер зажат то записать текущие пороги в энергонезависимую память if (eb.hold()) { EEPROM.put(0, pressure_low); EEPROM.put(2, pressure_high); disp.displayByte(_S, _A, _U, _E); display_cur_pressure = false; last_time2 = millis(); } // Датчик давления 0 - 1000 0 - 10 атмосфер pressure = analogRead(pressure_port); pressure = midArifm2(pressure); if (millis() - last_time1 > 350) { last_time1 = millis(); if (display_cur_pressure & is_on_display) { disp.displayInt(pressure); } } if (millis() - last_time2 > 5000) { display_cur_pressure = true; last_time2 = millis(); } if (millis() - last_time3 > 30000) { display_cur_pressure = false; last_time3 = millis(); is_on_display = false; disp.clear(); } // измерение каждые 1500 мс if (millis() - last_time_pressure > 1500) { last_time_pressure = millis(); // Если текущее давление ниже нижнего порога - включить насос if (pressure < pressure_low) { if (!is_on_pump) { digitalWrite(relay_port, HIGH); is_on_pump = true; } } // Иначе если давление выше верхнего порога - выключить насос else if (pressure > pressure_high) { if (is_on_pump) { digitalWrite(relay_port, LOW); is_on_pump = false; } } } DEBUG_MSG(pressure); DEBUG_MSG(','); DEBUG_MSG(pressure_low); DEBUG_MSG(','); DEBUG_MSG(pressure_high); DEBUG_MSG(','); DEBUG_MSG(is_on_pump*100); }