Контроллер паяльного фена

edcop
Offline
Зарегистрирован: 23.07.2016

Когда-то у меня была похожая проблема из-за смены условного анода с условным катодом симистора. Поменяйте местами, а управляющий электрод трогать не нужно. Вдруг поможет.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

edcop пишет:

Когда-то у меня была похожая проблема из-за смены условного анода с условным катодом симистора. Поменяйте местами, а управляющий электрод трогать не нужно. Вдруг поможет.

цепь симистора отдельно работает отлично, поначалу тоже перепутал А1 и А2 - не работало, в нынешней схеме подключил правильно)

блин, на выходе с оптрона -0,74в... откуда - хз, собирал на макетке и всё работало...куда плясать? всё выпаивать и проверять?

edcop
Offline
Зарегистрирован: 23.07.2016

Ну если на макетке всё работало, то конечно остаётся прозвонка всех компонентов. Пройтись паяльником по всем контактам и очень внимательно просмотреть замыкания, собственно их можно определить при прозвонке. "Электроника - наука о контактах!!!"

Питание на макетке и в готовом изделии не менялось? Пройтись тестером по цепи питания одно из первых дел.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

edcop пишет:

Ну если на макетке всё работало, то конечно остаётся прозвонка всех компонентов. Пройтись паяльником по всем контактам и очень внимательно просмотреть замыкания, собственно их можно определить при прозвонке. "Электроника - наука о контактах!!!"

Питание на макетке и в готовом изделии не менялось? Пройтись тестером по цепи питания одно из первых дел.

питание - 220в, розетка вроде та же... 5в блок тот же... единственное что поменял - резисторы на 220к, ну не из-за них же?

Umkalab
Offline
Зарегистрирован: 09.01.2017

http://cf.mf-image.ru/d/eyJ0IjoiMjAxNy0wMi0xNVQwODozNzo1OS4zNzUwNTk2WiIs...

Для проверки Zero-Cross модуля, допилите схему белыми компонентами. Резистор и светодиод. При првильной работе модуля светодиод будет мерцать с частотой 100Гц.

Желтым выделено то, что по моему мнению не должно быть в схеме. Там нет электролита на 1мкф, там стоит керамика. И 0,1/250  это не тот совсем конденсатор. На контактах этого конденсатора напряжение не составляет и 5 вольт. Переменки правда, но всё же.

 

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

Umkalab пишет:

http://cf.mf-image.ru/d/eyJ0IjoiMjAxNy0wMi0xNVQwODozNzo1OS4zNzUwNTk2WiIs...

Для проверки Zero-Cross модуля, допилите схему белыми компонентами. Резистор и светодиод. При првильной работе модуля светодиод будет мерцать с частотой 100Гц.

Желтым выделено то, что по моему мнению не должно быть в схеме. Там нет электролита на 1мкф, там стоит керамика. И 0,1/250  это не тот совсем конденсатор. На контактах этого конденсатора напряжение не составляет и 5 вольт. Переменки правда, но всё же.

 

Электролит на 10, поставил как на схеме Олега. 0,1/250 это Х-кондёр, вроде надо такой ставить, если не такой, то какой? как в снабберной цепи симистора? Я тут измерил сопротивление резисторов, с которыми у меня работало - написано 220к, по факту 145к, попробую их воткнуть, может заработает.

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

to OlegK

> когда у меня в ОПС стояла LM358, то было сразу заметно, что отображаемая температура "уплывала",

поподробнее можно?
разве процесс не должен был "стабилизироваться" в любом случае? (так сказать в первом приближении), ну т.е. поплыло значение с датчика (читай как с ОУ) - туда же плывет и "управление", т.е. компенсирует "ошибку"

поясню доп. так
использую обычный ЛМ358 - и не могу "выловить" тот отрицательный момент, который вносит "его якобы нестабильность"... т.е. не вижу этой нестабильность визуально, поэтому и хочу уточнить, ЧТО, ГДЕ, КОГДА и на что обратить внимание, что бы УВИДЕТЬ эту нестабильность

(я понимаю, что тема "отдельный фен" а я про "паяльную станцию", но, надеюсь, понятно обьяснил)

спасибо

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

sunjob пишет:
поподробнее можно?

Если на пальцах, то после калибровки у нас настроен некий режим ОУ (смещение, усиление). Процесс калибровки не быстрый и ОУ с температуры окр. среды прогревается, т.к. на него подано питание. К примеру, я настроил комнатную темп. 20 град. На след. день включаю - на холодной ПС у меня показания уплыли в меньшую сторону и показывается, допустим, 18 град. при той же комнатной. Если ПС постоит включённой, то показания возвращаются обратно к настроенным ранее, т.е. к 20. Если внутри корпуса температура повысится, то показания чуток уплывут вверх. Немного, но всё же.
С прецизионным ОУ такого не происходит, т.к. тот же AD8551 имеет дрейф смещения 0.005 мкв/С против 20 мкв/С у 358-й.
Ну и я выше уже писал, что не стОит заморачиваться, это чисто мои придирки, т.к. по роду работы имею дело с измерениями.

Цитата:
ну т.е. поплыло значение с датчика (читай как с ОУ) - туда же плывет и "управление", т.е. компенсирует "ошибку"
Примем входное значение температуры за 300 град. при холодном ОУ.  При прогреве, при такой же температуре он "выдаст" к примеру 305. Регулирование "увидит", что нужно понизить температуру и по факту будет держать 295, а с ОУ будет "читаться " 300.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

OlegK, разобрался я вроде с детектором нуля, кажется работает. Но симистор так и не открывается, грешу на код - выложу всю портянку, может удалил что важное когда правил - можете глянуть пожалуйста, всё-таки исходники Ваши:


/* 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 MediumNumbers[];
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; //установленная скорость вращения кулера
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 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(); //выводим интерфейсные надписи на экран
  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 = getOversampled(A0_Read); //считать значение с А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 > -3 && delta < 3) { //если разница в пределах 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() {

}

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

  myOLED.clrScr();
  myOLED.setFont(MediumNumbers);
  myOLED.printNumI(SetHotAirT, LEFT, 2);
  myOLED.printNumI(GetHotAirT, LEFT, 20);
  myOLED.printNumI(selectedMode, LEFT, 38);
  myOLED.printNumI(SetHotAirRPM, RIGHT, 2);
  myOLED.printNumI(A0_Read, RIGHT, 20);
  myOLED.printNumI(getOversampled(A0_Read), RIGHT, 38);
  myOLED.update();

  /*lcd.setCursor(6, 2);
    //lcd.print(bspace);
    lcd.setCursor(7, 2);
    if (HotAirProtect) { //если сработала защита фена от перегрева
      lcd.print("[!]"); //вывести знак предупреждения
    } else if (HotAirON) { //если фен включен и защита от перегрева не сработала
      lcd.print(HAcountdown); //вывести значение счётчика до отключения фена
    }

    lcd.setCursor(11, 2);
    //lcd.print(bspace);
    lcd.setCursor(11, 2);
    lcd.print(SetHotAirT); //вывести значение установленной температуры фена
    lcd.write((byte)0); //вывести знак градуса

    lcd.setCursor(16, 2);
    //lcd.print(bspace);
    lcd.setCursor(16, 2);

    if (GetHotAirT > 505 && !HotAirON) { //если измеренная температура фена больше 505 градусов или фен выключен
      lcd.print("---"); //вывести прочерк
    } else {
      lcd.print(GetHotAirT); //вывести значение измеренной температуры фена
    }
    lcd.write((byte)0); //вывести знак градуса

    lcd.setCursor(11, 3);
    //lcd.print(bspace);
    lcd.setCursor(11, 3);
    if (needCool && !HotAirON && GetHotAirT > 50) { //если необходимо охлаждение, фен выключен и измеренная температура фена больше 50 градусов
      lcd.print("100%"); //вывести значение оборотов кулера 100%
    } else { //иначе
      lcd.print(SetHotAirRPM); //вывести значение выставленных оборотов кулера
      lcd.print("%"); //вывести знак %
    }

    for (byte z = 1; z < 4; z++) { //для всех 4 строчек (очистка указателя выбранного режима)
      lcd.setCursor(10, z); //перейти на 11 символ, z строку
      lcd.print(" "); //вывести пробел
    }

    lcd.setCursor(10, selectedMode); //перейти на 11 символ, строку с выбранным режимом (фен - 1 строка, кулер - 2)
    lcd.print(">"); //вывести знак указателя*/
}

//чтение последних установок из памяти
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() {
  EEPROM_int_write(4, SetHotAirT); //записываем значение температуры фена по адресу 4
  EEPROM_int_write(8, SetHotAirRPM); //записываем значение оборотов кулера по адресу 8
}

//ПИ-регулятор фена
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)
}

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

MkTwo пишет:
Но симистор так и не открывается, грешу на код - выложу всю портянку

Первым делом поправьте у себя мой старый косяк - в процедуре HotAirOff() нужно  MemHotAir(); перенести чуть выше, под скобку, где Beep(1000); Остальное гляну позже.

ЗЫ. Глянул, вроде в плане управления симистором всё нормально. Можно залить тестовый скетч, вместо фена подключить лампу накаливания и посмотреть в сериал порт, что выводится. Скетч ниже раз в секунду наращивает мощность по 5% в течении 10 секунд, после чего отключает симистор и реле.
Если сообщения "ZC" не будут выводиться, значит узел контроля 0 не работает. Если выводятся, но лампа так и не горит, значит смотреть цепи симистора. И проверить, соответствуют ли пины в коде тому, что на них подключено физически.

Тестовый скетч

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

OLED  myOLED(SDA, SCL, 8);
extern uint8_t MediumNumbers[];

volatile uint16_t ots = 9990;
volatile float Power = 0.0; 
byte count = 0;

void setup() {
  Serial.begin(115200);
  pinMode(3, INPUT_PULLUP);
  D4_Out;
  //D4_Low;
  D5_Out; 
  D5_Low; 
  myOLED.begin();
  attachInterrupt(1, ZC, FALLING);
  delay_ms(1000);
  D4_High;
}
void loop() {
  static uint32_t prevMillis;
  if (millis() - prevMillis > 1000 && count < 10) { 
    prevMillis = millis();
	count++;
	myOLED.clrScr();
        myOLED.setFont(MediumNumbers);
        myOLED.printNumI(Power, LEFT, 20);
        myOLED.update();
	Power += 5.0;
	CalcImp();
	Serial.print("Power "); 
	Serial.println(Power); 
  } 
  if (count == 10) {
	  Power = 0.0;
	  CalcImp();
	  delay_ms(10);
	  D5_Low;
          delay_ms(10);
          D4_Low;
	  Serial.print("----------); 
	  Serial.println("Finished");
  }
}  
void ZC() {
  Serial.println("ZC");
  StartTimer1(TriacOn, ots);
  RestartTimer1();
}
void TriacOn() {
    if (Power > 0.0) {
      D5_High;
      delay_us(100);
    }
    D5_Low;
  StopTimer1();
}
void CalcImp() {
  ots = (uint16_t)(acos(Power / 50.0 - 1.0 ) * 9900.0 / pi);
}
sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

ОУ, дрейф смещения

олег, я об этом и имел в виду, ну т.е. все правильно! (меня поставило в тупик отсутствие понятия "дрейфа смещения" в вашей фразе, на которую я обратил внимание ... :о)

спасибо

зы

наверное, было бы правильнее написать что "уплывала не отображаемая" - а "конечная/целевая/устанавливаемая/выходная" температура, тогда бы сразу "непонятливым" было бы понятно, что имелся в виду "дрейф" :о)

 

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

OlegK пишет:

В общем получил вот это: 



=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2017.02.20 10:22:45 =~=~=~=~=~=~=~=~=~=~=~=
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 5.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 10.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 15.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 20.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 25.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 30.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 35.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
PZC
ower 40.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 45.00
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
ZC
Power 50.00
ZC
ZC
----------Finished

Но лампа не горит (и врут календари)... Загрузил обычный блинк - лампа работает в нормальном режиме, вообще не понимаю что к чему...

void setup() {
  pinMode(5, OUTPUT); //реле
  pinMode(4, OUTPUT); //симистор
  digitalWrite(4, HIGH);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(5, HIGH);  
  delay(1000);           
  digitalWrite(5, LOW); 
  delay(1000);       
}

Не может быть такого, что ZC срабатывает слишком часто и симистор не успевает открываться? Загружал вот такой скетч с целью узнать частоту импульсов прерывания, получалось 109 Гц, хотя не знаю правильно ли я делал вообще:

int count = 0;
unsigned long tm = 0;
int freq;

void setup()
{
  pinMode(3, INPUT);
  Serial.begin(9600);
  Serial.println("Ready");
  attachInterrupt(1, zero_cross, FALLING);
}

void zero_cross()
{
  tm = millis();
  count++;
  
}

void loop()
{
  Serial.print("zc ");
    Serial.print(count);
    Serial.print(":");
    Serial.print(tm);
    Serial.print(":");
    Serial.print(count/(tm/1000));
    Serial.println(" ");
}

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

MkTwo пишет:
В общем получил вот это:

Ну нормально. Нужно было ещё в TriacOn() запихать вывод в порт, что бы убедиться, срабатывает ли таймер, который и открывает симистор.

Цитата:
ZC срабатывает слишком часто и симистор не успевает открываться?

Не может. ZC срабатывает с частотой 100 Гц и у всех успевает, а тут вдруг не хочет.

А какой оптрон на симистор воткнут?

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

MOC3041 воткнул, я там ещё с ногами промахнулся - вход подключил на 1 и 3 ноги вместо 1 и 2, но потом от 3 до второй перемычку кинул, 3 обозначается NC - это ничего страшного, надеюсь?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

MkTwo пишет:
MOC3041

Ну, теперь ясно, почему не работает. Этот оптрон с узлом контроля 0. Нужно поменять на "без". К примеру, на MOC3021.

Цитата:
NC - это ничего страшного, надеюсь?

NC = not connected, т.е. просто вывод, никуда не подключённый.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

вот и смотри после этого инфу о компонентах на ЧипиДипе... Там ZC написано только в названии общего даташита где-то внизу страницы... Чуть позже выпаяю МОС3021 из макетки, проверю, но точно знаю что с ним работало у меня, теперь-то я вспомнил) отпишусь обязательно

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

MkTwo пишет:
вот и смотри после этого инфу о компонентах на ЧипиДипе...

Поэтому лучше смотреть даташиты от производителя ))

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

на счет "ничего страшного"

> NC - это ничего страшного, надеюсь?
>
> NC = not connected, т.е. просто вывод, никуда не подключённый.

я бы обозвал эти пины NFC (not fucking connected)

есть куча прецендентов у MOC, что этот самый NC садили на землю или на питание - и палили схему, либо, как минимум, "делали неработоспособной"

ну, т.е. обратите на это внимание, возможно вы обладатель "счастливого экземпляра" MOC

ну и естественно
> Нужно поменять на "без"

все имхо (удачки)

p.s.
а тут на форуме есть возможность вставлять сполер?

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

sunjob пишет:
на счет "ничего страшного" > NC - это ничего страшного, надеюсь? > > NC = not connected, т.е. просто вывод, никуда не подключённый. я бы обозвал эти пины NFC (not fucking connected) есть куча прецендентов у MOC, что этот самый NC садили на землю или на питание - и палили схему, либо, как минимум, "делали неработоспособной" ну, т.е. обратите на это внимание, возможно вы обладатель "счастливого экземпляра" MOC ну и естественно > Нужно поменять на "без" все имхо (удачки) p.s. а тут на форуме есть возможность вставлять сполер?

сейчас займусь - отпаяю NC и другой оптрон поставлю

по поводу спойлеров: http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

пункт "свернуть" на второй вкладке

получится как-то так

 

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

OlegK пишет:

MkTwo пишет:
вот и смотри после этого инфу о компонентах на ЧипиДипе...

Поэтому лучше смотреть даташиты от производителя ))

это точно) в общем всё у меня заработало, ещё раз спасибо! теперь осталось:

1) родить оформление дисплея

2) запилить всё в корпус

3) откалибровать температуру

Sergant
Offline
Зарегистрирован: 24.03.2016

MkTwo пишет:

1) родить оформление дисплея

Просьба "рожать" так, чтобы можно было позже скопировать "раздел скетча" под наш общий дисплей OLED :) заранее спасибо

Почти все заказал жду, обнаружил деражатель для фена по разумной цене, но на днях появилась ПЛАТНАЯ доставка :(  Себе же заказал комплект фен с держателем (для прошлой конструкции покупал фен намного дороже да еще и без держателя)

Umkalab
Offline
Зарегистрирован: 09.01.2017

Ха, смешные вы люди... Мои грабли про MOC в теме ОПС вам ничего не напоминают???

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

Sergant пишет:

MkTwo пишет:

1) родить оформление дисплея

Просьба "рожать" так, чтобы можно было позже скопировать "раздел скетча" под наш общий дисплей OLED :) заранее спасибо

Почти все заказал жду, обнаружил деражатель для фена по разумной цене, но на днях появилась ПЛАТНАЯ доставка :(  Себе же заказал комплект фен с держателем (для прошлой конструкции покупал фен намного дороже да еще и без держателя)

обалдеть цены, кусок пластика с магнитом как сама рукоять...

в общем вот так получилось, внизу пишет время до отключения, либо перегрев при срабатывании защиты, справа выбор регулируемого параметра - обрисовываем прямоугольником что регулируем, вроде всё работает...

вот ссылка на мой скетч и библиотеку с новыми шрифтами:

https://www.dropbox.com/s/va99jdd5hpk0iuw/HA.rar?dl=0

замечания и тестирования приветствуются, температуру надо калибровать и по графику зависимостей считать, ещё не делал, скоро займусь... а так по факту пишет температуру 380, а по факту там около 150

 

Umkalab пишет:

Ха, смешные вы люди... Мои грабли про MOC в теме ОПС вам ничего не напоминают???

Не поверишь - до последнего был уверен что этот мосфет без детекции нуля... про грабли читал)

edcop
Offline
Зарегистрирован: 23.07.2016

Я так понимаю Ваш вариант без энкодера, на кнопках. Выложите пожалуйста принципиальную схему Вашего варианта фена. На фото несколько светодиодов, что они показывают?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Sergant пишет:
обнаружил деражатель для фена по разумной цене, но на днях появилась ПЛАТНАЯ доставка

Уголок и пара клипс для полипропиленовых труб - вот и держатель и себестоимость близка к нулевой.
В идеале бы клипсы не белого цвета найти. Серого, вроде, бывают.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

edcop пишет:

Я так понимаю Ваш вариант без энкодера, на кнопках. Выложите пожалуйста принципиальную схему Вашего варианта фена. На фото несколько светодиодов, что они показывают?

можно на ТЫ) в общем первый светодиод выведен с блока питания, показывает что бп включен, второй светодиод в цепи оптрона вентилятора, третий в цепи оптрона симистора, четвертый - в цепи включения реле, но блин он термоядерный, надо другой ставить. Энкодер не хочу, у меня паяльник на энкодере. Схема ниже, вроде всё поправил...

edcop
Offline
Зарегистрирован: 23.07.2016

Есть вопросы по схеме:

1. LM358 4 нога на землю, 8 нога на +5В вроде...

2. На схемах не вижу пищалки.

3. Нумерация пинов Ардуины не понятна.

4. Опторазвязка на мосфет обязательна?

5. Схемы кнопок не вижу.

Спасибо.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

edcop пишет:

Есть вопросы по схеме:

1. LM358 4 нога на землю, 8 нога на +5В вроде...

2. На схемах не вижу пищалки.

3. Нумерация пинов Ардуины не понятна.

4. Опторазвязка на мосфет обязательна?

5. Схемы кнопок не вижу.

Спасибо.

хм...такого не рисовал, когда всё до конца доделаю - нарисую схему полную и выложу, пока что кину печатную плату, там в принципе всё ясно должно быть...

1) да, питание на 8ой ноге

2) пищалка к 13ому пину через транзистор по стандартной схеме

3) тут не ардуино, просто общее обозначение, на печатке всё пронумеровано

4) не обязательна, и напрямую кидают, но у меня блок питания на 2 линии с раздельной землёй, схема через оптрон позволяет земли разделить и полностью развязать цепи 5в и 24в

5) кнопки по умолчанию подтянуты на 5в, по нажатию замыкаются на землю

ссылка на печатку https://www.dropbox.com/s/7g9umr6rsflgu3g/FEN.lay6?dl=0

будут вопросы - пиши, не стесняйся

edcop
Offline
Зарегистрирован: 23.07.2016

Не могу понять какой МК стоит. На атмегах вроде 28 ног, а тут 30.

Подойдёт ли такая обвязка LM358 для оригинальной схемы от OlegK? Хотелось бы конечно и калибровку к ней прикрутить (подстроечники "Начало" и "Конец").

Есть в продаже следующие прецезионные операционники:

- OP07CP

- LTC1051CN8

- INA217AIP

Из них какой-то подойдёт?

Спасибо.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

edcop пишет:
LTC1051CN8

Этот.

 

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

edcop пишет:

Не могу понять какой МК стоит. На атмегах вроде 28 ног, а тут 30.

Подойдёт ли такая обвязка LM358 для оригинальной схемы от OlegK? Хотелось бы конечно и калибровку к ней прикрутить (подстроечники "Начало" и "Конец").

Это не МК а плата Arduino Nano v3

я не заморачивался со сложной обвязкой ОУ, схему брал из этой статьи http://avrproject.ru/publ/kak_podkljuchit/podkljuchaem_termoparu_k_mikro...

правда немного изменил её, почему - читай комментарии к статье, там написано какие сопротивления лучше брать и почему, против схемы от Олега ничего не имею, но и сказать про неё ничего не могу - вообще даже не смотрел на неё, мне достаточно точности, которая получается с моей схемой, как и писал выше - нужно калибровать и выводить уравнение зависимости значений на А0 от температуры

edcop
Offline
Зарегистрирован: 23.07.2016

Еще несколько вопросов топикстартеру:

1. Подскажите, для чего встречные диоды в схеме с операционником?

2. Геркон в фене никак не задействован? По схеме не нашёл.

3. Сильно ли греется симистор на применяемом радиаторе?

Спасибо.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

edcop

1. Они защищают вход ОУ от напряжения свыше 0,5-0,6 вольт.

2. Задействован. Подключен к пину 11, на рисунке платы можно посмотреть. На схеме тоже есть - разъём Service, подписано  - геркон к пину 11. Алгоритм работы - в сообщении #1.

3. Специально не мерял, но "пальцевый" измеритель показал, что примерно до градусов 45-50. Симистор пластиковый, посажен на термопасту.

Sergant
Offline
Зарегистрирован: 24.03.2016

OlegK подскажите какие диоды применены в основной плате (в схеме номинала не нашел)!?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Диоды - любые, с обратным напряжением более питающего. Я ставлю 1N4148 или мелкие выпрямительные из китайских БП

edcop
Offline
Зарегистрирован: 23.07.2016

OlegK пишет:
2. Задействован. Подключен к пину 11, на рисунке платы можно посмотреть. На схеме тоже есть - разъём Service, подписано  - геркон к пину 11. Алгоритм работы - в сообщении #1.

Спасибо.

Для чего тогда в разъёме ещё D4 и D12?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

edcop пишет:
Для чего тогда в разъёме ещё D4 и D12?

Все выводы, помеченные как N/U (Not Used) - не использованы, зарезервированы для чего-нибудь.
К примеру для подключения другого графического дисплея (по SPI) или второго энкодера, для раздельной регулировки вентилятора или кнопок для пресетов. Да мало ли ещё для чего. Пусть будут, есть не просят.

К примеру, для порта SPI можно сформировать отдельный разъём, а для геркона выделить свободный вывод на разъёме геркона -

Русл@н
Offline
Зарегистрирован: 14.04.2016

Жестко вас там отпинали) Я купил такой экранчик, только верхние строки желтые, теперь действительно не пойму куда его приспособить)

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Русл@н пишет:
Жестко вас там отпинали

Где, кого, если не секрет.

pter
Offline
Зарегистрирован: 15.02.2016

Здравствуйте,

Русл@н пишет:

Жестко вас там отпинали,

это наверно как отнеслись к MkTwo на пикабу с его библеотекой для экрана.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

Русл@н пишет:

Жестко вас там отпинали) Я купил такой экранчик, только верхние строки желтые, теперь действительно не пойму куда его приспособить)

да я уж понял что дрова ножом колол)) кстати, можно просто верхнюю строку на жёлтый слой перекинуть, там делов то - координаты поменять)

leg42
Offline
Зарегистрирован: 04.03.2016

Подскажите. Где правильно на схеме или печатке? На схеме splan указаны пин 5 на зеро и MOC 3023. На плате зеро вроде нету.

 

 

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Ага, походу опечатка в схеме. На плате - соответствует.
D2 - к выходу ZeroCross, D5 - управление симистором.

ЗЫ. Обновил архив исправленной схемой.

Sergant
Offline
Зарегистрирован: 24.03.2016

Коллеги подскажите, может быть ворос ламерский, но я запутался. На схеме конденсаторы 0.1 это указанов в чем мкФ или нФ, что используем кодировку соотвественно 104 или 101 ? Видимо сам разобрался нФ и кодировка у 0.1 будет 101 но необходимо подтверждение!

Здесь https://www.drive2.ru/b/466734715605353483/ описан способ реализации работы энкодера (скетч с прерыванием и без прерывания), я не специалист в этом возможно это может упростить нашу схему ?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Sergant пишет:
На схеме конденсаторы 0.1 это указанов в чем

В мкФ. Или 100нФ. Кодировка 104.

Цитата:
описан способ реализации работы энкодера

Упростит, нужно попробовать...

Попробовал по ссылке, работает, но при быстром вращении в минус глючит (пропуски, перескоки).
При медленном работает нормально.
После незначительной модификации этот вариант от dimax вроде неплохо себя показал.
Даже если очень быстро крутить не сбивается.
Получилось так -

ISR(PCINT1_vect) {
  static byte old_n = PINC & 6; //B00000110 mask
  byte new_n = PINC & 6;

  if (old_n == B110 && new_n == 0) {
    X++;
    Serial.println(X);
  } else
  if (old_n == B100 && new_n == B10) {
    X--;
    Serial.println(X);
  }
  old_n = new_n;
}
Miamin
Offline
Зарегистрирован: 29.02.2016

Как я понимаю, используется внешние преерывание?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Да, по пину А2.

Miamin
Offline
Зарегистрирован: 29.02.2016

OkegK обьясниет пожайлута в атмеге 328/168/8 на картинках  по распиновки отображают PCINTx такое прерывание и еще внешние INTx. С внешним понятно, а что это за PCINTx, как его использовать?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

INT0, INT1 - внешние прерывания по пинам D2, D3, соответственно. Могут срабатывать по фронту, спаду или по изменению состояния.
PCINTx - тоже внешние прерывания, по отдельным пинам, насколько я знаю, срабатывают и по фронту и по спаду, т.е. выбрать нельзя.
Что бы использовать, нужно сконфигурировать соответствующие регистры.
На примере этой конструкции:
    PCICR = 0b00000010; // разрешили прерывание для группы 1
    PCMSK1 = 0b00000100; // разрешили прерывание для пина А2
ну и само прерывание
   ISR(PCINT1_vect) {
       //тут что-то делаем
   }
Подробнее можете почитать в этой статье.

MkTwo
MkTwo аватар
Offline
Зарегистрирован: 28.08.2016

В общем доделал я свой фен)

Выложу тут ссылки на пикабу, там я всё подробно расписал:

первая часть http://pikabu.ru/story/payalnyiy_fen_na_arduino_chast_pervaya_4894541

вторая часть http://pikabu.ru/story/payalnyiy_fen_na_arduino_chast_vtoraya_4911432

исходники https://www.dropbox.com/s/bb06nvpxaf3t2xr/HA.zip?dl=0

Всем спасибо за помощь!