Raspberry Pi

Русский сайт по микрокомпьютеру Raspberry Pi

Вход








Регистрация | Забыли пароль?

Поиск



По всему сайту
По тэгам
По тэгам и заголовкам

Рубрики

  • Проекты и статьи
  • Модели
  • Новости
  • Мысли
  • Облако тэгов

    raspberry pi 3, raspbian, ubuntu, linux, умный дом, windows 10, osmc, игры, python, windows, gpio, установка ос, raspberry pi 2, raspberry pi zero, raspberry pi zero w, слежение, самолёт, http, diy, 1c-битрикс, web, сеть, кластер, бесперебойник, акустика

    Боковое меню

  • RSS-канал
  • Карта сайта
  • Обратная связь
  • Пользователи


    Top.Mail.Ru

  • Как посредством ШИМ-контроллера регулировать обороты кулера на Rapsberry Pi и ему подобных SoC

    Зачастую центральные процессоры мини-пк семейства Rapsberry охлаждаются маленьким, а потому и шумным пятивольтовым вентилятором. Многие решают эту проблему, подключая его к 3.3 вольтовому выводу, однако данное решение имеет недостаток, связанный с тем что типовые пятивольтовые вентиляторы потребляют 200 мА, вследствие чего вызывают нагрузку на не рассчитанный на такую мощность регулятор 3.3В

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

    Содержание

    1. Шим - что это и для чего нужен?
    2. Регулировка оборотов при помощи биполярного NPN-транзистора
    2.1. Схема подключения кулера
    3. Регулировка оборотов при помощи МОП транзистора
    3.1. Схема подключения кулера
    3.2. N-канальные мосфеты с логическим управлением
    4. Как снять показания температуры процессора
    5. Активация кулера при указанной температуре
    5.1. Компиляция со сборкой и запуском программы
    6. ШИМ контроль - вариант I
    6.1. Компиляция со сборкой и запуском программы
    7. ШИМ контроль - вариант II
    7.1. Компиляция со сборкой и запуском программы
    8. Помещение программы в автозагрузку системы
    9. Проверка
    10. Удаление программы из автозагрузки системы


    1. Шим - что это и для чего нужен?


    Аббревиатура расшифровывается как широтно-импульсная модуляция (или PWM с английского - pulse-width modulation) - это процесс регулировки мощности способом пульсации включения и отключения прибора. ШИМ встречается в двоичном, троичном, а также аналоговом и цифровом видах. Главное предназначение ШИМ - увеличение КПД при построении источников питания электроники, в том числе и регулировка яркости подсветок различных экранов.

    2. Регулировка оборотов при помощи биполярного NPN-транзистора


    Первым делом ищем и устанавливаем подходящий биполярный NPN-транзистор. Кулер потребляет 200мА, поэтому нам нужен транзистор с коллекторным током больше 200мА с запасом в несколько крат. В зарубежных даташитах этот параметр обозначается как Ic, в отечественных Iк. Совместимы транзисторы: 2N2222A, 2N5550, 2N5551 и так далее. Сперва выясняем назначение выводов транзистора . Необходимо определить дислокацию его эмиттера, коллектора и базы. Самым простым способом будет проверка этого всего по справочнику или даташиту.

    2.1. Схема подключения кулера


    Транзистор подключаем по следующей схеме:



    Теперь при подаче «1» на вход схемы ток потечёт через резистор R1, затем базу и эмиттер на землю. В таком случае, транзистор откроется и ток пойдет через переход кoллeктор-эмиттeр, а следовательно и чeрeз нaгpyзкy (кулер).

    R1 - Peзистop занимающий ключевую роль, его назначение в ограничении тока чeрeз пepexoд бaзa-эмиттep. В случае его отсутствия ток не будет ограничен и испортит упpaвляющyю микpocxeму, поскольку она соединяет транзистop с линией питaния).

    Помимо этого, нельзя забывать, что нагрузка индуктивна и необходим зaщитный диoд (D1). Проблема в том, что энepгия, накопленная мaгнитным пoлем, не позволит моментально снизить ток до нyля при размыкании ключа. Из этого следует, что на кoнтaктax нaгpyзки появится напряжеeие обpaтной пoлярности, которое с легкостью может помешать работе контрoллера или даже испортить его.



    3. Регулировка оборотов при помощи мосфета


    Помимо биполярного, также есть возможность использовать и полевой транзистор, или как его иначе называют - МОСФЕТ, транзистор с изoлированным затвoром (также МОП или МДП). Их удобство заключается в том, что управление реализовано лишь напряжением - в случае, когда напряжение на затворе выше порогового значения, транзистор открывается. Пока транзистор открыт или закрыт, управляющий ток через него. У биполярных же транзисторов ток течёт всё время, пока открыт транзистор и в этом существенный недостаток перед полевыми транзисторами.

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

    3.1. Схема подключения кулера




    Внимание! Нагрузку подключать только «сверху» (к стоку). В противном случае схема не заработает. Причина заключается в том, что транзистор откроется, если напряжение превысит пороговое значение между затвором и истоком. Если подвести нагрузку снизу, она понизит напряжение, вследствие чего, транзистор не сумеет открыться полностью или частично.
    R2 - резистор (10 кОм), в неопределенном состоянии "стягивающий" потенциал к земле.
    R1 - резистор (100 Ом), ограничивающий ток заряда-разряда
    Помимо прочего не забываем, что нагрузка имеет индуктивность и необходим защитный диод (D1).



    3.2. N-канальные мосфеты с логическим управлением


    Недостаток мосфетов — пороговые напряжения затворов, превышающие 3.3 вольта. Однако, имеются вариации мосфетов и с логическим уровнем управления, такие как: IRL520NPBF, IRL2505, NTZD3155C FDN337N, 2N7000, ZVN4306A, и другие.

    4. Как снять показания температуры процессора


    Есть несколько вариантов получить мгновенную температуру процессора.
    В случае, если вы пользуетесь Armbian, используйте команду:

    armbianmonitor -m


    данная команда выдает частоту, длительность сеанса работы системы и температуру процессора с периодичностью в 6 секунд.
    Также существует вторая команда, возвращающая температуру процессора:

    cat /sys/devices/virtual/thermal/thermal_zone1/temp


    либо

    cat /sys/devices/virtual/thermal/thermal_zone0/temp


    либо

    cat /sys/class/thermal/thermal_zone0/temp


    Два термодатчика, находящиеся в процессоре (SoC) предоставляют значения, благодаря которым можно найти среднюю температуру.
    Чтобы узнать температуру процессора Raspberry Pi, воспользуйтесь консолью для ввода следующей команды:

    vcgencmd measure_temp


    Обратите внимание, что у Raspberry Pi температура представлена в миллиградусах и, чтобы получить целые градусы, необходимо разделить полученное значение на тысячу.

    5. Активация кулера при указанной температуре


    Ниже приведены способы, использующие WiringPi и требующие установки библиотек, которые можно установить по инструкциям, приведенным по ссылкам здесь: WiringPi, WiringOP, BPI-WiringPi.

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


    #include
    #include
    #include
    #include

    #define PIN 7

    #define TEMPERATURE_MIN 55

    using namespace std;

    static int getTemperature() {
    static fstream myfile;
    int temperature = 0;
    myfile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
    myfile >> temperature;
    myfile.close();
    return temperature;
    }

    int main() {
    int temperature;
    int pinState = 0;
    try {
    if (wiringPiSetup() == 0) {
    pinMode(PIN, OUTPUT);

    while (1) {
    temperature = getTemperature();

    if (temperature >= TEMPERATURE_MIN && pinState == 0) {
    digitalWrite(PIN, HIGH);
    pinState = 1;
    } else if (temperature < (TEMPERATURE_MIN - 10) && pinState == 1) {
    digitalWrite(PIN, LOW);
    pinState = 0;
    }

    usleep(1000 * 1000);
    }
    }
    } catch (exception& e) {
    cerr << e.what() << endl;
    }
    return 0;
    }



    Данный скрипт заработает так — при достижении порога температуры в 54 градуса активируется кулер, и остановится только когда температура упадет более чем на 10 градусов от верхней границы (44 градуса)

    Данные о температуре получены при помощи функции static int getTemperature(). Не забываем, что у Raspberry Pi температура исчисляется в миллиградусах, и для получения целых значений необходимо разделить искомое число на тысячу, а значит нужно внести пару изменений в код,
    вместо:

    static int getTemperature() {
    static fstream myfile;
    int temperature = 0;
    myfile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
    myfile >> temperature;
    myfile.close();
    return temperature;
    }



    пишем:


    static int getTemperature() {
    static fstream myfile;
    int temperature = 0;
    myfile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
    myfile >> temperature;
    myfile.close();
    return temperature / 1000;
    }



    5.1. Компиляция со сборкой и запуском программы


    Создаём файл FanPiOnOff.cpp и вставляем в него написанный выше код:

    nano FanPiOnOff.cpp


    Компилируем и собираем программу:

    g++ -Ofast -Wall FanPiOnOff.cpp -lwiringPi -lpthread -o FanPiOnOff


    Запускаем:

    ./FanPiOnOff


    на случай, если необходимо запускать программу в фоне:

    nohup ./FanPiOnOff &


    6. ШИМ контроль - вариант I


    Логика программы заключается во включении вентилятора (с определенным коэффициентом заполнения) при достижении заданных температур и отключении при падении ниже их.

    45 °C -> 35 %
    50 °C -> 50 %
    60 °C -> 75 %
    75 °C -> 100 %


    #include
    #include
    #include
    #include
    #include

    #define PIN 7
    #define RANGE 100

    #define PWM_VALUE1 35
    #define PWM_VALUE2 50
    #define PWM_VALUE3 75
    #define PWM_VALUE4 100

    #define TEMPERATURE_1 45
    #define TEMPERATURE_2 50
    #define TEMPERATURE_3 60
    #define TEMPERATURE_4 70

    using namespace std;

    static int getTemperature() {
    static fstream myfile;
    int temperature = 0;
    myfile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
    myfile >> temperature;
    myfile.close();
    return temperature;
    }

    int main() {
    int temperature;
    bool pwmStopped = true;

    try {
    if (wiringPiSetup() == 0) {
    while (1) {
    temperature = getTemperature();

    if (temperature > TEMPERATURE_4) {
    if (pwmStopped) {
    softPwmCreate(PIN, ((PWM_VALUE4 * RANGE) / 100), RANGE);
    pwmStopped = false;
    } else {
    softPwmWrite(PIN, ((PWM_VALUE4 * RANGE) / 100));
    }
    } else if (temperature > TEMPERATURE_3) {
    if (pwmStopped) {
    softPwmCreate(PIN, ((PWM_VALUE3 * RANGE) / 100), RANGE);
    pwmStopped = false;
    } else {
    softPwmWrite(PIN, ((PWM_VALUE3 * RANGE) / 100));
    }
    } else if (temperature > TEMPERATURE_2) {
    if (pwmStopped) {
    softPwmCreate(PIN, ((PWM_VALUE2 * RANGE) / 100), RANGE);
    pwmStopped = false;
    } else {
    softPwmWrite(PIN, ((PWM_VALUE2 * RANGE) / 100));
    }
    } else if (temperature > TEMPERATURE_1) {
    if (pwmStopped) {
    softPwmCreate(PIN, ((PWM_VALUE1 * RANGE) / 100), RANGE);
    pwmStopped = false;
    } else {
    softPwmWrite(PIN, ((PWM_VALUE1 * RANGE) / 100));
    }
    } else {
    softPwmStop(PIN);
    pwmStopped = true;
    }

    usleep(1000 * 1000);
    }
    }
    } catch (exception& e) {
    cerr << e.what() << endl;
    }
    return 0;
    }



    6.1. Компиляция со сборкой и запуском программы


    Создаём файл FanPiPWM.cpp и вставляем в него написанный выше код:

    nano FanPiPWM.cpp


    Компилируем и собираем программу:

    g++ -Ofast -Wall FanPiPWM.cpp -lwiringPi -lpthread -o FanPiPWM


    Запускаем:

    ./FanPiPWM


    на случай, если необходимо запускать программу в фоне:

    nohup ./FanPiPWM &


    7. ШИМ управление: Пример 2


    К тому же, есть возможность изменять коэффициент заполнения плавно. В этом случае для срабатывания вентилятора и коэффициента заполнения привязываем минимальные параметры, (допустим, 45 градусов и 35% соответственно), а к максимальной температуре (допустим, 70 градусов) привяжем коэффициент заполнения в 100%. Рассчитать коэффициент заполнения помогут функции static int map(int x, int inMin, int inMax, int outMin, int outMax);.


    #include
    #include
    #include
    #include
    #include

    #define PIN 7U

    #define RANGE_MAX 100
    #define RANGE_MIN 35

    #define TEMPERATURE_MAX 70
    #define TEMPERATURE_MIN 45

    using namespace std;

    static int getTemperature() {
    static fstream myfile;
    int temperature = 0;
    myfile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
    myfile >> temperature;
    myfile.close();
    return temperature;
    }

    static int map(int x, int inMin, int inMax, int outMin, int outMax) {
    if (x < inMin) {
    return outMin;
    } else if (x > inMax) {
    return outMax;
    }
    return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
    }

    int main() {
    int temperature;
    int pwmValue;
    bool pwmStopped = true;

    try {
    if (wiringPiSetup() == 0) {
    while (1) {
    temperature = getTemperature();
    pwmValue = map(temperature, TEMPERATURE_MIN, TEMPERATURE_MAX, RANGE_MIN, RANGE_MAX);

    if (temperature >= TEMPERATURE_MIN && pwmStopped) {
    softPwmCreate(PIN, pwmValue, RANGE_MAX);
    pwmStopped = false;
    } else if (temperature >= (TEMPERATURE_MIN - 5) && !pwmStopped) {
    softPwmWrite(PIN, pwmValue);
    } else {
    if (!pwmStopped) {
    softPwmStop(PIN);
    }
    pwmStopped = true;
    }

    usleep(1000 * 1000);
    }
    }
    } catch (exception& e) {
    cerr << e.what() << endl;
    }
    return 0;
    }



    7.1. Компиляция со сборкой и запуском программы


    Создаём файл FanPiPwmLinear.cpp и вставляем в него написанный выше код:

    nano FanPiPwmLinear.cpp


    Компилируем и собираем программу:

    g++ -Ofast -Wall FanPiPwmLinear.cpp -lwiringPi -lpthread -o FanPiPwmLinear


    Запускаем:

    ./FanPiPwmLinear


    на случай, если необходимо запускать программу в фоне:

    nohup ./FanPiPwmLinear &


    8. Помещение программы в автозагрузку системы


    Осталось лишь автоматизировать запуск созданной нами программы, отвечающей за регулировку оборотов кулера, при старте системы.
    Для этого нужно в конец файла /etc/rc.local:

    sudo nano /etc/rc.local


    Поместить команду старта скрипта перед строкой exit 0:

    sudo ./home/pi/FanPiPwmLinear &


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

    ps aux | grep -i FanPiPwmLinear


    9. Проверка


    Для того, чтобы проверить функциональность программы, необходимо нагрузить процессор, чтобы его температура поднялась до нужной отметки и убедиться в реакции кулера на это событие. Разогреть процессор помогут приложения вроде sysbench или stress. Их можно установить с aptitude:

    sudo apt-get install sysbench


    либо

    sudo apt-get install stress


    Запуск приложения с использованием четырех ядер:

    sysbench --num-threads=4 --test=cpu --cpu-max-prime=20000 --validate run


    либо

    sudo stress --cpu 4 --timeout 30s


    При работе данных утилит температура процессора начнет расти.
    Принудительное завершение работ, как утилиты sysbench, так и stress можно при помощи сочетания клавиш Ctrl+C.

    10. Удаление программы из автозагрузки системы


    Для того, чтобы удалить программу из автозагрузки, необходимо всего лишь удалить строчку с запуском программы из файла /etc/rc.local.

    29.06.2019 в 15:03, Просмотров: 902

    шим, охлаждение, кулер

    Короткая ссылка: http://4raspberrypi.ru/content.php?p=42

    ID: 42