Управление скоростью вращения вентилятора?

Тема в разделе "Arduino & Shields", создана пользователем ArtSmm, 24 авг 2016.

  1. ArtSmm

    ArtSmm Нерд

    Решил сделать управление вентилятором, в зависимости от уровня влажности в помещении.
    Основной код я написал.

    Пока вентилятор просто включается и выключается, при достижении уровня влажности.
    Если верно понимаю, скоростью вращения можно управлять через ШИМ порт на плате, например 9.

    Правильно ли мыслю:
    сначала ставим pinMode(9, OUTPUT) ? те конфигурируем, порт как выход,
    затем, чтобы скорость увеличивалась от уровня влажности, надо написать что-то вроде?

    if (h > 45) {
    analogWrite(9, 125);
    }

    например.
    Плюс от вентилятора я втыкал в 9 пин соотв

    и так далее, пока вентилятор не достигнет 100% скорости?
    Плюс, надо ли что-то дополнительно ставить, чтобы управлять скоростью вращения?



    //Сам код:

    #include <DHT.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x3F, 16, 2);

    int Relay = 3; //Реле

    int hum;
    int humMin = 38; //мин влажность для начала вращения вентилятора
    int humMax = 70; //максимальная влажность, когда вентилятор вращается на 100%
    int fanSpeed;
    int fanLCD;

    #define DHTPIN 4 //Порт для подключения датчика влажности
    #define DHTTYPE DHT11 // Задаем датчик DHT 11

    DHT dht(DHTPIN, DHTTYPE);

    void setup() {

    Serial.begin(9600);
    Serial.println("DHTxx test!");

    dht.begin();

    lcd.init();
    lcd.backlight();

    pinMode(Relay, OUTPUT);

    }
    void loop() {

    delay(2000); //пауза для определения датчика
    float h = dht.readHumidity(); //читаем данные влажности с датчика
    float t = dht.readTemperature(); //читаем температуру

    hum = h;

    //На случай ошибки в данных, считываем еще раз
    if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;

    }

    if ((hum >= humMin) && (hum <= humMax)) {
    fanSpeed = map(hum, humMin, humMax, 32, 255); //текущая скорость вращения ввентилятора
    fanLCD = map(hum, humMin, humMax, 0, 100); //скорость вращения для отображения на LCD
    }

    //Выводим значения на экран I2C

    lcd.setCursor(0, 0);
    lcd.print("Hum:");
    lcd.setCursor(5, 0);
    lcd.print(h);
    lcd.setCursor(10, 0);
    lcd.print("%");
    lcd.setCursor(0, 1);
    lcd.print("Temp:");
    lcd.setCursor(5, 1);
    lcd.print(t);
    lcd.setCursor(10, 1);
    lcd.print("C");
    lcd.setCursor(12, 0);
    lcd.print("S");
    lcd.setCursor(13, 0);
    lcd.print(fanLCD);

    delay(1000);

    //Влажность больше 40, то включаем вентилятор

    if (h > 40) {
    digitalWrite(Relay, LOW);
    }

    else
    digitalWrite(Relay, HIGH);

    }
     
  2. vvr

    vvr Инженерище

    если у вас вентилятор - мотор постоянного тока , то управляете его скоростью или через транзистор или через драйвер
     
  3. ArtSmm

    ArtSmm Нерд

    Хорошо, попробую
     
  4. vvr

    vvr Инженерище

    ну и от делея нужно избавиться, а то он будет тормозить вашу программу
     
  5. fogary

    fogary Гик

    Вы хотите управлять скоростью вентилятора, даже вычисляете значение для этого, но никак не применяете, а сам вентилятор тупо включаете и выключаете с помощью реле.
     
  6. ArtSmm

    ArtSmm Нерд

    Это я уже понял, поэтому и задавал вопрос про необходимость использования других элементов. Человек подсказал, что транзистор нужен
     
  7. fogary

    fogary Гик

    Понятно, думал Вы забыли код изменить.
     
  8. ArtSmm

    ArtSmm Нерд

    Спасибо
     
  9. yul-i-an

    yul-i-an Гик

    Если необходимо поддерживать влажность, то нужен регулятор (П, ПИ или ПИД). Тогда Вам просто нужно будет задать влажность, а регулятор в зависимости от разницы задания и текущего значения будет регулировать производительность регулятора.
    Самый простой П-регулятор, но у него всегда будет статическая ошибка, что в Вашем случае наверное не критично.
    скорость = (задание-текущее значение)*коэффициент пропорциональности
    Коэффициент пропорциональности подбирается экспериментально, для достижения минимальной ошибки регулирования и не допущения раскачивания системы.

    Вот например ПИ регулятор
     
  10. ArtSmm

    ArtSmm Нерд

    Спасибо за пояснение. Наваял код для управления вентилятором, но похоже для увеличения скорости не хватает мощности порта. Вентилятор с 3 пинами, на 12в расчитан.
    Питание подключил к + макетной платы, минус к gnd соотв, а 3 пин к 9 порту, его выставил как выходной. В порте только 5в. Как можно увеличивать мощность в данном случае, за счет чего?

    #include <OLED_I2C.h>
    #include <DHT.h>
    #include <Wire.h>

    OLED myOLED(SDA, SCL, 8); //Задаем дисплей

    extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русских символов.

    int Relay = 3; //Реле

    //Программа

    int hum; //Переменная влажности

    int fan_pin = 9; //9 ШИМ для вентилятора
    int fanSpeed = 5; //Переменная отвечает за скорость вращения

    #define DHTPIN 4 //Порт для подключения датчика влажности
    #define DHTTYPE DHT11 // Задаем датчик DHT 11

    DHT dht(DHTPIN, DHTTYPE);

    void setup() {

    //код дисплея

    myOLED.begin();
    myOLED.setFont(SmallFont);

    //-------------
    Serial.begin(9600);

    dht.begin();

    pinMode(Relay, OUTPUT); //Реле

    //Ставим pin вентилятора, как выходной
    pinMode(fan_pin, OUTPUT);

    }
    void loop() {

    delay(2000); //пауза для определения датчика
    float h = dht.readHumidity(); //читаем данные влажности с датчика
    float t = dht.readTemperature(); //читаем температуру

    hum = h;

    //На случай ошибки в данных, считываем еще раз
    if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;

    }
    //Влажность больше 30, то включаем вентилятор

    if (h > 30) {
    digitalWrite(Relay, LOW);
    }
    else
    digitalWrite(Relay, HIGH);

    //Скорость вращения вентилятора
    fanSpeed = map(h, 0, 1023, 0, 255);
    if (h > 25) {
    analogWrite(fan_pin, 64);
    }

    if (h > 35) {
    analogWrite(fan_pin, 127);
    }

    if (h > 60) {
    analogWrite(fan_pin, 255);
    }

    delay(50);

    //Текст на дисплее
    myOLED.clrScr();
    myOLED.print("Dannie:", LEFT, 0);
    myOLED.print("HUM:", CENTER, 14);
    myOLED.print(String(h, 1), CENTER, 26);
    myOLED.print("TEMP:", CENTER, 38);
    myOLED.print(String(t, 1), CENTER, 54);
    myOLED.update();
    delay (5000);

    //---------------
    }
     
  11. Developer-RU

    Developer-RU Гик

    Не. всё удали нафиг.
    Во первый делай надо убрать, темпратура и влажность измеряется не моментально, соответственно:
    управление вентилятором вынеси в attachinterupt в которой будет проверяться глобальная переменная и по ней уже или шимом или как там захочешь выставляй скорость.
    а в основном цикле программы неспеша мерий темпиратуру влажность, выводи на дисплей, отправляй там смс или еще что И НАЗНАЧАЙ ТОЙ САМОЙ ГЛОБАЛЬНОЙ ПЕРЕМЕННОЙ СКОРОСТЬ ВРАЩЕНИЯ.

    и будет у тебя всё нормально работать...
     
  12. fogary

    fogary Гик

    Значение переменной h не нужно замапить в диапазон 0-100? Не хотите поменять порядок проверки влажности от большего к меньшему?
     
  13. ArtSmm

    ArtSmm Нерд

    Возможно. Переделал код:

    Код (C++):
    #include <OLED_I2C.h>
    #include <DHT.h>
    #include <Wire.h>

    OLED  myOLED(SDA, SCL, 8); //Задаем дисплей

    extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русских символов.

    //Программа

    int Relay = 3; //Реле
    int led = 10; //Выход на зеленый светодиод
    int led2 = 11; //Выход на красный светодиод
    int fan_pin = 9; //9 ШИМ для вентилятора
    int hum; //Переменная температуры
    int humMin = 30; //влажность для начала вращения вентилятора
    int humMax = 70; //максимальная влажность при которой вентилятор вращается на 100%
    int fanSpeed;

    #define DHTPIN 4 //Порт для подключения датчика влажности
    #define DHTTYPE DHT11   // Задаем датчик DHT 11

    DHT dht(DHTPIN, DHTTYPE);

    void setup() {

      //код дисплея

      myOLED.begin();
      myOLED.setFont(SmallFont);

      //-------------
      Serial.begin(9600);

      dht.begin();
     
      pinMode(Relay, OUTPUT); //Реле
      //Ставим pin вентилятора, как выходной
      pinMode(fan_pin, OUTPUT);
      pinMode(led, OUTPUT);
      pinMode(led2, OUTPUT);

    }
    void loop() {

      delay(2000); //пауза для определения датчика
      float h = dht.readHumidity(); //читаем данные влажности с датчика
      float t = dht.readTemperature(); //читаем температуру

      h = hum;
      hum = dht.readHumidity();
      if(hum < humMin) {
        fanSpeed = 0;
        digitalWrite(Relay, HIGH);
      }

      //На случай ошибки в данных, считываем еще раз
      if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
        return;

      }
      if((hum >= humMin) && (hum <= humMax)) { //если влажность больше минимума
        fanSpeed = map(hum, humMin, humMax, 32, 255); //текущая скорость вращения
        analogWrite(fan_pin, fanSpeed); //вращаем вентилятор со скоростью fanSpeed
      }
      if((hum >= humMin) && (hum <= humMax)) {
        digitalWrite(led, HIGH); //если влажность в диапазоне, включаем 1 диод
      } else {
        digitalWrite(led, LOW);
      }
      if(hum > humMax) { //если влажность > максимума
        digitalWrite(led2, HIGH); //включаем 2 светодиод  
      } else {
        digitalWrite(led2, LOW); //иначе выключаем
      }

      //Текст на дисплее
      myOLED.clrScr();
      myOLED.print("Dannie:", LEFT, 0);
      myOLED.print("HUM:", CENTER, 14);
      myOLED.print(String(h, 1), CENTER, 26);
      myOLED.print("TEMP:", CENTER, 38);
      myOLED.print(String(t, 1), CENTER, 54);
      myOLED.update();
      delay (5000);

      //---------------
    }
     
    Последнее редактирование: 2 сен 2016
  14. ArtSmm

    ArtSmm Нерд

    Если я верно понимаю, скорость вращения увеличивается за счет напряжения, а напряжение надо увеличивать до 12в
     
  15. ostrov

    ostrov Гуру

    Когда уже научитесь тэгами пользоваться?
     
  16. Tomasina

    Tomasina Сушитель лампочек Модератор

    тебе же еще во втором сообщении написали:
    а ты подключаешь вентилятор (=мотор) напрямую. Странно что порт еще не погорел от перегрузки.
    http://www.pighixxx.com/test/portfolio-items/connect-a-computer-fan-3-wires/
    http://www.pighixxx.com/test/portfolio-items/connect-a-dc-motor/
     
    Developer-RU нравится это.
  17. ArtSmm

    ArtSmm Нерд

  18. yul-i-an

    yul-i-an Гик

    Некоторые изменения для упрощения кода и экономии памяти (не принимать как руководство к действию, просто пример как можно код подправить), не проверял.
    Код (C++):
    #include <OLED_I2C.h>
    #include <DHT.h>
    #include <Wire.h>

    OLED  myOLED(SDA, SCL, 8); //Задаем дисплей
    extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русских символов.

    //Программа
    #define Relay 3 //Реле
    #define led 10 //Выход на зеленый светодиод
    #define led2 11 //Выход на красный светодиод
    #define fan_pin 9 //9 ШИМ для вентилятора
    #define humMin 30 //влажность для начала вращения вентилятора
    #define humMax 70 //максимальная влажность при которой вентилятор вращается на 100%
    #define minFanSpeed 32//минимальная скорость вращения
    #define maxFanSpeed 255//максимальная скорость вращения
    #define DHTPIN 4 //Порт для подключения датчика влажности
    #define DHTTYPE DHT11   // Задаем датчик DHT 11
    DHT dht(DHTPIN, DHTTYPE);
    byte fanSpeed=0;//Переменная скорости
    int hum=0; //Переменная влажности

    void setup() {

      //код дисплея
      myOLED.begin();
      myOLED.setFont(SmallFont);

      //-------------
      Serial.begin(9600);
      dht.begin();
       pinMode(Relay, OUTPUT); //Реле
      //Ставим pin вентилятора, как выходной
      pinMode(fan_pin, OUTPUT);
      pinMode(led, OUTPUT);
      pinMode(led2, OUTPUT);

    }
    void loop() {
      if(millis()>2000){//delay(2000); //пауза для определения датчика
      float h = dht.readHumidity(); //читаем данные влажности с датчика
      float t = dht.readTemperature(); //читаем температуру
      }

      h = hum;
      hum = dht.readHumidity();

      if(hum < humMin) {
        fanSpeed = 0;
        digitalWrite(Relay, HIGH);
      }

      //На случай ошибки в данных, считываем еще раз
      if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
        return;

      }

      if((hum >= humMin) && (hum <= humMax)) { //если влажность больше минимума
        fanSpeed = map(hum, humMin, humMax, minFanSpeed, maxFanSpeed); //текущая скорость вращения
        analogWrite(fan_pin, fanSpeed); //вращаем вентилятор со скоростью fanSpeed
      }
      digitalWrite(led,((hum >= humMin) && (hum <= humMax))?HIGH:LOW);
      digitalWrite(led2,(hum>humMax)?HIGH:LOW);

      //Текст на дисплее
      myOLED.clrScr();
      myOLED.print("Dannie:", LEFT, 0);
      myOLED.print("HUM:", CENTER, 14);
      myOLED.print(String(h, 1), CENTER, 26);
      myOLED.print("TEMP:", CENTER, 38);
      myOLED.print(String(t, 1), CENTER, 54);
      myOLED.update();
      delay (5000);

      //---------------

    }
    И от delay избавится надо.
     
  19. ArtSmm

    ArtSmm Нерд

    Спасибо за подробный ответ:)