#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Encoder.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 8); // Определяем пины для подключения дисплея
Encoder myEnc(2, 3); // Определяем пины для подключения энкодера
int encButton = 9; // Определяем пин для подключения кнопки энкодера
int pinPWM = 10; // Определяем пин для управления скорость вращения турбины
int pinSSR = 13; // Определяем пин для управления коммутацией нагревателя
int pinOn = 12; // Определяем пин для управления включением блока питания из дежурного режима
int pinBase = 11; // Определяем пин для подключения геркона
static const unsigned char PROGMEM logo_bmp[] = // Рисуем каркас меню
{ B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11110000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B10000000, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000,
B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11110000
};
static const unsigned char PROGMEM cursor_bmp[] = // Рисуем курсор
{ B11111111, B11111111,
B10000000, B00000000,
B10000000, B00000000,
B10000000, B00000000,
B10000000, B10000000,
B10000000, B11100000,
B10000000, B11111000,
B10111111, B11111110,
B10000000, B11111000,
B10000000, B11100000,
B10000000, B10000000,
B10000000, B00000000,
B10000000, B00000000,
B11111111, B11111111
};
float realTemp = 0; // Реальное значение температуры
int setTemp = 100; // Установленное значение температуры
byte realPWM = 0; // Реальное значение оборотов турбины
byte setPWM = 50; // Установленное значение оборотов турбины
byte indexPWM = 0; // Индекс для выбора правильных коэффициентов пересчета температуры
int realTempArray[100]; // Массив для усреднения значения температуры при измерениях
unsigned long summTemp = 0; // Сумма данных массива
int averTemp = 0; // Усредненная температура
int minTemp = 0; // Минимальное значение температуры для станции
int maxTemp = 500; // Максимальное значение температуры для станции
byte minPWM = 30; // Минимальное значение оборотов турбины
byte maxPWM = 100; // Максимальное значение оборотов турбины
long timeCurrent = 0; // Таймер для хранения текущего времени
long timeMenu = 0; // Таймер для управления меню
long timeMeasurement = 0; // Таймер для управления циклами измерений
long timeSleep = 0; // Таймер для управления уходом в сон
long oldPosition = 0; // Переменная для чтения данных с энкодера
long newPosition = 0; // Переменная для чтения данных с энкодера
bool selectMenu = LOW; // Выбранное меню
bool flagEnc = LOW; // Флаг для устранения дребезга при вращении энкодера
bool flagEncButton = LOW; // Флаг для устранения дребезга при нажатии энкодера
bool flagBase = HIGH; // Флаг положения ручки в подставке
bool flagSleep = HIGH; // Флаг состояния сна
bool heat = LOW; // Флаг нагрева
int hysteresis = 3; // Температурный гистерезис
float K[8] = {0.500, 0.528, 0.528, 0.535, 0.535, 0.522, 0.505, 0.492}; // Мультипликативный коэффициент подсчета температуры
int A[8] = {36, 31, 32, 28, 23, 22, 22, 15}; // Аддитивный коэффициент подсчета температуры
void setup() {
TCCR1B = TCCR1B & 0b11111000 | 0x02; // Устанавливаем частоту ШИМ на 10 выводе как 3906.25 Гц
pinMode(A1, INPUT); // Определяем аналоговый пин A1 на ввод (выход ОУ)
pinMode(encButton, INPUT); // Определяем пин encButton на ввод
pinMode(pinBase, INPUT); // Определяем пин pinBase на ввод
pinMode(pinPWM, OUTPUT); // Определяем пин pinPWM на вывод
pinMode(pinSSR, OUTPUT); // Определяем пин pinSSR на вывод
pinMode(pinOn, OUTPUT); // Определяем пин pinOn на вывод
digitalWrite(pinOn, HIGH); // Подаем на пин включения высокий уровень TTL (переводим блок питания из дежурного режима в рабочий)
display.begin();
display.setContrast(50);
display.display();
}
void loop() {
flagBase = !digitalRead(pinBase); // Получаем состояния пина pinBase
timeCurrent = millis(); // Получаем текущее время
if ((timeCurrent - timeMeasurement) >= 100) { // Если с прошлого измерения прошло больше 100 мсек
heat = LOW; // Выключаем нагрев
digitalWrite(pinSSR, heat); // Отправляем на вывод состояние нагрева
delay(50); // Ждем 50 мсек (для исключения влияния помех от симистора)
summTemp = 0; // Обнуляем сумму
for (byte i = 0; i <= 99; i++) { // И повторяем 100 раз цикл
realTemp = analogRead(A1); // Считываем значение на A1
realTempArray[i] = realTemp; // Записываем в массив показаний
summTemp = summTemp + realTempArray[i]; // Складываем все элементы массива
}
averTemp = round(summTemp / 100); // Подсчитываем среднее арифметическое
indexPWM = realPWM / 10 - 3; // Вычисляем индекс коэффициентов пересчета показаний в температуру
realTemp = round(K[indexPWM] * averTemp + A[indexPWM]); // Вычисляем реальное значение температуры
timeMeasurement = millis(); // Записываем время проведения измерения
}
if (flagBase == LOW) { // Если ручка не в подставке
digitalWrite(pinOn, HIGH); // Включаем блок питания из дежурного режима в рабочий
flagSleep = LOW; // Устанавливаем флаг сна в низкий уровень
analogWrite(pinPWM, map(setPWM, 30, 100, 76, 255)); // Выводим ШИМ на pinPWM
realPWM = setPWM; // Приравниваем реальное значение PWM установленному
if (setTemp > realTemp + hysteresis ) { // Если установленная температуры выше чем сумма реальной и гистерезиса
heat = HIGH; // Включаем нагрев
}
if (setTemp < realTemp) { // Если установленная температура меньше реальной
heat = LOW; // Выключаем нагрев
}
digitalWrite(pinSSR, heat); // Отправляем на вывод состояние нагрева
timeSleep = millis(); // Записываем последнее время, когда ручка не в подставке
}
else { // Если ручка в подставке
heat = LOW; // Выключаем нагрев
digitalWrite(pinSSR, heat); // Отправляем на вывод состояние нагрева
if (((timeCurrent - timeSleep) <= 120000) && (flagSleep == LOW)) { // Если прошло меньше 120 секунд с последнего раза, когда ручка была не в подставке и станция не в режиме сна
analogWrite(pinPWM, 128); // Выводим ШИМ с заполнением 50% на pinPWM
realPWM = 50; // Записываем в реальное значение ШИМ 50
}
else { // Иначе
digitalWrite(pinPWM, LOW); // Отключаем турбину
realPWM = 0; // Записываем в реальное значение ШИМ 0
digitalWrite(pinOn, LOW); // Переводим блок питания в дежурный режим
flagSleep = HIGH; // Записываем в флаг сна высокое значение TTL
}
}
display.clearDisplay(); // Очищаем дисплей
display.drawBitmap(0, 0, logo_bmp, 84, 48, BLACK); // Рисуем каркас меню
display.setTextColor(BLACK); // Устанавливаем цвет текста
display.setTextSize(2); // Устанавливаем размер текста
display.setCursor(13, 3); // Устанавливаем координаты курсора
display.println(realTemp, 0); // Выводим значение реальной температуры
display.setCursor(56, 0); // Устанавливаем координаты курсора
display.println("o"); // Отрисовываем знак градуса
display.setCursor(67, 3); // Устанавливаем координаты курсора
display.println("C"); // Отрисовываем "C"
display.setTextSize(1); // Устанавливаем размер текста
display.setCursor(22, 24); // Устанавливаем координаты курсора
display.println(setTemp); // Выводим значение установленной температуры
display.setCursor(46, 21); // Устанавливаем координаты курсора
display.println("o"); // Отрисовываем знак градуса
display.setCursor(52, 24); // Устанавливаем координаты курсора
display.println("C"); // Отрисовываем "C"
display.setCursor(70, 24); // Устанавливаем координаты курсора
if (heat == HIGH) { // Если нагрев включен
display.println("H"); // Отрисовываем "H"
}
if (flagBase == HIGH) { // Если ручка в подставке
if (flagSleep == LOW) { // Если станция не в режиме сна
display.println("B"); // Отрисовываем "B"
}
else { // Если станция в режиме сна
display.println("S"); // Отрисовываем "S"
}
}
display.setCursor(20, 37); // Устанавливаем координаты курсора
display.print(realPWM); // Выводим значение реальных оборотов турбины
display.print("/"); // Отрисовываем "/"
display.print(setPWM); // Выводим значение установленных оборотов турбины
display.print(" %"); // Отрисовываем " %"
if (selectMenu == 0) { // Если выбран 0-ой пункт меню
display.drawBitmap(0, 21, cursor_bmp, 16, 14, BLACK); // Отрисовываем курсор напротив значения установленной температуры
}
else { // Иначе
display.drawBitmap(0, 34, cursor_bmp, 16, 14, BLACK); // Отрисовываем курсор напротив значения оборотов турбины
}
display.display(); // Отображаем все на дисплее
newPosition = myEnc.read(); // Читаем позицию энкодера
if (flagEnc == LOW) { // Если флаг энкодера в низком уровне
bool buttonState = digitalRead(encButton); // Читаем в переменную buttonState значение с кнопки энкодера
if (buttonState == 0) { // Если это низкий уровень (кнопка нажата)
if (flagEncButton == HIGH) { // Если флаг кнопки энкодера в высоком уровне
selectMenu = !selectMenu; // Выбираем следующий пункт меню
flagEnc = HIGH; // Устанавливаем флаг энкодера в высокий уровень
timeMenu = millis(); // Записываем время, когда трогали меню
flagEncButton = LOW; // Устанавливаем флаг кнопки энкодера в низкий уровень
}
else { // Если флаг кнопки энкодера в низком уровне
flagEncButton = HIGH; // Устанавливаем его в высокий уровень
}
}
else { // Если это высокий уровень (кнопка не нажата)
flagEncButton = LOW; // Устанавливаем флаг кнопки энкодера в низкий уровень
}
if (newPosition != oldPosition) { // Если позиция энкодера изменилась
flagEnc = HIGH; // Устанавливаем флаг энкодера в высокий уровень
timeMenu = millis(); // Записываем время, когда трогали меню
if (newPosition > oldPosition) { // Если новая позиция энкодера больше предыдущей
if (selectMenu == 0 && setTemp < maxTemp) { // Если выбран пункт меню 0 и температура меньше максимальной
setTemp = setTemp + 10; // Увеличиваем температуру на 10
}
if (selectMenu == 1 && setPWM < maxPWM) { // Если выбран пункт меню 1 и обороты меньше максимальных
setPWM = setPWM + 10; // Увеличиваем обороты на 10
}
}
if (newPosition < oldPosition) { // Если новая позиция меньше предыдущей
if (selectMenu == 0 && setTemp > minTemp) { // Если выбран пункт меню 0 и температура больше минимальной
setTemp = setTemp - 10; // Уменьшаем температуру на 10
}
if (selectMenu == 1 && setPWM > minPWM) { // Если выбран пункт меню 1 и обороты больше минимальных
setPWM = setPWM - 10; // Уменьшаем обороты на 10
}
}
}
}
if ((timeCurrent - timeMenu) >= 250) { // Если прошло больше 250 мсек с момента, как трогали меню
flagEnc = LOW; // Устанавливаем флаг энкодера в низкий уровень
oldPosition = newPosition; // Сохраняем позицию энкодера
}
}
Все что надо — в наличии — и турбинка, и нагреватель…
Сколько на фен STM'ок с AMOLED'ами ни навесь, кроме красивостей дополнительных плюшек не получишь.
А тут гармоничное решение.
В экономической части обзора отсутствует стоимость блока питания, так что экономическая целесообразность в этом продукте отсутствует напрочь.
Прошу прощения, а нет ли ошибки с расположением R15?
А так давольно красиво и бюджетно получитесь.
Молодец! :)
Если бы у меня не было покупной станции, собрал бы по этому обзору себе.
Вентилятор, кстати, присутствует далеко не во всяком газотурбинном двигателе, и если он присутствует, то большая часть воздуха, проходящего через вентилятор в двигатель вообще не попадает.
На что было справедливо замечено, что
Каким боком к этому относится Ваше
?
И вы немного путаете последовательность комментов.
Сразу не заметил наличие выключателя на входе устройства (по схеме его нет, а на фото такой ракурс, что кажется, что это какое другое устройство). Хочу сказать, что выключатель тут обязателен! (Посмотрите видео про возгорание паяльных станций Lukey.) Идея проста — в выключенном состоянии идет высоковольтная помеха из сети и пробивает симистор. Включается нагреватель фена, но без турбины. Нагреватель разогревается до «красна», плавится и загорается пластмасса. И ни один автомат или УЗО этому процессу помешать не смогут — ведь 700 Вт вполне себе нормальная нагрузка.
Насчет помех на входе ОУ — вы, вероятно, правы, но добавить 2 массива по 8 значений в скетч мне тоже было совсем не сложно.
А вот терморезистор — это строго наоборот. Большое сопротивление, никакого ЭДС.
(попробовал)
Завтра ещё раз перечитаю на свежую голову.
видимо пришла пора продавать люкей852. давно паяю Т12, держал его только ради фена
И еще я как-то не понял по схеме где у вас фаза разрывается? Я что-то… вообще туплю дико… Можно суть конденсатора C9 и резистора R17?
И ниже камрад спросил по поводу библы для энкодера. Я бы тоже поинтересовался.
теперь следите за руками:
— точность MAX31855 в диапазоне -200°C..+700°C всего ±2°C и скорее всего чип может и больше (мои догадки) просто точность любой К-термопары как раз и есть ±2°C и точнее делать смысла нет
— шаг измерения температуры термопары 0.25°C. выше смысла нет, см пункт первый
— MAX31855 имеет компенсацию холодного спая. у автора ее нет. стоит температуре в корпусе фена подняться выше комнатной, а она подымется. все его калибровки и температура поплывут.
— с наводками у нее проблем меньше
так что вполне себе решение и замена архаичному оу.
А так заказал одну на попробовать. Спасибо.
Термопара показывает не абсолютное значение температуры, а разницу температур между холодным и горячим спаем.
Вот для того и ставят.
Это с паяльником вполне одного энкодера хватит. А тут и воздух и температуру. Сам делал подобное, но продал. Сейчас осталось ОУ дождаться и буду новый собирать. Хотел с сенсорным экраном, интерфейс нарисовал, на макетку загрузил, потыкал и понял что это так же не удобно как и один энкодер…
Есть PCINT1-XX. Есть прерывание по таймеру. Почему нужно использовать именно INT1-2 не понятно.
а второе прерывание вешать на только на ОДНУ ногу втрого эткода и дочитывать значение второй ноги втрого энкодера после срабатывания прерывания.
даже библиотеку для этого написал, где это можно легко реализовать — elchupanibrei.livejournal.com/29025.html
Аналогично платке для т12.
Уже 1.5 года лежит такой фен, все ждал подходящую схему.
А здесь все хотелки и сразу, даже печатка и исходник прошивки…
Огромное спасибо автору.
Дорого, но… хавают )
Спасибо — отличный проект!!!
И еще вопрос — обязательно использовать 40амперный мосфет? Он же управляет вентиляторов только?.. Подойдут менее мощные, с материнки например?
К слову довольно удобно подобный результат можно получить в бесплатном Graph.
Теперь знаю чем займусь в ближайшее время. С той разницей, что есть жменька семисегментников, сдвиговых регистров и потенциометров 10К. Цена вопроса 556 рублей заказать фен (у этого же продавца есть лот с платной доставкой в Россию :-) дешевле получается).
Еще раз спасибо!
— на странице продавца в описании лота и в комментах, если я правильно понял, есть версии 12в и 24в.
есть какие то преимущества?, 12-ти вольтовый БП проще подобрать.
— за что отвечает uint32_t currentFrequency;?
— переменная pars дважды обнуляется и больше ни где не используется. Я правильно понял, что она использовалась при подборе количества выборок для усреднения и сейчас не нужна?
— по поводу динамической индикации, боюсь Вы правы, в лупе есть задержка для подавления помех, тем более я хотел их два приспособить. Впрочем есть дисплей от телефона 3110. Но он на 3,3в, или на Вашем шилде есть преобразователи уровней?
— как я понял в качестве опорного для АЦП используется Vcc. Но 7805 может выдавать от 4,8 до 5,2 в. Или коэффициенты компенсируют все возможные погрешности?
-у меня в наличии МОС 3036. Нужно ли менять параметры R13, R3?
— ОУ нет. Покупать такой же или посоветуете другой?
uint32_t currentFrequency, так же как и переменная pars, действительно просто занимают пару байт памяти. Первая осталась по ошибке от родственного проекта на дисплее, вторая использовалась для усреднений. Я подправил, спасибо.
На шилде дисплея преобразователя уровней нет. Я пока не сталкивался с проблемами по поводу толерантности дисплея 5110, рассчитанного на 3.3 В логику с 5 вольтовой логикой. Может мне просто везло.
Да, в качестве опорного напряжения для АЦП используется Vcc. Можно использовать внутренний 1.1 В, уменьшив примерно в 4 раза коэффициент усиления ОУ, но я бы не сказал что он намного стабильнее.
3063 аналог этой оптопары, так же имеет встроенную детекцию перехода через ноль как и вся серия 304X и 306X.
Если ОУ нет, то LM358 отличный вариант для покупки, это самый дешевый ОУ, который есть везде. Из популярного есть еще TL072, он дороже и лучше, но для этого применения разницы нет.
И просто и защита присутствует и релейное управление, все по феншую. Дешево и безопасно )))
А что такое релейное управление?
Плюс хочу пид контроль… Да много что хочу )
Я ж говорю реализаций вагон.
И экран… Хочу большой 12864. Но может и маленький такой. Олед не хочу. Он убер мелкий. У меня есть парочка. Один в более или менее пользовании на минидельте. Не удобно. Слишком мелкое все.
Пид контроль и большой экран все хотят, хотя… ))
Кстати у Олега как раз на энкодере, хотя кто то требует кнопки )))
Я бы не сказал что реализаций именно фена так уж много, по мне так всего то несколько проектов и уж тем более на Атмеге.
Реле, имеется ввиду управление защитой через реле, тиристоры и иже с ними, слишком это все пожароопасно, зато безопасно, ну и что бы контроль нуля, тут же (при всем уважение к автору), в данной схеме защита отсутствует вовсе и при пробитии тиристора, фен уйдет в неконтролируемый нагрев со всеми вытекающими… ) )) Все исключительно ИМХО
Не факт что его пробьет на кз. 50/50. Да и как уже сказал выше… Плюс я хочу бипер. На новой плате на паяльник такая тема удобная. Включил и даже не смотришь на экран, чисто бик. Можно паять. Хотя и Т12 и и так ждать надо 5 секунд.
1. по паспорту 7805 на входе держит не более 18 вольт, можно заменить на любой импульсный.
2. блок питания 24+3 — блок от принтера Canon(k30292), 24+3 — 850ма.
3. Контроллер заменяем Arduino mini — размеры минимальны, цена меньше в разы по сравнению с изготовлением платы.
4. MOC3041M, IRLZ44N и дисплей — есть готовые платы на али.
Таким образом, всё что указано можно заказать в виде конструктора и собрать в любой корпус, в течении 30 минут.
Первый попавшийся даташит
Input Voltage (VO = 5V to 18V) 35 V
Немного её переделал для полной запитки от 24VDC.
Остальное просто распечатал.
Сделал шаг 1%, при 65% перестает крутиться моторчик, может шкалу сделать с учетом этого? Ставил при испытании
analogWrite(pinPWM, map(setPWM, 30, 100, 76, 255));.
Без изменения частоты ШИМ двигатель включается при оборотах 20%, напряжение тестером 5,9в.Решил оставить без изменения частоты ШИМ.
При выключении изменен алгоритм, теперь пока температура не падает до 20 градусов, турбина дует на100%.
drive.google.com/open?id=1kIVslnNhh_wwUYiPS6cWZgkMM5ohE07Z
и затем снять показания, получить нужные коэффициенты в Exel, внести их в скетч и перепрошиться.
Меняете калибровочные коэффициенты K (мультипликативный) и A (аддитивный), прошиваете — меняются показания. Чтобы из Exel получить первоначальные коэффициенты, нужно изначально в прошивке задать их равными 1 и 0
и уже потом полученные показания забить в Exel и получить их истинные значения. Они в свою очередь будут зависеть от коэффициента усиления ОУ.