Найти тему
Сергей Малофеев

Эквивалент нагрузки на модулях Arduino

Как-то пришло время дооснастить лабораторию новым девайсом - эквивалентом нагрузки.

Погуглив интернет и решив не переводить транзисторы на ТЭНы для обогрева комнаты взял за базу схему с ШИМ регулированием (источник https://www.radiokot.ru/circuit/analog/measure/26/):

Схема от Radiokot.ru
Схема от Radiokot.ru

Как функционирует данное устройство вполне понятно, загадкой для меня осталось только на мой взгляд сильно "усложненное" исполнение драйвера, а также цепочка формирования отрицательного напряжения (об этом подробнее ниже).

Устройство было решено собрать из имеющихся модулей, а именно:

- Arduino Pro Mini - в качестве ШИМ регулятора.

- 0.96' I2c 128x64 Oled Display Module - для отображения процента заполнения ШИМ.

- Энкодер KY-040.

- L298N - в качестве драйвера управления полевыми транзисторами, применение этого модуля излишне (надо бы было просто взять драйвер типа IR442x), просто модули L298 есть в наличии, дополнительно от него получаем +5В для питания контроллера.

- Вольтметр / амперметр 60В, 50А.

- Блок питания на 12В 1А (в моем случае маломощный трансформатор со стабилизатором на LM317.

- Вентилятор (на схемах ниже не показан, продувает воздух в основном через R3).

Непосредственно нагрузку собрал по следующей схеме:

-2

Основной критерий для MOSFEET - минимальное сопротивление канала в открытом состоянии и необходимым напряжением сток-исток. Забегая вперед - греется только R3 (правда сильно). Кстати, R3 выполнен из нихромовой проволоки диаметром 1,5 мм. Катушку L1 подобрал из оставшихся после разбора импульсного БП.

Схема соединения модулей выглядит следующим образом:

В контроллер залил следующий код:

-3

/*

Программа для формирования ШИМ с переменной скважностью
и частотой генерации 8 кГц.
- ШИМ с выводов 9 и 10 (синхронно для управления 2-мя полевиками)
- Энкодер для изменения скважности в пределах 0-100% на выводы 2, 4
- LED дисплей 128х32 для отображения текущей скважности на выводах А4 и А5
*/
# include "SPI.h"
# include "Wire.h"
# include "Adafruit_GFX.h"
# include "Adafruit_SSD1306.h"
# include <avr/io.h>
# include <avr/interrupt.h>
# define OLED_RESET 4 //для LED
# define ENC_A 2 // пин энкодера 1
# define ENC_B 4 // пин энкодера 2
# define ENC_TYPE 1 // тип энкодера, 0 или 1
volatile int encCounter;
volatile int number = 0; //вспомогательная переменная для вывода в порт
volatile boolean state0, lastState, turnFlag; //переменные для обработки внешнего прерывания
int val = 0; // переменная для хранения считываемого значения скважности
Adafruit_SSD1306 display(OLED_RESET); //определяем LED дисплей
void setup() {
//Настраиваем LED дисплей
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //0x3C - адрес LED
display.clearDisplay();
display.display(); //выполнить очистку LED
delay(1000);
display.setTextSize(1); // установка размера шрифта
display.setTextColor(WHITE); // установка цвета текста
display.setCursor(20,0); // установка положения курсора х,у в пикселях
//заставка
display.println();
display.println("Electronic load");
display.println("equivalent");
display.display(); //вывести надпись
//настраиваем регистры счетчика 1 для формирования ШИМ
OCR1A = 0; //изначально нет генерации ШИМ
OCR1B = 0;
TCCR1A = 0b10100010;
TCCR1B = 0b00011001;
TIMSK1 = 0b00000001;
ICR1 = int(2000); //8000 Гц
DDRB = 0b00000110; // PB1 и PB2 выходные каналы.
// Serial.begin(9600);
attachInterrupt(0, int0, CHANGE);
sei();
}
void int0() { //обработка прерывания по внешнему событию (энкодер)
state0 = digitalRead(ENC_A);
if (state0 != lastState) {
# if (ENC_TYPE == 1)
turnFlag = !turnFlag;
if (turnFlag)
encCounter += (digitalRead(ENC_B) != lastState) ? -20 : 20; //шаг 1%
# else
encCounter += (digitalRead(ENC_B) != lastState) ? -20 : 20; //шаг 1%
# endif
lastState = state0;
}
//граничные условия
if (encCounter < 0) {
encCounter = 0;
}
if (encCounter > 2000) {
encCounter = 2000;
}
}
ISR(TIMER1_OVF_vect){ //обработка прерывания по таймеру 1
OCR1A = number;// задаем скважность
OCR1B = number;// -//-
}
//основной цикл программы//
void loop() {
if (number != encCounter) { //обновляем надпись на дисплее при изменении значения скважности ШИМ
// Serial.println(encCounter);
display.clearDisplay();
display.setCursor(55,0);
display.setTextSize(1);
display.println("PWD");
display.setTextSize(2);
display.setCursor(45,12);
display.print(encCounter/20);
display.print(" %");
display.display();
number = encCounter;
}
}

Шаг регулировки скважности выбран 1%, можно уменьшить до 0,05%, но на мой взгляд для шага меньше 0,5% лучше применить второй энкодер (реализовать схему регулировки грубо/точно). Поскольку микроконтроллер остался практически не загружен, да и еще в L298N осталось 2 канала, можно добавить, например, терморезистор и регулировать обороты вентилятора.

Еще одно замечание касаемо L1, толщина провода должна быть достаточной, чтобы выдержать пропускаемый предельный ток.

Ну а работает получившийся девайс следующим образом:

В заключении упомяну, как обещал выше, о формировании отрицательного напряжения на затворах для более быстрого закрытия MOSFEET. В отличии от оригинальной версии с использованием 3-х диодов и конденсатора, в данной схеме за это отвечают цепочки R1,C1 и R2,C2. В итоге получаем кратковременно -2В при закрытии и более резкие фронты управляющего импульса, что вполне достаточно (полевые транзисторы при напряжении ниже порогового и так надежно закрыты):

Осциллограмма управляющих импульсов на затворе MOSFEET (маркер 1 (слева) соответствует напряжению 0В)
Осциллограмма управляющих импульсов на затворе MOSFEET (маркер 1 (слева) соответствует напряжению 0В)

Пока испытания устройства прошли на максимальном токе 10А и напряжении 9В.