Цикл поворотов Servo (Влево-Вправо) на заданной скорости

Тема в разделе "Arduino & Shields", создана пользователем Otto, 23 дек 2016.

  1. Otto

    Otto Нерд

    Конструкция такова: переделал напольный дешёвый вентилятор. Работает через ИК пульт. На вентиляторе можно с пульта включить/переключить любой из 3-х режимов скорости + поставить на каждый режим скорости таймер через который отключится вентилятор. В вентиляторе переделал системы поворотов и теперь можно так же с пульта через Servo-привод поворачивать вентилятор влево-вправо (при зажатии на пульте кнопуки - осуществляется поворот в нужную сторону).

    Всё работает достаточно хорошо. Вот только в ступор ввела простая мысль. Хочу ещё добавить автоповороты вентилятора (влево-вправо) при коротком нажатии одной кнопки (с небольшой скоростью, что бы происходили плавные повороты) и отключение данного режима при нажатии другой кнопки.

    Помогите пожалуйста сделать часть кода ручного управления серво с небольшой плавной скоростью. Так же может кому пригодятся мои наработки с вентилятором, код так же выложу, получилось в реале классно!

    вот часть кода отвечающая за вращения серво при нажатии кнопок:
    Код (C++):
    #include <Servo.h>      //библиотека для Servo
    #include <IRremote.h>   // библиотека IRremote для ИК пульта

    int RECV_PIN = 11; //вход ИК инфракрасного приемника
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    Servo servoPovorot; //даём имя servo

    // переменные для контроля за процессом поворотов Servo
    bool Right_Pin_1 = false;
    bool Left_Pin_1  = false;


    /* Переменная для плавного вращения servo,чтобы не использовать delay.
    промежуточная переменная для хранения (увеличенного диапазона от 0 до 20000)значений (увеличения или уменьшения)PWM,
    с последующей конвертации в переменную(val_1) диапазон градусов поворота доступных для servo.*/

    int L = 0;

    //переменная для конвертации (увеличенного диапазона значений от 0 до 20000) (L),в значения требуемые для поворота servo.
    int val_1;

    //переменная для (увеличения или уменьшения)скорости поворота servo.
    int speed_PWM = 1;

    //переменная eventTime, для паузы, вместо delay,будем использовать функцию millis.
    unsigned long eventTime = 0;


    void setup() {            
      irrecv.enableIRIn(); // включить ИК приёмник
      servoPovorot.attach(9); // серво подключён на цифровой вход (pin 9)
    }

    void loop() {
       /* Делаем, что бы система работала в режиме удержания кнопки для Серво.
      После приёма определённого кода кнопки,сразу перехватывать идущий за ним (кодом), (пустой инфракрасный сигнал)
      и считать его - (пустой инфракрасный сигнал), за код кнопки.
      После пропадания (пустого инфракрасного сигнала) - будем считать, что код перестал слаться.*/


      /* 1. После приёма определённого кода кнопки, перехватывать (пустой инфракрасный сигнал).
         2. Конвертировать пульсирующий (-) с (ИК) преемника сигнал в постоянный.
      После появления и пропадания сигнала, состояние сразу не меняется! а ждет  100 миллисекунд.
      Если 100 миллисекунд не прошло, и поступил еще один ИК сигнал с пульта,
      тогда таймер заново запускается на 100 миллисекунд.*/

     
      if (digitalRead(RECV_PIN) == LOW)    
        eventTime=millis();
      if(millis()-eventTime>100) (Right_Pin_1 = false),(Left_Pin_1 = false);


      /* Если Right_Pin_1) ==, выставляем ограничение для переменной(L) до (&& L<30000) и начинаем увеличивать
      значения переменной(L), на значение переменной speed_PWM,
      и также выставляем ограничение при убывании (&& a>0).*/

      if(Right_Pin_1 == true && L<20000  ) L=L+speed_PWM;
      if(Left_Pin_1  == true && L>0  ) L=L-speed_PWM;


      //читаем значение (L) и конвертируем его в значение val_1, то бишь в значение поворота в градусов доступных для servo.
      val_1 = L;          
      val_1 = map(val_1, 0, 20000, 1, 130);     // (углы поворота от 1 до 130 градусов)
      servoPovorot.write(val_1);                // Положение Серво в соответствии с val_1.


    // 2 Команды с пульта отвечающие за ручные повороты Серво.
      if(results.value == 0xFFC23D) Right_Pin_1  = true;   // Поворот Вправо
      if(results.value == 0xFF22DD) Left_Pin_1   = true;   // Поворот Влуво


        irrecv.resume();
      }
    }
    Полный рабочий код для вентилятора во вложении.

    Во всём коде не используется delay(), т.к. при его использовании всё может стать клином...
     

    Вложения: