Управление температурой приточного воздуха

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

Привет всем очень требуется регулятор приточного воздуха в квартиру.
Суть такая, берем ардуино нано и подключаем датчик температуры, симисторный регулятор тенов, регулятор оборотов вентилятора, пид регулятор и защиты от перегрева и обрывов с звуковой сигнализацией и дисплеем.
Что есть :
мощность тенов 2 кВт на 220, куллеры 12 вольт, датчик резистивный с делителем .i2c дисплей, кнопки для управления режимами и температурой.
Я брал скетч от паяльной станции но без успехов ,не могу разобраться в коде.

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

В общем это схема принципиальная

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так, а что от нас нужно-то?

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

Помочь со скетчем) программирование сложно для меня.

или переделать этот 


/* Soldering Station HotAir Only */

#include <EEPROM.h>
#include <CyberLib.h>
#include <Wire.h>
#include <OLED_I2C.h>
#include <Bounce2.h>


//OLED дисплей
OLED  myOLED(SDA, SCL, 8); //Подключаем дисплей
extern uint8_t HAsmallNumbers[];
extern uint8_t HAbigNumbers[];
extern uint8_t SmallFont[];
extern uint8_t logoHA[];

//переменные и обозначения

/* mode selector */
#define modeHotAir 0
#define modeFanPWM 1

uint16_t HA_sleeptime = 10; //время до режима сна
boolean need_HA_countdown = false; //отсчёт до выключения фена
byte selectedMode = modeHotAir; //выбранный режим по умолчанию
uint16_t HAcountdown = 1; //счётчик таймера отключения фена
uint32_t prevDisplayMillis = 0; //время предыдущего обновления дисплея
uint32_t prevWorkMillis = 0; //время предыдущей проверки работы
uint32_t UPbuttonPressTime = 0; //время последнего нажатия кнопки плюс
uint32_t DWNbuttonPressTime = 0; //время последнего нажатия кнопки минус
uint32_t prevHAmillis = 0; //последнее время активности фена
uint16_t Graph_count = 0; //счётчик замера температуры
uint32_t HAONbuttonPressTime = 0; //время последнего нажатия кнопки включения фена

boolean need_log = false; //включение вывода лога

boolean UPbuttonState, DWNbuttonState, HAONbuttonState; //флаги нажатия кнопок
#define pinBuzzer 13 //пин пищалки
#define min_hotair_temp 50 //минимальная температура фена
#define max_hotair_temp 450 //максимальная температура фена
#define min_rpm 30 //минимальные обороты кулера
#define max_rpm 100 //максимальные обороты кулера
#define default_temp 250 //начальная температура фена
#define default_rpm 50 //начальная скорость вращения кулера

//установки для кнопок
#define sw_HA 2 //геркон фена
#define bt_HAON 10 //кнопка включения фена
#define bt_Sel 9 //кнопка выбора режима
#define bt_Up 8 //кнопка плюс
#define bt_Dwn 7 //кнопка минус

//защита от дребезга
Bounce swHotAir = Bounce();
Bounce swSolder = Bounce();
Bounce SolderOnButton = Bounce();
Bounce HotAirOnButton = Bounce();
Bounce SelButton = Bounce();
Bounce UpButton = Bounce();
Bounce DwnButton = Bounce();

//установки для фена
volatile uint16_t ots = 9990; //время цикла для StartTimer1
volatile boolean HotAirON = false; //флаг включения фена
volatile boolean HotAirProtect = false; //флаг защиты фена
uint16_t GetHotAirT = 0; //измеренная температура фена
uint16_t SetHotAirT = 100; //установленная температура фена
byte SetHotAirRPM = 100; //установленная скорость вращения кулера
uint16_t last_HotAirT; //последняя запомненая температура фена
byte last_RPM; //последняя запомненая скорость вращения кулера
boolean HAneedBeep = true; //флаг сигнала стабильности температуры
byte HAgood = 0; //счётчик стабилизации температуры фена
boolean needCool = true; //необходимость охлаждения фена
boolean HA_gerkon = false; //флаг геркона
#define pinFanPwm 6 //пин управления скоростью вращения кулера ШИМ
#define Kp 1.0 //0.5 пропорциональный коэффициент ПИ-регулятора
#define Ki 0.005 //0.008 интегральный коэффициент ПИ-регулятора
int integral = 0; //начальное значение интегральной поправки ПИ-регулятора
volatile float HAPower = 0.0; //мощность, на основании которой рассчитывается время задержки открытия симистора
boolean HA_PROT = false; //флаг защиты фена


//чтение последних установок из памяти
void MemRead() {
  SetHotAirT = EEPROM_int_read(4); //прочесть значение из адреса 4 (запомненное значение температуры фена, сразу 2 ячейки)
  if (SetHotAirT < min_hotair_temp || SetHotAirT > max_hotair_temp) { //если запомненное не в диапазоне максимума и минимума
    SetHotAirT = default_temp; //выставить значение по умолчанию
  }
  SetHotAirRPM = EEPROM_int_read(8); //прочесть значение из адреса 8 (запомненное значение оборотов кулера, сразу 2 ячейки)
  if (SetHotAirRPM < min_rpm || SetHotAirRPM > max_rpm) { //если запомненное не в диапазоне максимума и минимума
    SetHotAirRPM = default_rpm; //выставить значение по умолчанию
  }
}

//запись параметров фена в память

void MemHotAir() {
  if (last_HotAirT != SetHotAirT) {
    EEPROM_int_write(4, SetHotAirT);
    last_HotAirT = SetHotAirT;
  }
  if (last_RPM != SetHotAirRPM) {
    EEPROM_int_write(8, SetHotAirRPM);
    last_RPM = SetHotAirRPM;
  }
}

//ПИ-регулятор фена
void HA_PI() {
  int err = SetHotAirT - GetHotAirT; //вычисляем ошибку (разницу между установленной и реальной температурой) в данный момент времени
  float TempPower = ((Kp * err) + (Ki * integral)); //вычисляем значение с учётом выбранных коэффициентов и накопленной интегральной поправки ПИ-регулятора
  if (TempPower < 100.0 && TempPower > 0.0) integral += err; //если полученное значение в диапазоне от 0 до 100 - прибавляем к интегральной поправке значение ошибки
  HAPower = constrain(TempPower, 0.0, 100.0); //ограничиваем значение интервалом от 0 до 100 и присваиваем получившееся значение мощности для работы с симистором
  CalctImpulseControl(); //вычисляем задержку для симистора
}

//вычисление задержки для симистора
void CalctImpulseControl() {
  ots = (uint16_t)(acos(HAPower / 50.0 - 1.0 ) * 9900.0 / pi);
}

//вывод звукового сигнала
void Beep(uint16_t duration) { //название функции(длительность сигнала)
  D13_High;
  delay_ms(duration);
  D13_Low;
  /* for passive buzzer */
  //tone(pinBuzzer, 1000, duration);
}

//функция оверсэмплинга
uint16_t getOversampled(uint16_t ADC_value) {
  unsigned long int result = 0;
  for (byte z = 0; z < 64; z++) { //делаем 64 замера
    result +=  ADC_value; //складываем всё вместе
  }
  return result >> 6; //делаем побитовый сдвиг для полученного значения (64 это 2 в 6-ой степени, поэтому >>6)
}

void setup() {
  pinMode(3, INPUT_PULLUP); //пин отслеживания перехода через 0
  D4_Out; //пин защиты фена (реле)
  D4_Low; //выставить логический 0 - реле разомкнуто
  D5_Out; //пин нагревателя фена (выход на симистор)
  D5_Low; //выставить логический 0 - симистор закрыт
  D13_Out; //пин пищалки
  D13_Low; //выставить логический 0 - сигнала нет
  ButtonsSetup(); //инициализация кнопок

  if (need_log) { //если нужно выводить лог
    Serial.begin(115200); //открываем сериал-порт на 115200 бод
  }

  myOLED.begin(); // Инициализируем дисплей
  myOLED.invert(true);
  Splash(); //выводим лого-рисунок
  MemRead(); //читаем память
  delay_ms(2000); //ждём 2с
  myOLED.invert(false);
  initDisplay(); //выводим интерфейсные надписи на экран
  myOLED.update();
  attachInterrupt(1, ZC, FALLING); //включаем прерывание 1 на 3ем пине для отслеживания перехода через 0
}


void loop() {

  ScanButtons(); //работа с кнопками

  //выключение фена через 1 минуту простоя
  if (need_HA_countdown) { //если фен на подставке
    unsigned long currHAmillis = millis(); //запоминаем время1
    if (currHAmillis - prevHAmillis > 60000) { //если время1 - последнее время активности фена больше 1мин
      if (HAcountdown > 1) { //если отсчёт фена больше 1
        HAcountdown--; //отсчёт фена -1
        if (HAcountdown == 1) { //если отсчёт фена равен 1 - сигнал
          Beep(100);    //сигнал если осталась 1 минута
        }
      } else { //если досчитали до конца - выключаем полностью и подаём сигнал
        HAcountdown = 1; //отсчёт прошёл
        prevHAmillis = 0; //последнее время активности фена равно 0
        MemHotAir(); //запомнить установленную температуру фена в память
        need_HA_countdown = false; // отменяем необходимость отсчёта
        HotAirON = false; //выключаем флаг включенного фена
        Beep(200); //сигнал
      }
      prevHAmillis = currHAmillis; //запоминаем время1 как последнее время активности фена
    }
  }

  //обновление информации на LCD с интервалом 500мс
  uint32_t currDisplayMillis = millis(); //запоминаем время2
  if (currDisplayMillis - prevDisplayMillis > 500) { //если время2 - время последнего обновления дисплея больше 0,5с
    prevDisplayMillis = currDisplayMillis; //время последнего обновления дисплея присвоить время2
    DisplayUpdate(); //обновить дисплей

    //отправляем данные в сериал-порт
    if (need_log) { //если включен режим вывода лога
      if (HotAirON) { //если включен фен
        Graph_count++; //увеличить счётчик номера замера температуры
        Serial.print(Graph_count); //вывести в сериал-порт номер замера температуры
        Serial.print(";"); //разделитель ";"
      } else { //если фен выключен
        Graph_count = 0; //обнулить счётчик номера замера температуры
      }
      Serial.println(GetHotAirT); //вывести значение температуры
    }
  }

  //работа с интервалом 50мс (фен, кулер)
  uint32_t currWorkMillis = millis();
  if (currWorkMillis - prevWorkMillis > 50) {
    prevWorkMillis = currWorkMillis;
    WorkWithHotAir();
  }
}

//работа с феном
void WorkWithHotAir() {

  GetHotAirT = (0.543*(getOversampled(A0_Read)))+8.141; //считать значение с А0 с оверсэмплингом и вычислить температуру (индивидуально для каждой термопары!)

  if (HotAirON) { //если фен включен
    //переводим проценты оборотов кулера в ШИМ
    analogWrite(pinFanPwm, map(SetHotAirRPM, min_rpm, max_rpm, 80, 255)); //включить кулер на установленной скорости вращения

    //защита от перегрева или обрыва термопары
    if (GetHotAirT > SetHotAirT + 50 || GetHotAirT < 0) { //если температура фена больше установленной на 50 градусов или меньше 0 градусов
      HAProtection(); //выполнить функцию защиты фена
      return;
    }

    // Включаем реле
    D4_High;

    //ПИ-регулятор фена
    HA_PI();

    if (HAneedBeep) { //если температура стабилизировалась - сигнал
      int delta = GetHotAirT - SetHotAirT; //разница установленной и измеренной температур
      if (delta > -5 && delta < 5) { //если разница в пределах 3 градусов
        HAgood++; //счётчик стабилизации +1
        if (HAgood == 20) { //если за 20 измерений температура стабильна - пищим 2 раза
          Beep(50);
          delay_ms(200);
          Beep(50);
          HAgood = 0; //сбрасываем счётчик стабилизации
          HAneedBeep = false; //отменяем необходимость сигнала
        }
      } else { //если разница больше чем 3 градуса
        HAgood = 0; //температура нестабильна
        HAneedBeep = true; //включаем сигнал о стабилизации
      }
    }
  } else { //если фен выключен
    HotAirOff(); //функция выключения фена
    if (GetHotAirT >= 50 && needCool) { //если температура фена больше 50 градусов и флаг необходимости охлаждения включен
      analogWrite(pinFanPwm, 255); //включаем кулер на полные обороты
    } else { //если температура ниже 50 градусов и охлаждение не нужно - проверяем защиту фена от перегрева
      if (!HotAirProtect) { //если защита от перегрева выключена
        analogWrite(pinFanPwm, 0); //выключаем кулер
        needCool = false; //отменяем необходимость охлаждения
      }
    }
    need_HA_countdown = false; //отключаем отсчёт до выключения
    HAcountdown = 1; //таймер выключения на 1 минуту
  }
}

void HAProtection() { //функция защиты фена
  analogWrite(pinFanPwm, 255); //кулер на полную
  HotAirProtect = true; //защита от перегрева включена
  HA_PROT = true; //защита включена
  HotAirON = false; //фен выключен
  HotAirOff(); //выполнить выключение фена
}

/*********************************** Вспомогательные функции *************************************/

//чтение int значения из памяти (двухбайтовое значение хранится в двух ячейках)
int EEPROM_int_read(int addr) {
  byte raw[2];
  for (byte i = 0; i < 2; i++) {
    raw[i] = EEPROM.read(addr + i);
  }
  int &num = (int&)raw;
  return num;
}

//запись int значения в память (двухбайтовое значение хранится в двух ячейках)
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for (byte i = 0; i < 2; i++) {
    EEPROM.write(addr + i, raw[i]);
  }
}

//сброс таймера отключения фена
void ResetHAcountdown() {
  HAcountdown = HA_sleeptime;
}

//включение таймера отключения фена
void ActivateHAcountdown() {
  need_HA_countdown = true;
  HAcountdown = HA_sleeptime;
}

//полное выключение фена
void HotAirOff() {
  D5_Low; //выключение нагревателя
  delay_ms(30);
  D4_Low; //выключение реле защиты
  if (HotAirProtect && HA_PROT) { //если включена защита фена - сигнал
    HA_PROT = false;
    Beep(1000);
    MemHotAir();
  } //запомнить значение установленной температуры фена
}

//отслеживание перехода через 0
void ZC() {
  StartTimer1(HeaterOn, ots);
  RestartTimer1();
}

//открытие симистора
void HeaterOn() {
  if (HotAirON) {
    if (HAPower > 0.0) {
      D5_High;
      delay_us(100);
    }
    D5_Low;
  }
  StopTimer1();
}

//работа с кнопками
void ScanButtons() {

  if (swHotAir.update() && HotAirON) { //если изменилось состояние геркона и фен включен
    ResetHAcountdown(); //сбросить таймер отключения
    Beep(50); //сигнал
  }

  //кнопка включения фена
  if (HotAirOnButton.update()) { //обновляет объект и возвращает TRUE (1), если состояние пина изменилось (кнопка была нажата или же, наоборот, отпущена) и FALSE (0) в противном случае
    if (HotAirOnButton.read()) { //возвращает обновленное состояние пина (false или true)
      HAONbuttonState = false;
    } else {
      if (!HotAirON) { //если фен выключен
        HotAirON = true; //включить фен
        HotAirProtect = false; //выключить режим защиты от перегрева
        prevHAmillis = millis(); //запомнить время последнего обращения к фену
        ActivateHAcountdown(); //активировать отсчёт до отключения
        Graph_count = 0; //обнулить счётчик номера замера температуры
        integral = 0; //сбросить накопленное значение интегральной поправки ПИ-регулятора
        selectedMode = modeHotAir; //выбранный режим - 0, фен
        HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
        needCool = true; //включить необходимость охлаждения
      } else { //если фен включен
        ResetHAcountdown(); //сбросить таймер отключения
      }
      HAONbuttonState = true;
      HAONbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки включения фена
      Beep(50); //сигнал
    }
  }

  if  (HAONbuttonState) { //долгое нажатие на кнопку включения фена (больше 1000мс)
    if ( millis() - HAONbuttonPressTime >= 1000 ) {
      HAONbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки
      if (HotAirON) { //если фен включен
        HotAirON = false; //выключить фен
        MemHotAir(); //запомнить выставленную температуру
        Beep(200); //долгий сигнал
      }
    }
  }

  //кнопка выбора режима
  SelButton.update();
  if (SelButton.fell()) { //возвращает true, если кнопка перешла из 1 в 0
    Beep(50);
    (selectedMode < modeFanPWM) ? (selectedMode++) : (selectedMode = modeHotAir); //тернарная условная операция, (logic ? val1 : val2), если logic=true выполняем val1, иначе val2
  }

  //кнопка плюс
  if (UpButton.update()) { //если кнопка изменила состояние
    if (UpButton.read()) { //если кнопка отпущена
      UPbuttonState = false; //отключить обработку долгого нажатия
    } else {
      switch (selectedMode) {
        case modeHotAir: //если выбран режим фена - добавить температуру на 5 градусов
          if (SetHotAirT < max_hotair_temp) {
            SetHotAirT += 5;
          }
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
        case modeFanPWM: //если выбран режим кулера - добавить обороты на 5 процентов
          if (SetHotAirRPM < max_rpm) {
            SetHotAirRPM += 5;
          }
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
      }

      UPbuttonState = true; //включить обработку долгого нажатия
      UPbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки
      Beep(50); //сигнал
    }
  }

  if  (UPbuttonState) {
    if ( millis() - UPbuttonPressTime >= 300 ) { //если долгое нажатие (дольше 300мс)
      UPbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки
      switch (selectedMode) {
        case modeHotAir: //если выбран режим фена - добавить температуру на 10 градусов
          SetHotAirT += 10;
          if (SetHotAirT > max_hotair_temp) SetHotAirT = max_hotair_temp;
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
        case modeFanPWM: //если выбран режим кулера - добавить обороты на 10 процентов
          SetHotAirRPM += 10;
          if (SetHotAirRPM > max_rpm) SetHotAirRPM = max_rpm;
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
      }
    }
  }

  //кнопка минус
  if (DwnButton.update()) { //если кнопка изменила состояние
    if (DwnButton.read()) { //если кнопка отпущена
      DWNbuttonState = false; //отключить обработку долгого нажатия
    } else {
      switch (selectedMode) {
        case modeHotAir: //если выбран режим фена - убавить температуру на 5 градусов
          if (SetHotAirT > min_hotair_temp) {
            SetHotAirT -= 5;
          }
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
        case modeFanPWM: //если выбран режим кулера - убавить обороты на 5 процентов
          if (SetHotAirRPM > min_rpm) {
            SetHotAirRPM -= 5;
          }
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
      }
      DWNbuttonState = true; //включить обработку долгого нажатия
      DWNbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки
      Beep(50); //сигнал
    }
  }

  if  (DWNbuttonState) { //если долгое нажатие (дольше 300мс)
    if ( millis() - DWNbuttonPressTime >= 300 ) {
      DWNbuttonPressTime = millis(); //запомнить время последнего нажатия кнопки
      switch (selectedMode) {
        case modeHotAir: //если выбран режим фена - убавить температуру на 10 градусов
          SetHotAirT -= 10;
          if (SetHotAirT < min_hotair_temp) SetHotAirT = min_hotair_temp;
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
        case modeFanPWM: //если выбран режим кулера - убавить обороты на 10 процентов
          SetHotAirRPM -= 10;
          if (SetHotAirRPM < min_rpm) SetHotAirRPM = min_rpm;
          HAneedBeep = true; //включить сигнал напоминания "1 минута до отключения"
          ResetHAcountdown(); //сбросить таймер отключения
          break;
      }
    }
  }
}

//вывод логотипа
void Splash() {
  myOLED.clrScr();
  myOLED.drawBitmap(0, 0, logoHA, 128, 64);
  myOLED.update();
  //если нужно построить диаграмму выхода на заданную температуру
  if (need_log) {
    myOLED.setFont(SmallFont);
    myOLED.print("*", 4, 4);
  }
}

//инициализация кнопок
void ButtonsSetup() {
  pinMode(sw_HA, INPUT_PULLUP); //пин геркона
  swHotAir.attach(sw_HA); //устанавливает пин, к которому подключен геркон и включает подтягивающий резистор

  pinMode(bt_HAON, INPUT_PULLUP);
  HotAirOnButton.attach(bt_HAON); //устанавливает пин, к которому подключена кнопка и включает подтягивающий резистор
  HotAirOnButton.interval(5); //время задержки для антидребезга в мс

  pinMode(bt_Sel, INPUT_PULLUP); //по аналогии с кнопкой включения фена
  SelButton.attach(bt_Sel);
  SelButton.interval(5);

  pinMode(bt_Up, INPUT_PULLUP); //по аналогии с кнопкой включения фена
  UpButton.attach(bt_Up);
  UpButton.interval(5);

  pinMode(bt_Dwn, INPUT_PULLUP); //по аналогии с кнопкой включения фена
  DwnButton.attach(bt_Dwn);
  DwnButton.interval(5);
}

//выводим интерфейсные надписи на экран
void initDisplay() {
  myOLED.clrScr();
  myOLED.setFont(HAbigNumbers);
  myOLED.print("---", 1, 0);
  myOLED.drawLine(2, 41, 82, 41); //вертикальная линия
  myOLED.drawLine(82, 2, 82, 61); //горизонтальная линия
  myOLED.print(".", 60, 0); //degrees
  myOLED.setFont(SmallFont);
  myOLED.print("COOLER", 86, 3);
  myOLED.print("TEMP", 86, 35);
  myOLED.print("TO", 2, 53);
  myOLED.print("SLEEP:", 17, 53);
}

//обновление дисплея
void DisplayUpdate() {

  initDisplay();

  if (HotAirProtect) { //если сработала защита фена от перегрева
    for (int i = 2; i < 79; i++) {
      for (int j = 42; j < 62; j++) {
        myOLED.clrPixel(i, j); //очищаем остатки надписи "TO SLEEP"
      }
    }
    myOLED.setFont(SmallFont);
    myOLED.print("! OVERHEAT !", 5, 49); //вывести предупреждение
    myOLED.drawRect(5, 45, 77, 59);
    for (int i = 6; i < 77; i++) {
      for (int j = 46; j < 59; j++) { //инвертирование прямоугольника сигнализации перегрева
        myOLED.invPixel(i, j);
      }
    }
  } else if (HotAirON) { //если фен включен и защита от перегрева не сработала
    myOLED.setFont(HAsmallNumbers);
    if (HAcountdown < 10) {
      myOLED.print("0", 55, 45); //вывести значение счётчика до отключения фена
      myOLED.printNumI(HAcountdown, 67, 45);
    }
    else {
      myOLED.printNumI(HAcountdown, 55, 45); //вывести значение счётчика до отключения фена
    }
  }

  myOLED.setFont(HAsmallNumbers);
  myOLED.printNumI(SetHotAirT, 87, 45); //вывести значение установленной температуры фена

  if (GetHotAirT > 505 && !HotAirON) { //если измеренная температура фена больше 505 градусов или фен выключен
    myOLED.setFont(HAbigNumbers);
    myOLED.print("---", 1, 0); //вывести прочерк
  }
  else {
    myOLED.setFont(HAbigNumbers);
    if (GetHotAirT < 100) {
      myOLED.print("0", 1, 0);
      myOLED.printNumI(GetHotAirT, 21, 0);
    }
    else {
      myOLED.printNumI(GetHotAirT, 1, 0); //вывести значение измеренной температуры фена
    }
  }

  if (needCool && !HotAirON && GetHotAirT > 50) { //если необходимо охлаждение, фен выключен и измеренная температура фена больше 50 градусов
    myOLED.setFont(HAsmallNumbers);
    myOLED.print("-./", 87, 13); //вывести значение оборотов кулера MAX
  }
  else if (SetHotAirRPM == 100) { //если обороты кулера на максимуме - пишем MAX
    myOLED.setFont(HAsmallNumbers);
    myOLED.print("-./", 87, 13); //вывести значение оборотов кулера MAX
  }
  else { //иначе
    myOLED.setFont(HAsmallNumbers);
    myOLED.printNumI(SetHotAirRPM, 87, 13); //вывести значение выставленных оборотов кулера
    myOLED.print(":", 111, 13); //вывести знак %
  }

  if (selectedMode == 0) {
    myOLED.drawRoundRect(82, 32, 127, 62); //нарисовать рамку вокруг установленной температуры
  }
  else {
    myOLED.drawRoundRect(82, 0, 127, 30); //нарисовать рамку вокруг выставленных оборотов кулера
  }

  myOLED.update();
}

 

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

тот код где то на форуме взял, не помню где. у него бы убрать геркон переделать температуры 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

спрашивай у автора.  При чём здесь мы?

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

Пост от 17 го года, автору уже пофиг

inspiritus
Offline
Зарегистрирован: 17.12.2012

Тыгыды исчи исполнителя за чатлы

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

И сколько такая радость стоить будет?

b707
Онлайн
Зарегистрирован: 26.05.2017

Илья Смольников пишет:

И сколько такая радость стоить будет?

Этот вопросец надо разместить в отделе "Ищу исполнителя" - там и цену скажут.

Но навскидку, с учетом ТЭНов, вентилятора, управления ПИД и тд и тп - мне бы это было интересно обсуждать начиная с 6-8 тыр

Илья Смольников
Offline
Зарегистрирован: 12.08.2020

эээммм ,мне тогда проще купить готовый вариант

b707
Онлайн
Зарегистрирован: 26.05.2017

Илья Смольников пишет:

эээммм ,мне тогда проще купить готовый вариант

абсолютно верно, рекомендую так и поступить.

Серийное всегда дешевле заказного.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Поработал немного ассенизатором - вычистил срач. Прошу больше дерьма не лить.

Краткое резюме для ТС:

1. Помогают тем, кто делает сам! Тем, кто сам не делает помочь невозможно - можно только сделать за них.
2. Хотите делать самостоятельно - делайте, на конкретные вопросы Вам ответят и помогут.
3. Не хотите (или не можете) делать самостоятельно - заказывайте в коммерческом разделе форума, сделают за Вас.
4. Не хотите ни делать, ни заказывать - идите нафиг.

Всё. Срача здесь больше не будет.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

ЕвгенийП пишет:

Краткое резюме для ТС:

1. Помогают тем, кто делает сам! Тем, кто сам не делает помочь невозможно - можно только сделать за них.
2. Хотите делать самостоятельно - делайте, на конкретные вопросы Вам ответят и помогут.
3. Не хотите (или не можете) делать самостоятельно - заказывайте в коммерческом разделе форума, сделают за Вас.
4. Не хотите ни делать, ни заказывать - идите нафиг.

Всё. Срача здесь больше не будет.

Идеально! Вот так бы всегда...