Товары из Китая

DIY паяльная станция T12 + блок питания


DIY паяльная станция T12 + блок питания

Всем доброго дня!

В этой статье я хочу разсказать, как я делал портативный блок питания и паяльную станцию в одном корпусе и что из этого получилось. Будет радиолюбительство, программирование ардуино, много интересного для начинающих и еще больше букв.

Так уж получается, что большую часть жизни я провожу на работе. Здесь у меня есть хороший инструмент и немного времени, чтобы помогать людям с ремонтом различного електрооборудования. Но баранокороновирус заставил побыть немного дома. И когда кум припер детскую игрушку, в которой отвалился проводок, у меня просто не оказалось, чем его припаять и запитать для проверки.

В общем, решил я, что не мешало бы обзавестись домашним паяльником и источником питания. И так, ТЗ:

1. Удобный паяльник с контролем температуры.

2. Блок питания на 3..12В и пару ампер. В идеале до 5А, хотя бы кратковременно.

3. Малые габариты и вес, что бы взять с собой к клиенту.

4. Возможность питания в полевых условиях, например, от автомобильного аккумулятора.

Хочу еще сказать, что я знаю о существовании TS100 и что от повер-банка с PD и соответствующим тригером — будут чудеса. Но это дорого, да и хотелось задействовать накопившееся дома барахло.

Во первых, в украинском магазине был куплен корпус Z4W. У него ширина 150 мм (как в большинстве моих поделок), глубина 130 и высота — всего 50 мм.

Для питания — я выбрал всем известный народный блок на 24в. Здесь, на сайте, Kirich делал обзор на такой блок. Его хватит и на паяльник, и еще на пару ампер нагрузки. А если без паяльника — то и ампер 5 даст, но кратковременно, иначе в таком корпусе — ему станет жарко.

За паяльную часть будет отвечать контроллер Т12, за блок питания — модуль на XL4016, за измерения — Atmega328.

Самым первым, место в корпусе занял народный блок. Пришлось ампутировать ему левый верхний угол, но ему и на 3-х крепления не плохо.

DIY паяльная станция T12 + блок питания

Модуль преобразователя я купил давным-давно, вот здесь. Такие же — есть и на али.

Схема перобразователя:

DIY паяльная станция T12 + блок питания.

Для начала, я выпаял с него потенциометр с выключателем и клеммники. Для крепления к днищу корпуса, болты были заменены на стойки, высотой 30 мм. Родный електролиты — мешали стойкам, поэтому были заменены на 35 вольтовые. Они и ниже, и ESR у них в два раза меньше.

DIY паяльная станция T12 + блок питания

Еще фото
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

На месте входных клем — поселился источник 5 вольт для Атмеги, измерительных цепей и мозгов для паяльника.

Немного об источнике 5 вольт
Источник построен на микросхеме XL4001

Это — понижающий преобразователь. Она может принять на вход до 37 вольт. по даташиту — держит до 2 А, но я больше ампера — никогда не использовал. И еще — может работать в режиме СС, как драйвер для светодиодов. Я еще использовал ее в предрегуляторе своего блока питания.

У меня как то был немалый заказ на JLCPCB, и я заказал по горстке плат, для включения ее в режимах стабилизации напряжения и тока.

DIY паяльная станция T12 + блок питания

Даный преобразователь не умеет СС. Но у китайцев есть много на этой микросхеме, и с таким режимом. Например, Kirich уже делал обзор на подобный преобразователь.

Контроллер паяльника — куплен уже давно. Вот как он выглядит.

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

Так как на передней панели он занял бы слишком много места, было решено разместить его в глубинах корпуса. А энкодер, разьем и дисплей — вынести на переднюю панель. Ну и «родной» стабилизатор на 5 вольт уже не нужен. Вместо него — будет ушко крепления. При выпайке дисплея — очень помог кусочек медной фольги. А на его место — стал кусочек макетки, со штырьковым разьемом. Помимо линий дисплея, к штырькам выведены сигналы для светодиода нагрева, датчика вибрации, питание 5 вольт и общий. На место выходного разъема — впритык стал папа CH 3.96.

Вот, что получилось
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

Теперь в Corel draw нарисовал макетик передней панели, с реальными размерами органов управления. Потом распечатал его, вырезал и прикрепил к пластиковой стенке корпуса, и разметил отверстия.

DIY паяльная станция T12 + блок питания

Потом в кореле дооформил панель, распечатал, прорезал отверстия и заламинировал.

Картинки с Corel
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

Полная схема устройства:

DIY паяльная станция T12 + блок питания

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

Этот процес — я немного описал в этой статье.

Вот так выглядит плата с индикаторами:

DIY паяльная станция T12 + блок питания

Передняя панель — в сборе:

DIY паяльная станция T12 + блок питания

Еще фото передней панели
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

Поверх ее — находится плата измерений и ограничения тока.

DIY паяльная станция T12 + блок питания

Больше фото
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

В преобразователе — был заменен резистор R7, что бы понизить диапазон установки максимального выходного напряжения с 32 до 23 вольт. Анод диода, который стоит на входе для защиты от переплюсовки — теперь подключен выходу плюс.

Фото преобразователя с проводами и разъемами
DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

DIY паяльная станция T12 + блок питания

Комплекты пап и обжатых мам XH — отсюда.

Ну и вот, как все это разместилось в корпусе

DIY паяльная станция T12 + блок питания

Немного о схеме:

Если к выходным клеммам подключить внешний источник питания от 10 до 24 вольт — можно будет пользоваться паяльником, он запитается через диод VD1. Он был добыт на плате преобразователя, стоял параллельно входу, для защиты от переплюсовки.

ОР1 — усиливает сигнал с датчика тока и масштабирует его до 2,5 вольт при токе 5,12 ампер. Это пригодится при вычислениях, в атмеге. Я специально использовал хороший rail-to-rail ОУ, но схема начинала «видеть» ток на выходе, только начиная где то с 160мА, при падении на шунте (0,16 * 0,01) = 1,6мВ. Ниже этого — на выходе ОУ был ноль. В последствии — был добавлен резистор R13, он явно выделяется на фото. В паре с R16 — он образует делитель до, примерно, 1,4мВ, ОУ теперь видит ток от 50мА. Можно было бы еще увеличить R16, но меня и так устроило.

Делитель на R5, R17, R22 — масштабирует выходное напряжение, что бы получить 2,5 вольт при выходном 25,6. Так — удобнее при вычислении.

OP2 — сравнивает выходной ток с заданием от потенциометра R27 (5мВ…2,5В). При превышении — включает светодиод HL2 подает «притормаживающее» напряжение на вход обратной связи преобразователя.

Встроенный в потенциометр регулировки напряжения выключатель S1 — открывает транзистор VT1, шунтирующий блокирующее напряжение для XL4016, и дает сигнал на атмегу.

Схемка на ОР3 — должна управлять вентилятором охлаждения, но я этот фрагмент не реализовал. Пока — и так не жарко.

О программировании Atmega328:

Я писал програму в среде Arduino IDE, поэтому остановлюсь только на моментах, которые не совсем стандартны для «ардуинопользования».

Контроллер Atmega328 — взят новый. С завода — он не будет работать со средой ардуино, так как в нем нет загрузчика. Программирование будет осуществляться через USBasp программатор и SPI интерфейс. В качестве такого программатора, в теории, можно использовать и обычную ардуину, в стандартных примерах даже есть соответствующий скетч, но я не пробовал. Еще момент: в моем USBasp есть перемычка, которая замедляет скорость интерфейса при прошивке. Мне приходится ее использовать при прошивке новеньких Атмег, видимо с завода они «тикают» на низкой частоте.

На моей плате — не нашлось места для кварцевого резонатора. Но атмега может работать и от встроенного резонатора. Чтобы объяснить Arduino IDE, что так тоже можно, необходимо добавить в нее соответствующее ядро. Я предпочел MiniCore. Делал все по инструкции от Alex Gyver. Теперь в меню инструменты — плата появится вкладочка MiniCore, выбираем там ATmega328. Теперь в меню инструменты — Clock обязательно выбираем Internal 8 MHz. Еще в меню инструменты — программатор нужно выбрать USBasp.

Теперь подключаем программатор к Атмеге, я для этого предусмотрел соответствующие пины на плате, и к USB (само собой, драйвера на программатор должны быть). Включаем питание, выбираем инструменты — записать загрузчик. К слову, у меня не получалось, пока я не переключил программатор на пониженую скорость.

После прошивки загрузчика — можно заливать скетчи на нормальной скорости, через пункт Скетч — загрузить через программатор. Кнопка Загрузка на паннели инструментов — работать не будет.

О программе:

Все сегменты индикатора — подключены к одному порту. Это позволяет выводит информацию очень быстро. У меня — самым не занятым оказался порт D. Под такой вариант и разводилась плата. Как организованы выводы портов — видно на этом рисунке:

DIY паяльная станция T12 + блок питания

Выходы разрядов идут к ардуино пинам 11, 12, 13, 8, 9, 10. Сигнал включения — к 16, Аналоговые значения напряжения и тока, соответственно к А4 и А5. Все это — исключительно в угоду удобству разводки платы.

Ардуино пины 11, 12, 13, как и вывод Reset и GND — подведены к разьему программирования.

Текст программы
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// Use Mini core, Atmega328, No bootloader, Internal clock 8 MHz
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define TRIMM 0
// 0: normal
// 1: voltage
// 2: current
// 3: A/h
// Real input range ADC input ADC value
//-------------------------------------------------
// 25.5 V 2.5V 1023 / 4 = 255
// 2 V 80
// 12 V 480
// 22 V 883
//-------------------------------------------------
// 5.12 A 2.5V 1023 / 2 = 512
// 0.5 A 100
// 2 A 400
// 4 A 800
#define DIG_1 11
#define DIG_2 12
#define DIG_3 13
#define DIG_4 8
#define DIG_5 9
#define DIG_6 10
#define ON_OFF 16
#define VOLTAGE_PIN 4
#define CURRENT_PIN 5
byte active_digit;
byte image[6];
long current_count_mA;
int current_count;
unsigned int current_count_timer;
int ms_3600_ticks;
volatile int voltage_ADC, current_ADC, voltage_ADC_dirty, current_ADC_dirty;
int voltage_display, current_display;
int voltage_buffer, current_buffer;
byte buffer_count;
float voltage_corrector, current_corrector;
const byte symbols[] =
{
//bfagc0de
0b11101011, // 0
0b10001000, // 1
0b10110011, // 2
0b10111010, // 3
0b11011000, // 4
0b01111010, // 5
0b01111011, // 6
0b10101000, // 7
0b11111011, // 8
0b11111010, // 9
0b00000000, // space
0b01110001, // F
0b11111001, // A
0b10010001, // /
0b01011001 // h
};
void setup() {
analogReference(EXTERNAL);

pinMode(DIG_1, OUTPUT);
pinMode(DIG_2, OUTPUT);
pinMode(DIG_3, OUTPUT);
pinMode(DIG_4, OUTPUT);
pinMode(DIG_5, OUTPUT);
pinMode(DIG_6, OUTPUT);
DDRD = 0xFF;
PORTD = 0x00;
TCCR1A = 0;
TCCR1B = 1<<WGM12 | 1<<CS11 | 1<<CS10; // enable CTC, prescale 64. Increment each 1/(8000000/64=250kHz) 8 mkS
TIMSK1 = 1<<OCIE1A; // enable compare interrupt
OCR1A = 1250; //10mS
TCCR2A = 0; //TMR2 normal mode
TCCR2B = 1<<CS21 | 1<<CS20; // prescale 32, interrupt each 1 / (8000000/256/32=976.56Hz) = 1mS
TIMSK2 = 1<<TOIE2; // enable interrupt
TCNT2 = 0; // reset counter
current_count_mA = 0;
current_count_timer = 65000;
}
void loop() {
voltage_ADC_dirty = analogRead(VOLTAGE_PIN);
current_ADC_dirty = analogRead(CURRENT_PIN);
current_count = current_count_mA / 1000;
voltage_corrector = map(voltage_ADC,0,1023,3,-6);
voltage_display = ((float)voltage_ADC + voltage_corrector) / 4; // VV.V
current_corrector = map(current_ADC,0,1023,10,-10);
if (current_ADC == 0) current_corrector = 0;
current_display = ((float)current_ADC + current_corrector) / 2; // A.AA

if (digitalRead(ON_OFF))
{
if (TRIMM == 0)
{
image[0] = symbols[((voltage_display/100)%10)];
image[1] = symbols[((voltage_display/10)%10)];
image[1] |= 0b00000100;
image[2] = symbols[(voltage_display%10)];
image[3] = symbols[((current_display/100)%10)];
image[3] |= 0b00000100;
image[4] = symbols[((current_display/10)%10)];
image[5] = symbols[(current_display%10)];
}
if (TRIMM == 1)
{
image[0] = symbols[((voltage_ADC/1000)%10)];
image[1] = symbols[((voltage_ADC/100)%10)];
image[2] = symbols[((voltage_ADC/10)%10)];
image[3] = symbols[(voltage_ADC%10)];
image[4] = symbols[10];
image[5] = symbols[10];
}
if (TRIMM == 2)
{
image[0] = symbols[((current_ADC/1000)%10)];
image[1] = symbols[((current_ADC/100)%10)];
image[2] = symbols[((current_ADC/10)%10)];
image[3] = symbols[(current_ADC%10)];
image[4] = symbols[10];
image[5] = symbols[10];
}
if (TRIMM == 3)
{
image[0] = symbols[((current_count_mA/100000)%10)];
image[1] = symbols[((current_count_mA/10000)%10)];
image[2] = symbols[((current_count_mA/1000)%10)];
image[3] = symbols[((current_count_mA/100)%10)];
image[4] = symbols[((current_count_mA/10)%10)];
image[5] = symbols[(current_count_mA%10)];
}
}
else
{
if (current_count_timer < 1000)
{
image[0] = symbols[12];
image[1] = symbols[13];
image[2] = symbols[14];
image[3] = symbols[((current_count/100)%10)];
image[3] |= 0b00000100;
image[4] = symbols[((current_count/10)%10)];
image[5] = symbols[(current_count%10)];
}
else
{
current_count_mA = 0;
image[0] = symbols[10];
image[1] = symbols[10];
image[2] = symbols[10];
image[3] = symbols[0];
image[4] = symbols[11];
image[5] = symbols[11];
}

}
}
ISR(TIMER1_COMPA_vect) // each 10mS
{
TCNT1 = 0; // !!!!!!!!!!!!!!!!!!!!!!!!!!!
ms_3600_ticks++;
if (ms_3600_ticks > 360)
{
ms_3600_ticks = 0;
current_count_mA = current_count_mA + current_display;
if (current_count_mA > 999000) current_count_mA = 999000;
}
if (current_count_timer < 65000) current_count_timer++;
if (digitalRead(ON_OFF)) current_count_timer = 0;

voltage_buffer = voltage_buffer + voltage_ADC_dirty;
current_buffer = current_buffer + current_ADC_dirty;
buffer_count++;
if (buffer_count > 15)
{
buffer_count = 0;
voltage_ADC = voltage_buffer >> 4;
voltage_buffer = 0;
current_ADC = current_buffer >> 4;
current_buffer = 0;
}

}
ISR(TIMER2_OVF_vect)
{
active_digit++;
if (active_digit > 5) active_digit = 0;
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,LOW);
switch (active_digit)
{
case 0:
PORTD = image[0];
digitalWrite(DIG_1,HIGH); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,LOW);
break;
case 1:
PORTD = image[1];
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,HIGH); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,LOW);
break;
case 2:
PORTD = image[2];
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,HIGH); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,LOW);
break;
case 3:
PORTD = image[3];
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,HIGH); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,LOW);
break;
case 4:
PORTD = image[4];
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,HIGH); digitalWrite(DIG_6,LOW);
break;
case 5:
PORTD = image[5];
digitalWrite(DIG_1,LOW); digitalWrite(DIG_2,LOW); digitalWrite(DIG_3,LOW); digitalWrite(DIG_4,LOW); digitalWrite(DIG_5,LOW); digitalWrite(DIG_6,HIGH);
break;
}
}

Соответственно разводке платы, сигнальные линии порта D, в виде 0bxxxxxxxx соответствуют сегментам bfagcpde, где p — десятичная точка. Значения, которые нужно отправить в регистр для отображения соответствующего символа, лежат в масиве symbols[].

Ардуино меряет аналоговые сигналы относительно напряжения питания. Функция analogRead(PIN) вернет 0, если на соответствующем пине 0, и максимум 1023, если уровень на входе равен напряжению питания. Питание может быть не стабильно, поэтому желательно использовать отдельный источник опорного напряжения. Недорогой и простой способ — это получить 2,5вольт от TL431 (VD6 на схеме) и подать их на Aref микроконтроллера. Функция analogReference(EXTERNAL); переводит АЦП атмеги на работу от внешнего источника опорного напряжения.

Для вывода информации на дисплей используется порт D. Необходимо записать 1 во все биты регистра направления работы и 0 — в биты регистра вывода DDRD = 0xFF; PORTD = 0x00;.

В атмеге есть три аппаратных таймера. Здесь не плохо о них написано. В ардуино они используются для генерации ШИМ, а таймер 0 — для функций delay и millis. Таймеры работают независимо от основного ядра. Они могут генерировать прерывания, это когда процесор прерывает основной цикл, выполняет то, что описано в обработчике прерывания, а потом — возвращается к основному цыклу.

Таймером 1 управляют регистры TCCR1A, TCCR1B. Я включил его на нормальный счет, с тактированием от основного генератора и предделителем 64. Процесор работает на 8 МГц, следовательно таймер будет увеличиваться на 1 каждые 1/(8000000/64=250kHz) = 8 микросекунд.

Теперь нужно разрешить прерывание по сравнению от таймера, в регистре TIMSK1 и записать в регистр OCR1A величину для сравнения. До значения 1250 таймер досчитает за (1250 * 8 мкС) = 10000мкС, или 10 миллисекунд.

Таймером 2 управляют регистры TCCR2A, TCCR2B. Я включил его на нормальный счет, с тактированием от основного генератора и предделителем 32. Это 8 — розрядный таймер. Он считает до переполнения, равного 255, потом сбрасывается на 0, и далее — по кругу, все время.

Теперь нужно разрешить прерывание по переполнению от таймера, в регистре TIMSK2. Переполнятся таймер будет каждые 1 / (8000000/256/32=976.56Hz) = 1024 мкС.

Именем ISR(TIMER1_COMPA_vect) обзывается обработчик прерывания по сравнению таймера 1. Вызывается он каждые 10 мС.

В первую очередь, нужно обнулить счетный регистр TCNT1.

Потом — в отдельные переменные суммируются данные с АЦП напряжения и тока. Через каждые 16 замеров — эти суммы делятся на 16 (сдвиг числа на 4 разряда вправо). Это происходит через 160 мС. Достаточно быстро, и не сильно цифры мельтешат.

Именем ISR(TIMER2_OVF_vect) обзывается обработчик прерывания по переполнению таймера 2. Здесь считаются разряды дисплея, от 0 до 5. И в зависимости от значения, вытягиваем с массива image соответствующее значение в порт D и зажигаем соответствующий разряд.

У уже писал про приведение аналоговых сигналов напряжения 25,5 вольт и тока 5,12 ампер к 2,5 вольтам. Это не спроста. При 25,5 вольт АЦП выдаст 1023. Делим его на 4 и выводим на индикацию число 255. По току — делим на 2 и выводим 512,

Но если по максимальных значениях все удалось подстроить потенциометрами R5 и R19, то на минимальных — наблюдалось занижение результата. Так что по потенциометрах будем выстраивать среднее значение.

Возьмем среднее значение 12 вольт, и крайние 2 вольта и 22 вольта. Собираем математическую пропорцию, получаем, что в АЦП должно быть, соответственно 480, 80 и 883. Заставляем программу выводить значение АЦП напряжения (условие if (TRIMM == 1)) и выставляем на выходе 12 вольт. Резистором R5 — добиваемся показания 480. Ставим 2 вольта, видим 77, вместо желаемых 80, а при 22В — 889 вместо 883.

Функция вывода напряжения принимает вид voltage_display = ((float)voltage_ADC + voltage_corrector) / 4;, где значение коррекции меняется от 3 до -6. Это делается в функции voltage_corrector = map(voltage_ADC,0,1023,3,-6);.

Аналогично — с током. Среднее значение было взято 2А. Крайние 0,5А и 4А. Ожидаемые значения АЦП — соответственно 400, 100 и 800. По условию if (TRIMM == 2) выводим значение АЦП и выставляем резистором R19 показание 400 при реальном токе 2А. При 0,5А получили 90 вместо желаемых 100, а при 4А — 810 вместо 800. следовательно, коррекция меняется от 10 до -10. current_corrector = map(current_ADC,0,1023,10,-10); Вот только когда на АЦП реально 0, коррекция +10 нам не нужна if (current_ADC == 0) current_corrector = 0;. Ну и выводим ток на дисплей current_display = ((float)current_ADC + current_corrector) / 2;. Как результат — получена точность 0,1 вольт и 0,01 ампер.

Когда поворачиваем регулятор напряжения на минимум, до щелчка, размыкается выключатель S1. Закрывается транзистор VT1 и 12 вольт через VD2 поступают на вход обратной связи XL4016. Последняя выключается и на выходе устанавливается 0.

Переменная current_count_timer перестает постоянно сбрасываться и увеличивается до значения 65000.

Но пока она меньше значения 1000 (а длится это 1000 * 10 мс = 10 сек), на индикаторе напряжения высвечивается «A/h», а тока — значение счетчика ампер-часов. Потом, если включений на протяжении этого периода не будет, счетчик сбросится, а на дисплей — выведется «OFF».

В обработчике прерываний таймера 1 постоянно увеличивается переменная ms_3600_ticks. Когда она достигает значения 360, через (360 * 10 = 3600 мС) = 3,6 секунды, в переменную current_count_mA суммируется значение индикатора тока. За час — таких замеров будет ровно 1000. Следовательно, что бы получить значение Ампер/час, нужно эту сумму разделить на 1000.


СМОТРИ ТАКЖЕ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *