Вопросы по C++ (часть 2)

Вторая часть ответов на интервью-вопросы на знание языка программирования C++.

26) Что такое инкапсуляция

Инкапсуляцией называют скрытие деталей реализации внутри класса. При использовании механизма инкапсуляции объекты защищаются от произвольного изменения (с помощью ключевых слов protected или private); взаимодействие с объектом происходит с помощью публичных функций-членов.

27) Что такое перегрузка функций?

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

28) Что такое множественное наследование?

Множественное наследование позволяет определить производный класс, который будет наследовать члены от нескольких базовых классов.

29) Что такое перегрузка операторов?

Аналогично перегрузке функций это возможность ЯП определить поведение оператора, при передаче ему разных аргументов.

30) Что такое частичная специализация шаблона?

Частичная специализация шаблона позволяет явно задать параметры основного шаблона и доопределить полученный шаблон в соответствие с его назначением.

31) Что такое полиморфизм?

Свойство языка, позволяющая определить разное поведение для объектов с одинаковой спецификацией.

Пример 1: производный класс наследует публичный интерфейс базового класса, но с помощью перекрытия изменяет поведение виртуальных функций.

Пример 2: перегрузка функций.

32) В чём разница между передачей аргумента по значению и передачей аргумента по ссылке?

В способе размещения аргумента в памяти. При передаче аргумента по значение он копируется в стек, а вызываемая функция работает с копией аргумента. При передаче аргумента по ссылке вызываемая функция работает с исходным аргументом, а не его копией (ссылка является псевдонимом переменной).

33) Какая разница между объектом и классом?

Класс является сложным типом, который описывает внутренние данные и функциональный интерфейс. Объект является экземпляром класса, размещаемым в памяти.

34) В чём разница между объявлением и определением функции?

В объявлении указывается формат вызова, в который входят 1) имя функции, 2) описание аргументов, передаваемых в функцию, и 3) описание возвращаемого функцией результата. В определении реализуется алгоритм работы функции.

35) -

36) В чём разница между delete и delete[]?

Ключевое слово delete используется для удаления объекта, которое происходит в два этапа. Во-первых, вызывается деструктор объекта, который, например, выполняет удаление членов класса. Во-вторых, выполняется освобождение занимаемой объектом памяти. Ключевое слово delete[] используется для удаления массива объектов, при этом для каждого элемента массива будет вызван деструктор, а затем произойдёт освобождение памяти.

37) Какая разница между вложенным (внутренним) классом и абстрактным классом?

Внутренний класс - это класс, который определён внутри другого класса. Абстрактный класс - это класс, имеющий чисто виртуальные функции-члены.

38) В чём разница между перманентным и неперманентным объектом?

Перманентный объект сохраняет своё состояние на всём протяжении жизни, в то время как неперманентный объект может изменить своё состояние.

39) Чем отличается структура (struct) от объединения (union)?

Объединение отличается от структуры способом размещения данных-членов. В объединении данные-члены делят отводимую для них область памяти так, что перекрывают друг друга. В структуре (равно как и в классе) данные-члены размещаются в своих областях памяти.

40) Чем отличается поверхностное копирование от глубокого копирования?

При поверхностном копировании будет, например, продублирован указатель на данные (появится новый объект, который ссылается на существующие данные). При глубоком копировании вместо сохранения указателя будет осуществляться полное копирование данных.

41) Какая разница между открытыми, защищёнными и закрытыми членами класса?

Разница заключается в уровнях доступа к этим членам. Открытые члены класса доступны всем. Защищённые доступны только данному классу и классам-наследникам. Закрытые члены доступны только данному классу.

42) Какую максимальную длину может иметь массив?

Это зависит от нескольких факторов. Во-первых, от способа размещения массива. При размещении на стеке размер зависит от размера стека (и его способности к расширению). При размещении в куче - от возможностей аппаратных средств и ОС. Во-вторых, размер должен укладываться в size_t, который зависит от используемой платформы (32 или 64 разряда).

43) Как наиболее эффективно инвертировать связный список?

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

44) Какой размер у пустого класса?

Размер пустого класса должен по крайней мере быть равен размеру минимально адресуемой области памяти. Обычно это 1 байт.

45) Зачем используется виртуальный деструктор?

Это единственный способ обеспечить вызов деструктора у производного класса при удалении объекта по указателю на базовый класс.

46) Что такое виртуальный класс? Что такое дружественный класс?

Виртуальный класс - это класс, имеющий виртуальные функции-члены. Дружественный класс - это класс, который имеет доступ к закрытым членам данного класса.

47. Назовите лучший способ объявить и определить глобальную переменную. Вариант 1 (C-style):

// source.c
int global = 0;
// source.h
extern int global;

Вариант 2 (С++ style): определить класс с открытой статической переменной:

// source.hpp
class A {public: static int global;};
// source.cpp
int A::global = 0;

48) В какой области памяти инстанцируется объект?

Зависит от способа размещения. Если объект является локальной переменной, то он размещается в стеке. Если объект создаётся с использованием ключевого слова new, то он размещается в куче.

49) В какой области памяти инстанцируется структура?

Аналогично объекту (см. ответ на вопрос 48).

50) Почему первый элемент массива имеет индекс 0?

Индекс массива определяет смещение относительно начала массива. Очевидно, что по смещению 0 находится первый элемент.

Вопросы по С++ (часть 1)

Первая часть моих ответов на вопросы из списка.

1) Как определить, что связный список является кольцевым?

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

2) Какой целочисленный тип использовать?

Это определяется прикладной задачей, решаемой в рамках данной предметной области. Во-первых, нужно определиться с шириной коридора принимаемых значений переменной целочисленного типа (char, short, int, long, long long; с использованием модификаторов signed, unsigned). Во-вторых, учесть количество памяти, отводимое под переменную соответствующего типа (1, 2, 4 или 8 байт).

3) Каково отличие между конструктором и деструктором.

Конструктор - специальный метод объекта, вызываемый сразу после выделения ему памяти, выполняющий инициализацию членов объекта. Деструктор - метод вызываемый перед освобождением памяти, отводимой объекту, служащий для “деинициализации” (например, удаления) членов объекта.

4) В чём разница между агрегированием и ассоциированием?

Под агрегированием понимается владение (создание) объектом A объекта B. При этом допускается, что жизненный цикл объекта B не зависит от A.

Под ассоциированием понимается использование объектом A объекта B: объект A содержит ссылку или указатель на объект B и использует объект B, когда это необходимо.

5) Как определить размер класса?

Использовать конструкцию sizeof (имя класса) или sizeof (объект).

6) Как реализовать функцию itoa?

Вместо слов:

void itoa(int value, char *str)
{
    char *ptr = str;
    bool sign = value < 0;

    if (sign)
        value = -value;
    
    while (value)
    {
        char digit = value % 10;
        *ptr++ = '0' + digit;
        value /= 10;
    }

    if (sign)
        *ptr++ = '-';

    *ptr-- = '\0';

    while (str < ptr)
    {
        char symbol = *str;
        *str++ = *ptr;
        *ptr-- = symbol;
    }
}

7) Как определить указатель на функцию?

typedef void (*fn)(int, char *);

8) Как связать программу, написанную на C++, с функциями, написанными на C?

Объявление функций, написанных на C, нужно обернуть конструкцией вида extern "C" { }.

9) Как вернуть структуру из функции?

Обыкновенно, по значению (структура разместится в стеке).

10) Как написать функцию, которая инвертирует связный список?

Вариант 1. Перестановка значений. Двигаясь одновременно справа и слева к центру (до момента когда указатели встретятся) переставлять элементы. Минус - для этого нужно получить указатель на последний элемент (то есть обойти список).

Вариант 2. Перестановка указателей. Двигаясь в прямом направлении (слева направо): а) запоминаем указатель на текущий элемент и указатель на следующий элемент, б) у текущего элемента указателю на следующий элемент присваиваем значение указателя на предыдущий элемент, в) указателю на предыдущий элемент присваиваем адрес текущего элемента, г) переходим к следующему элементу по известному указателю (до тех пор пока он не NULL).

11) Какие преимущества от использования исключений C++?

С помощью исключений могут быть зафиксированы случаи некорректной работы программы (возникновение ошибок), приняты спасательные меры и сохранена работоспособность программы. Является альтернативой возврата кода ошибки. Имеет преимущество: исключение может быть поймано на любом уровне иерархии вызовов.

12) Какая разница между структурой и классом в C++?

Почти никакой. В структуре по умолчанию все члены являются публичными. В классе - приватными.

13) Какие есть модификаторы элементов классов/структур и переменных?

auto - обычный модификатор; является модификатором по умолчанию для локальных переменных функции.

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

static - переменная существует на протяжении жизненного цикла программы (глобальная + ограничение области видимости).

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

mutable - только для членов класса; разрешает модификацию члена класса, даже если он объявлен в коде как константный.

14) Что такое встроенные (inline) функции?

Функции, которые не оформлены как самостоятельная единица. Тело таких функций копируется в то место программы, из которого осуществляется её “вызов”. Использование inline-функций даёт выигрыш в скорости исполнения (не происходит сохранение и восстановление слова-состояния процессора в стеке), но увеличивает размер программы.

15) На что указывает ключевое слово extern в объявлении функции?

На то, что функция определена в другом файле.

16) -

17) Для чего используют ключевое слово static в объявлении функции?

Ключевым словом static ограничивается область видимости функции (её нельзя вызвать из другого файла). Если функция-член класса объявлена статической, то она может модифицировать только статичные члены класса.

18) Что такое неявное преобразование типов в конструкторе?

C++ допускает неявное преобразование аргумента Arg, указанного в конструкторе MyClass(int Arg) в объект MyClass. Для запрещения такого преобразования для конструктора необходимо указать ключевое слово explicit.

19) Что такое конструктор копирования?

Конструктор, который принимает единственный аргумент точно такого же типа как и сам объект. Предполагается, что создаваемый объект будет копией объекта, на который ссылается аргумент.

20) Что такое пространство имён (namespace)?

Средство разделения имён символов (функций, классов, переменных), служащее для исключения коллизий.

21) Что такое абстрактная функция?

Функция, которая должна быть обязательно определена в производном классе. Невозможно создать экземпляр базового класса, в котором объявлена абстрактная функция.

22) Что такое оператор разрешения контекста?

:: позволяет указать контекст класса, переменной, функции.

23) Что такое абстракция?

Средство для использования объектов без знания деталей реализации.

24) В чём разница между #define и const.

#define является директивой препроцессора, которая служит для подстановки в код определённых с её помощью величин. Модификатор const позволяет один раз определить константную переменную и использовать её в тех местах программы, где это необходимо (по сравнению с #define это иногда сокращает размер программы).

25) В чём разница между перегрузкой и переопределением метода?

Перегрузка позволяет создать много методов с одним и тем же именем, но разным набором аргументов и возвращаемых значений. Это делается, в основном, для повышения читаемости кода.

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

Блок управления внешней нагрузкой контроллера для гидропоники

Блок является частью контроллера для гидропоники и выполняет управление четырьмя массивами светодиодов.

Step-down преобразователь +30В -> +15В

Преобразователь выполнен на базе LM2842 (U1). Параметры преобразователя и порядок его настройки приводится в описании основного блока.

Расчёт:

1) Входные данные: VIN = 30 В, VOUT = 15 В, IOUT = 0,5 А, Iripple = 0,15 А.

2) R1 = 1,5 кОм, R2 = (VOUT/0,765 – 1) * R1 = (15 / 0,765 – 1) * 1,5 = 28 кОм.

3) СIN = 10 мкФ (керамика).

4) L1 = (30 – 15) * 15 / (30 * 0,15 * 550 * 103) = 91 мкГн (SDR1006-101KL).

5) COUT = 22 мкФ, Vripple=0,15 * (0,35 + [1 / (8 * 550 * 103 * 22 * 10-6)] = 0,053 В.

6) CBOOT = 1,0 мкФ.

7) D1 – 10BQ060 (60 В, 1,0 А).

Преобразователь +15В -> +3,3В

Преобразователь построен на базе микросхемы LM1117-N-3 (U2), характеризуемой максимальным током 800 мА.

Расчёт:

1) Входной конденсатор – 10 мкФ (тантал).

2) Выходной конденсатор – от 10 мкФ, рекомендуется 22 мкФ (тантал, ESR от 0,3 до 22 Ом).

Измерение тока в цепи нагрузки

Последовательно с нагрузкой соединён резистор номиналом 1 Ом (R29 - R32). Падение напряжения на этом резисторе пропорционально току, протекающему в цепи нагрузки. Это падение напряжения измеряется микроконтроллером STM32F031F (U3). Измеренное падение напряжения преобразуется микроконтроллером в периодический импульсный сигнал, имеющий фиксированную частоту 50 Гц и изменяемый коэффициент заполнения импульсов, пропорциональный падению напряжения. Этот периодический сигнал (F1-F4) поступает через транзистор (Q3-Q6) на оптопару HCPL053X (U10, U11) и далее в основной блок контроллера.

Прямой ток через диод оптопары HCPL053X составляет IF = (3,3 – VF)/R = (3,3 – 1,45) / 100 = 18,5 мА

Максимальный выходной ток оптопары при IF = 18,5 мА составляет примерно IO = 6 мА.

Для управления оптопарой выбран транзистор BC807 (коэффициент усиления по току – 100, не менее; в базе резистор 4,7 кОм, то есть базовый ток составляет (3,3 – 0,7)/4,7 = 0,55 мА, что позволяет получить ток коллектора от 50 мА и выше).

Управление нагрузкой

Управляющие сигналы на открытие силовых ключей поступают из основного блока контроллера на оптопары HCPL053X (U4, U7). Напряжение питания оптопар составляет +15 В.

Сигнал с коллектора оптопары поступает на инверсный вход драйвера n-канального MOSFET-транзистора (U5, U6 и U8, U9). В качестве драйвера используется микросхема IR2128S (с возможностью контроля КЗ; данная функция не используется). Драйвер также как и оптопара запитан от источника +15 В.

Сигнал с драйвера через резистор номиналом 100 Ом поступает на затвор силового n-канального транзистора IRF7341 (Q1, Q2). Силовой транзистор коммутирует напряжение +30 В на LC-фильтр нагрузки.

Расчёт LC-фильтра нагрузки

Расчёт происходит двумя способами, которые дают схожие результаты:

Начальные данные: fsw = 10 кГц, VIN = 30 В, IOUT = 1 А. Выходное напряжение изменяется в диапазоне от 0 до 30 В.

Из статьи “Катушки индуктивности Bourns для преобразователей энергии”:

1) Период импульсов: Tsw = 1 / fsw = 100 мкс.

2) Средний коэффициент заполнения: D = (VOUTmax – VOUTmin) / 2VIN = (30 – 0) / (2 * 30) = 0,5.

3) Время открытия ключа Ton = DTsw = 50 мкс.

4) Величина пульсаций тока: Iripple = 0,3 * IOUT = 0,3 А.

Примечания

1 Величина пульсаций (и это важно) означает разницу между значением тока, протекающим через катушку в момент закрытия ключа, и значением тока, протекающим через катушку в момент открытия ключа. Другими словами, в момент открытия ключа ток, имеющий значение I1, начинает линейно расти до значения I1 + Iripple. В момент закрытия ключа ток начинает линейно уменьшаться (происходит заряд конденсатора COUT) до значения I1. С новым импульсом на открытие ключа цикл повторяется.

2 Из величины Iripple следует, что значение минимального стационарного тока составляет Is = Iripple/2 = 150 мА. Минимальный стационарный ток – это ток, который может быть передан дросселем в ёмкость COUT после закрытия ключа при заданном коэффициенте заполнения импульсов коммутации ключа. Если нагрузка требует меньший ток, то появятся автоколебания тока после закрытия ключа (ток потечёт в обратную сторону – в дроссель). Чтобы это исключить после дросселя устанавливается диод Шоттки.

5) Падение напряжения на катушке: V = VIN – (VOUTmax - VOUTmin) / 2 – Vdiode = 30 – 15 – 1 = 14 В.

6) Минимальное значение индуктивности: L2 = L3= L4 = L5 = VTon / Iripple = 2,333 мГн

7) COUT = C12 = C15 = C19 = C22 = 150 мкФ, ESR = 0,3 (танталовый). Пульсации напряжения для выбранного конденсатора составят: Vripple = Iripple(ESR + [1 / (8 * fsw * COUT)]) = 0,115 В.

Расчёт дросселя выполнялся в программе DrosselRing (1100):

Основной блок контроллера для гидропоники

Основной блок является “мозгами” контроллера для гидропоники. Схема основного блока приводится на двух листах.

Лист 1

Step-down преобразователь +12В -> +3,3В

Преобразователь построен на базе LM2842 (U7). Его характеристики:

Настройка (из тех. описания на LM2842):

1) Величина выходного напряжения: VOUT = VFB * (1 + R39/R38), где R38 = 100..10000 Ом

2) Входной конденсатор С4 (керамика с низким ESR; X5R или X7R). Рекомендуемые значения ёмкости от 2,2 до 10 мкФ

3) Дроссель L1 = [(VIN - VOUT) * VOUT] / (VIN * Iripple * fsw)

С ростом допустимых пульсаций тока Iripple величина индуктивности уменьшается, но возрастают потери на намагничивание, потери в сердечнике. Это также требует выходного конденсатора большей ёмкости. Рекомендуемое значение Iripple составляет около 30% от величины выходного тока. Расчёт индуктивности ведётся для максимального значения VIN. КПД преобразователя напрямую зависит от сопротивления дросселя (лучшие показатели достигаются с использованием толстого провода). Рекомендуется использовать такой индуктор, в котором потери на нагрев составляют 2% от выходной мощности (другими словами, активное сопротивление дросселя составляет 2% от сопротивления нагрузки). Начальным вариантом является дроссель с индуктивностью от 10 до 22 мкГн и максимальным током 1,1 А или выше.

4) Выбор выходного конденсатора C6 зависит от величины максимальных допустимых пульсаций выходного напряжения. При постоянной частоте fsw величина пульсаций напряжения

Vripple = Iripple * (ESR + [1 / (8 * fsw * COUT)]).

Необходимо выбирать керамические конденсаторы с низким ESR. Рекомендуемый номинал от 22 до 100 мкФ с ESR ≤ 0,1 Ом.

5) C5 ≥ 0,15 мкФ (керамика). Рекомендуется 1,0 мкФ.

Расчёт:

1) Входные данные: VIN = 12 В, VOUT = 3,3 В, IOUT = 0,5 А, Iripple = 0,15 А.

2) R38 = 1,4 кОм, R39 = (VOUT / 0,765 – 1) * R38 = (3,3 / 0,765 – 1) * 1,4 = 4,7 кОм.

3) С4 = 10 мкФ (керамика).

4) L1 = (12 – 3,3) * 3,3 / (12 * 0,15 * 550 * 103) = 29 мкГн (SDR1006-330KL: 33 мкГн, Irms= 1,5 А).

5) C6 = 22 мкФ, Vripple = 0,15 * (0,35 + [1/(8 * 550 * 103 * 22 * 10-6)] = 0,053 В.

6) C5 = 1,0 мкФ.

7) D1 – 10BQ060 (60 В, 1,0 А).

Аналоговая часть

С целью уменьшения влияния цифровой части устройства на измеряемые аналоговые сигналы вводится «развязка» питания через LC-фильтр (по примеру схемы платы LPC1830-Xplorer).

Измерение аналоговых сигналов происходит с помощью резистивных делителей и операционных усилителей AD8606 (питание +3,3 В) с коэффициентом усиления 1 (на схеме U3, U5).

Резистивный делитель построен на резисторах номиналами 10 и 3,3 кОм (R19 и R21, R26 и R27, R32 и R33) и позволяет измерять входное напряжение величиной до 13,3 В.

После делителя сигнал смещается вверх на 0,5 В (с помощью U3:A) и поступает на неинверсный вход операционного усилителя. С выхода операционного усилителя повторённый сигнал идёт на вход АЦП микроконтроллера.

Дискретные сигналы

Входные сигналы типа “сухой контакт”

Измерение входного дискретного сигнала типа «сухой контакт» (-, минус) осуществляется с помощью подтянутого к питанию +12 В резистора (номинал 10 кОм) и транзисторной сборки ULN2804, выбранной исходя из величины опорного напряжения (+12 В).

Коллектор выходного транзистора ULN2804 (U6) подтянут к питанию +3,3 В. Сигнал с коллектора поступает на сдвиговый регистр 74HC165 (U4), который по сигналу микроконтроллера преобразует входной параллельный код в выходной последовательный код и выдаёт микроконтроллеру состояние датчиков типа «сухой контакт».

Выходные сигналы

К выходным дискретным сигналам относятся: силовые напряжением ~220 В (ток до 5 А) и силовые напряжением +12 В (ток до 0,1 А).

Выдача дискретных сигналов происходит с помощью:

Коммутацию напряжения ~220 В выполняет реле типа TRJ-12DC (RL1-RL4). В цепи фазы установлен предохранитель с номинальным током 5 А (FU1-FU4).

Коммутацию напряжения +12 В выполняет транзистор IRF7314 (Q1). В цепи +12 В установлен самовосстанавливающийся защитный резистор с номинальным током 0,1 А (R4, R8).

Лист 2

В центре схемы - микроконтроллер STM32F407Z. Он тактируется кварцевым резонатором частотой 12 МГц (X1 - HC-49SM, печатный монтаж), зашунтированным конденсаторами по 18 пФ (керамика).

Для питания микроконтроллера введён массив керамических конденсаторов номиналами 1,0 и 0,1 мкФ (C15-C22).

Отладка микроконтроллера происходит по интерфейсу JTAG. Для этого на плате размещается разъём XP1 (IDC-20MS).

Диагностический интерфейс

Для отладки устройства без использования специализированных средств (JTAG-программатора) служит выделенный USB-интерфейс, который построен на микросхеме CP2102 (U10), представляющей собой полноценный преобразователь USB-UART.

Кроме стандартной обвязки CP2102 (рекомендации по её параметрам приводятся в описании к микросхеме) добавлен транзистор, который формирует сигнал RESET (сброс микроконтроллера). Дополнительный сигнал ISP нужен для ввода микроконтроллера в режим загрузчика.

Сигнал RESET определяется состоянием на линии DTR, сигнал ISP – состоянием на линии RTS. Сигнал сброса микроконтроллера RESET проходит через ФНЧ с постоянной времени τ = R77 * C13 = 47000 * 0,1 * 10-6 = 4,7 мс.

Ethernet

Схема модуля позаимствована из схемы платы LPC1830-Xplorer (OM13028).

Модуль построен на PHY LAN8720 (U11). PHY тактируется от кварцевого генератора KXO-V97 частотой 50 МГц (самый крайний по приемлемости вариант, лучше использовать более точный генератор).

Особое внимание необходимо уделить питанию PHY. В цепи питания установлен LC-фильтр на базе L4 и C26-C28 (аналогично схеме-донору).

Сигнальный трансформатор встроен в разъём RJ-45 (XS1). В нём же установлены светодиоды, информирующие о скорости работы интерфейса и активности на линии.

Часы реального времени

Используется микросхема DS3231M (U13). Очень хороший вариант, рекомендую.

Часы могут работать как от основного питания, так от батарейки (в случае отсутствия основного питания). Взаимодействие микроконтроллера с часами происходит по интерфейсу I2C. Номиналы резисторов R87, R88 на линиях SDA и SCL определяют максимальную скорость информационного обмена. Установлены резисторы номиналом 10 кОм (при том, что имелся опыт работы на частоте 400 кГц с резисторами номиналом 22 кОм).

Энергонезависимая память

В качестве микросхемы энергонезависимой памяти используется AT45DB321D (U12) объёмом 4 Мбайт. Это довольно продвинутая память, которая берёт часть работы программиста на себя. Так, при записи новых данных, она копирует страницу во внутреннее ОЗУ, стирает страницу, а затем пишет в стёртую страницу результат слияния прошлых данных с теми, которые были переданы пользователем.

Драйвер RS-485

Для связи с периферийными устройствами по асинхронному последовательному каналу в контроллере находится драйвер шины RS-485 MAX-487 (U9) с управлением потоком (чтение/запись).

Схема токового управления нагрузкой

Схема управления питанием основана на pnp-транзисторе (Q4-Q7), с помощью которого выдаётся сигнал на оптопару. Расчёт схемы проведён исходя из того, что на другой стороне установлены оптопары типа HCPL0530/¼.

1) Прямой ток через диод оптопары составляет IF = (3,3 – VF) / R55 = (3,3 – 1,45) / 100 = 18,5 мА (VF - падение напряжения на диоде).

2) Максимальный выходной ток оптопары при IF = 18,5 мА составляет примерно IO = 6 мА.

3) Для управления оптопарой выбран транзистор BC807 (коэффициент усиления по току – 100, не менее; в базе резистор 4,7 кОм, то есть базовый ток составляет (3,3 – 0,7) / 4,7 = 0,55 мА, что позволяет получить ток коллектора от 50 мА и выше).

Измерения тока в цепи нагрузки

Из схемы питания нагрузки в основной микроконтроллер через оптопару поступают импульсы (разъёмы XT17, XT18). Коллектор оптопары подтянут к питанию +3,3V через резистор номиналом 4,7 кОм (R60-R63).

Подключение радиомодуля

Предполагается, что в устройстве будет использован радиомодуль RF-2423P, работающий в области частоты 2,4 ГГц. Подключение радиомодуля осуществляется через разъём XP2 (PBD-8). Линия питания поддержана дополнительным танталовым конденсатором C11 ёмкостью 10 мкФ.

Источник питания контроллера для гидропоники

В качестве источника питания для контроллера используется импульсный блок на базе микросхемы IR2153.

Параметры источника питания:

Схема блока питания:

На входе источника находится фильтр ЭМП на базе дросселя TR1 индуктивностью 15 мГн (номинальный ток 0,8 А) и пары конденсаторов C1 и C2 номиналами 0,47 и 0,15 мкФ.

При включении источника в сеть ~220 В происходит ограничение тока с помощью NTC термистора номиналом 20 Ом. Также в цепи ~220 В установлен предохранитель, рассчитанный на максимальный ток 0,8 А.

Сетевое напряжение ~220 В выпрямляется с помощью диодного моста BR1 (DF06S). Выпрямленное пульсирующее напряжение (примем его за Uвыпр) заряжает конденсатор С3 ёмкостью 100 мкФ. Параллельно C3 подключён шунтирующий конденсатор C4 ёмкостью 1 мкФ.

Напряжение Uвыпр делится с помощью RC-делителя на базе конденсаторов C8, C9 ёмкостью 1 мкФ и резисторов R5, R6 номиналом 180 кОм. Это делается для того, чтобы на одном конце первичной обмотки трансформатора TR2 получить потенциал равный Uвыпр/2.

Коммутацией напряжения (вернее потенциала) Uвыпр на второй конец первичной обмотки трансформатора TR1 занимается драйвер U1 (IR2153) и управляемые им полевые n-канальные транзисторы Q1, Q2 (IRFR310).

Питание драйвера U1 получено из сетевого напряжения с помощью резистора R1 номиналом 18 кОм (мощностью 2 Вт!), диода D1 (FR107) и конденсатора C5 ёмкость 100 мкФ (полупериодный выпрямитель; внутри драйвера находится стабилитрон с обратным напряжением 15,6 В).

Частота коммутации драйвером U1 силовых транзисторов Q1, Q2 задаётся резистором R2 и конденсатором C6, имеющими номиналы соответственно 14 кОм и 1000 пФ. Из описания драйвера частота переключения: fsw = 1/(1,38 * CT * (RT + 75)) = 1/(1,38 * 1000 * 10-12 * 14075) = 51 кГц.

Первичная обмотка трансформатора TR2 зашунтирована последовательно включёнными конденсатором C10 ёмкостью 1000 пФ и резистором R7 сопротивлением 100 Ом для исключения передачи во вторичную обмотку высокочастотных помех.

В трансформаторе TR2 имеются две гальванически не связанные вторичные обмотки. Параметры трансофрматора (тип и размер сердечника, количество витков) подбирались с помощью программы Lite-CalcIT (1700):

Одна из вторичных обмоток TR2 служит для получения однополярного питания +30 В. Напряжение вторичной обмотки выпрямляется с помощью диодного моста на базе диодов D3-D6 Шоттки 6CWQ10FN и сглаживается LC-фильтром. Параметры LC-фильтра:

Вторая обмотка трансформатора TR2 служит для получения однополярного питания +12 В. Аналогично предыдущему случаю, здесь используется диодный мост и LC-фильтр:

Параметры дросселей L1 и L2 (тип и размер магнитопровода, количество витков) подбирались с помощью программы DrosselRing (1100).

L1:

L2:

Контроллер для гидропоники

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

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

Среди таких параметров:

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

Такая необходимость и желание опробовать свои знания в области электроники привели к тому, что появился проект выходного дня под условным названием “Контроллер для гидропоники”.

Контроллер обладает следующими характеристиками:

Используемые микроконтроллеры:

Контроллер состоит из следующих блоков: