<-- назад

Решим еще одну Специальную задачу управления


Рассмотрим ЗАДАЧУ, в которой
надо построить систему измерения скорости вращения (об/мин) двигателя, вентилятора или скорости движения(м/сек) эскалатора, транспортера и т.д.

Для решения этой задачи ЗДЕСЬ предлагается довольно разработанная схема устройства, построенного на базе ДАТЧИКА ЛИНИИ.

Светодиод излучает в инфракрасном диапазоне на длине волны 950 нм. Свет отражается от поверхности, куда направлен, и попадает на фототранзистор.

Если свет отражается от светлой поверхности - на фототранзисторе высокое напряжение, если свет отражается от темной поверхности - на фототранзисторе низкое напряжение.
На датчике установлен сигнальный светодиод, который загорается, когда датчик находится над светлой поверхностью.

Вот на этом датчике мы построим нужный нам измеритель скорости вращения - cоберем цепь-проект-схему:

Теперь напишем следующую программу (читайте внимательно комментарии):
  const uint8_t  pinLine = A0;  //  пин сигнала от датчика
  uint32_t   strLine = 0; //время перехода датчика 
                   // со Светлого на Темное поле
  void setup(){
    Serial.begin(9600);  
    pinMode(9, OUTPUT); // ШИМ выход <Ардуино>
  }
 
  void loop(){ int n;  n = Serial.read();//запуск и управление мотором - 
   //задаем разные напряжения на пин 9 - разная скорость вращения
      if (n=='1'){analogWrite(9, 255); }  // 5v
      if (n=='2'){analogWrite(9, 130); }  // 2.5v
      if (n=='0'){analogWrite(9,  0); }     // 0v  стоп
  if(analogRead(pinLine)>400){ // если показания датчика >400 (темное поле) 
      if(strLine350) {                        
     //  ждем пока датчик не выйдет из темного поля
      if((millis()-strLine)>6000){Serial.println("STOP B");}  
      //  если датчик находится в темном поле более 6 секунд, 
      // т.е. мотор СТОИТ, то выводим на экран "STOP B"
     }
    } if((millis()-strLine)>6000){Serial.println("STOP W");}  
       //  если датчик находится в светлом поле более 6 секунд, 
       // то выводим на экран "STOP W"
   } //end 
В качестве мотора взят маленький вентилятор. При подаче на этот двигатель разных напряжений с выхода ШИМ-пина 9, получаем разные скорости:


отправляем с монитор-порта компьютера единицу (1) - получаем скорость 1111 (об/мин)


отправляем с монитор-порта компьютера двойку (2) - получаем скорость 338 (об/мин)


Можно рассмотреть ЕЩЁ один вариант этой задачи - вывод показаний датчика скорости вращения и показания датчика температуры на ЖК дисплей.
Соберем уже известную схему, дополнив её подключением датчика температуры:

И напишем следующую программу:
#include  //Подключим библиотеку для работы с дисплеем  
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7) 
//подключаем дисплей как на рис.

const uint8_t  pinLine = A0; //  подключаем датчик к А0
uint32_t strLine = 0; //переменная для хранения времени периода;
//в момент появления под датчиком ТЕМНОГО поля - датчик выдает импульс >400, а при
//появлении СВЕТЛОГО поля импульс исчезает -> на выходе датчика 0; 
//время между двумя импульсами - период Т

void setup(){
    Serial.begin(9600);  
    pinMode(9, OUTPUT);
    lcd.begin(16, 2); //Задаем размерность экрана (16 символов, 2 строки) 
 }
 
void loop(){
    int n;  
n = Serial.read(); //пуск и управление мотором
if (n=='1'){analogWrite(9, 255); } // напряжение на моторе =< 5 В
if (n=='2'){analogWrite(9, 130); } // напряжение на моторе =< 2.5 В
if (n=='3'){analogWrite(9, 0); }

    if(analogRead(pinLine)>400){ // если появляется импульс на выходе датчика  
      if(strLine < millis()){ // и если нет переполнения счетчика millis(), то...
      // выводим кол об/мин на дисплей -> n=60/T 
     lcd.setCursor(1, 0); //Устанавливаем курсор в начало 1й строки 
     lcd.print("n(r/min):");  
     lcd.setCursor(10, 0); //Устанавливаем курсор в 11й знак, 1й строки 
     lcd.print(60000/(millis()-strLine)); // n=60/T на дисплее 
     Serial.println(60000/(millis()-strLine)); //n=60/T на мониторе
   } strLine = millis(); //присваиваем переменной strLine 
                         // текущее значение millis() и снова определяем Т
    while(analogRead(pinLine)>350){                        
 //если мотор не движется, под датчиком может быть либо темное либо светлое поле
          if((millis()-strLine)>6000){lcd.setCursor(1, 0);lcd.print("STOP B        ");} 
      //  если под датчиком ТЕМНОЕ поле более 6 секунд, 
      // то выводим на экран "STOP B"
    }
  }   
      if((millis()-strLine)>6000){lcd.setCursor(1, 0);lcd.print("STOP W        ");}
       //  если под датчиком СВЕТЛОЕ поле более 6 секунд, 
       // то выводим на экран "STOP W"

 // показания датчика температуры
  lcd.setCursor(3, 1);
  // считываем показания с датчика температуры на пине А2
  int sensorADC1 = analogRead(A2);
  // переводим значения с АЦП в вольты
  float sensorVoltage = sensorADC1 * (5.0 / 1023.0);
  // переводим вольты в градусы цельсия
  int temperature = (sensorVoltage - 0.5) * 45;
  // выводим результат на дисплей
  lcd.print("Temp=");
  lcd.print(temperature);
  lcd.print("\x99""C"); //над строкой\х значок 99 градуса
  }
Если запустить эту программу в собранной установке, то на дисплее увидим:


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



<-- назад