Как постепенно увеличивать и уменьшать скорость двигателя с помощью ИК-пульта дистанционного управления

Я создаю вертолет с ИК-управлением, и у меня есть самая основная часть кода, но я не знаю, как заставить двигатель постепенно увеличивать скорость. Я хочу, чтобы двигатель постепенно увеличивал скорость, когда вы удерживаете кнопку на ИК-пульте дистанционного управления, и удерживал ее скорость, когда вы перестаете нажимать кнопку. И то же самое, когда вертолет падает. Вот код:

   #include <IRremote.h>
   #include <Servo.h>
   #define enA 9
   #define enB 11
   #define in1 6
   #define in2 7
   #define in3 4
   #define in4 5

   Servo ball1;

   int IR_RECEIVE_PIN = 2;
   IRrecv IrReceiver(IR_RECEIVE_PIN);
   decode_results results;

   void setup() {
     Serial.begin(9600);
     IrReceiver.enableIRIn();

     ball1.attach(10);

     pinMode(in1, OUTPUT);
     pinMode(in2, OUTPUT);
     pinMode(in3, OUTPUT);
     pinMode(in4, OUTPUT);
   }
   void loop() {
     if (IrReceiver.decode(&results)) {
       switch (results.value) {

         case 0xFFA857:
           Serial.println("case: UP");
           digitalWrite(enA, 255);
           digitalWrite(in1, HIGH);
           digitalWrite(in2, LOW);
           break;

         case 0xFFE01F:
           Serial.println("case: DOWN");
           digitalWrite(enA, 120);
           digitalWrite(in1, LOW);
           digitalWrite(in2, LOW);
           break;

         case 0xFF18E7:
           Serial.println("case: FORWARD");
           ball1.write(90);
           break;

         case 0xFF10EF:
           Serial.println("case: LEFT");
           digitalWrite(in3, LOW);
           digitalWrite(in4, LOW);
           break;

         case 0xFF5AA5:
           Serial.println("case: RIGHT");
           digitalWrite(in3, HIGH);
           digitalWrite(in4, LOW);
           break;

         case 0xFF48B5:
           Serial.println("case: BACKWARD");
           ball1.write( ? ); // I need help on the direction of the linear servo
           break;
       }

       Serial.println(results.value, HEX);
       IrReceiver.resume();
     }
   }

Это тот же код, который я использовал для управления светодиодом RGB (но модифицированным). Можно ли загрузить этот код в IC? Я уже запрограммировал UNO как ISP, но, похоже, возникла проблема. Кроме того, я использую линейный сервопривод для шага вертолета, может кто-нибудь, пожалуйста, показать мне, как изменить направление линейного сервопривода? У меня есть один, похожий на линейный сервопривод Pico.

, 👍1

Обсуждение

Должен ли каждый оператор "case" иметь соответствующий оператор " break`?, @tim

Да, я удалил их, когда пытался что-то сделать, но теперь я добавил их обратно... Спасибо!, @Renier Jr.

Правильное отступление вашего кода значительно облегчит его выполнение., @StarCat

Хорошо, я сделал отступ..., @Renier Jr.

Каждый раз, когда вы получаете код "вверх", увеличивайте скорость. Каждый раз, когда вы получаете код "вниз", уменьшайте скорость. IR (обычно) не имеет понятия "нажать" и "отпустить", только "нажать", и он повторно отправляет код во время нажатия., @Majenko

Mhh, обычно вы не видите модели полета с ИК-управлением, потому что они слишком ненадежны и не будут работать под прямыми солнечными лучами (потому что инфракрасный свет от солнца уже насыщает датчик, так что он не может видеть сигнал от отправителя). Вы уверены, что хотите использовать ИК-излучение? Хороший радиочастотный отправитель и приемник (как и в других моделях полетов) обычно намного лучше, @chrisl

Привет, крисл, спасибо тебе! Я посмотрю, смогу ли я получить радиочастотный отправитель и приемник... Я использовал ИК, потому что это все, что у меня есть сейчас, но я рассмотрю вашу идею. Еще раз спасибо!, @Renier Jr.


1 ответ


Лучший ответ:

0

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

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

void loop() {

  if (IrReceiver.decode(&results)) {

    switch (results.value) {

      case 0xFFA857: // вверх
        verticalSpeed = verticalSpeed + verticalSpeedStep;
        if (verticalSpeed > maxVerticalSpeed) verticalSpeed = maxVerticalSpeed;
        setVericalMotor();
        break;

      case 0xFFE01F: //вниз
        verticalSpeed = verticalSpeed - verticalSpeedStep;
        if (verticalSpeed < 0) verticalSpeed = 0;
        setVericalMotor();
        break;

    }
  }
}

void setVericalMotor() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, verticalSpeed);
}

Что касается вашего вопроса относительно сервопривода, они обычно работают от 0 до 180 градусов, поэтому используйте что-либо в этом диапазоне в качестве "обратного" для 90 градусов вперед (обычно это должно быть 0 или 180).

,

Спасибо вам за помощь!!, @Renier Jr.

Я раньше не работал с verticalSpeed, и компилятор говорит, что он не объявлен в области видимости вместе с verticalSpeedStep и maxVerticalSpeed... Не могли бы вы, пожалуйста, помочь мне?, @Renier Jr.

Код, который я вам показал, не является полной программой, это просто идея о том, как разработать вашу программу, и как ее часть вы должны объявить переменные. Поскольку вы новичок в программировании, я предлагаю вам следовать одному из многих руководств по началу работы с Arduino, которые вы можете найти на arduino.cc и многие другие сайты., @Nino

Хорошо, спасибо тебе!, @Renier Jr.