кнопка переключения режимов

Тема в разделе "Arduino & Shields", создана пользователем Иropь, 5 июн 2016.

  1. Иropь

    Иropь Нерд

    Добрый день имеем скетч для для управления пятью шаговыми двигателями при помощи пульта ДУ , но так как для пяти двигателей надо 10 кнопок пульта, хочу немного разгрузить пульт и переключаться между двигателями или одной кнопкой по кругу,или назначить на пульте кнопки, 0т 1 до 5 ,по числу двигателей,а кнопками + и - управлять вращением выбранного двигателя, но что то не пойму как это осуществить , ибо конструкция switch case уже есть?
     

    Вложения:

  2. Tomasina

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

    нарисуй на бумажке алгоритм и поймешь, что это даже проще чем 10 кнопок.
     
    Иropь нравится это.
  3. Иropь

    Иropь Нерд

    Да вот как раз не могу сообразить как будет выглядеть сама конструкция скетча, так бы саму программу написать было бы гораздо проще...
     
  4. joman

    joman Гик

    Я бы написал примерно так:
    Код (C++):
    #define SWITCH_PIN 10
    #define MOVE_PIN 11
    byte DvigNum = 0; // Номер двигателя

    void setup() {
      // Инициализация
    }

    void loop() {
      if(digitalRead(SWITCH_PIN)){
        DvigNum = (DvigNum + 1) % 5 ;
      }
      if(digitalRead(MOVE_PIN)){
        switch (DvigNum){
          case 0:
            //крутим двигатель 1
            break;
          case 1:
            //крутим двигатель 2
            break;
          // тут описываем остальные двигатели
          default:
            // какая то непонятка, сюда мы не должны попасть
          break;
        }
      }
    }
     
    Иropь нравится это.
  5. Tomasina

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

    не надо себя привязывать ни к конструкции скетча, ни к синтаксису языка C++, эти ограничения тебя только тормозят.
    Нужен пошаговый алгоритм (текстовый, графический - неважно): если нажата кнопка "1" - делаем что? проверяем какое условие? Цель - "вслепую" запустить двигатель, не привязываясь к операторям языка
    После этого структура в коде сама всплывет.
     
    Иropь нравится это.
  6. Иropь

    Иropь Нерд

    Я больше склоняюсь к покнопочному алгоритму,нажал кнопку 1 крутим двиг 1 , нажал кнопку 2 , крутим двиг 2, и т.д. чтобы было точно понятно без доп индикации какой двиг крутим, хотя большой разницы с одной кнопкой нет, я так понимаю кнопкой 1 мы включаем двиг 1, но он не крутится на выходах пинов все нули, нужно включить его второй раз чтобы начал крутится кнопкой + или - , в зависимости от направления....а вот как его включить второй раз не пойму никак...
     
  7. Tomasina

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

    ну ё-мое... Тебя сейчас не должно волновать что там на пинах.

    Проблема: НЕТ ЖЕСТКО ПРОПИСАННОЙ ЛОГИКИ ПОВЕДЕНИЯ.

    Ибо даже сейчас получается две возможных ветки поведения:
    1. Кнопки 1-5 включают/выключают конкретные движки, кнопки "+/-" изменяют только направление движения последнего выбранного движка. Последовательность нажатия кнопок неважна.
    2. Кнопки 1-5 выбирают текущий движок, но не управляют им, кнопки "+/-" стопорят/стартуют текущий движок в нужном направлении.
    Причем в обеих вариантах даже не учтена обработка нештатных ситуаций (при полном вращении вперед двигло врубили назад, без паузы на остановку) - это проблемы оператора или программы? Ибо нет алгоритма.

    Вот поэтому и нужен точный алгоритм поведения. Не состояние пинов, не вопросы "включить его второй раз". Нет МК, нет проводов, нет пинов. Есть только 7 кнопок и 5 движков. Нужна четко прописанная последовательность шагов для запуска движка.
     
  8. Tomasina

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

    чем управляют RELAY_PIN и RELAY_PIN_1?
    кнопки 1-5 и +/- находятся на одном пульте или на разных?
     
  9. Иropь

    Иropь Нерд

    1) Включение/выключение устройства и переключение входов, в конкретном случае они не нужны,2 ) на одном пульте ...
     
  10. Иropь

    Иropь Нерд

    Кнопками 1-5 выбираем один из движков, а кнопками +/ - , включаем движение мотора, мотор крутится пока нажата кнопка +/- , нештатные ситуации не актуальны , ибо скорость там маленькая , точное кол-во шагов тоже...он просто крутит переменный резистор
     
  11. Tomasina

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

    во, появилось еще одно условие: пока нажата кнопка. :)

    Каким кнопкам соответствуют коды?
    0xC90
    0x490
    0xB47
    0x80B47
    0xC0B47
    0x20B47
    0x60B47
    0xE0B47
    0x40B47
    0xA0B47
    0xA90
    0x3EE
     
  12. Иropь

    Иropь Нерд

    0хС90 и 0х490 плюс минус, потом по порядку 1,2 4,5 7,8 3,6..в принципе все кнопки и все двигатели имеют идентичный алгоритм..две последние реле
     
    Последнее редактирование: 6 июн 2016
  13. Tomasina

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

    т.е. одновременно может крутиться только один из моторов?

    Тогда как-то так:
    Код (C++):

    #include "IRremote.h"  // https://github.com/z3t0/Arduino-IRremote

    #define BUTTON_1          0xB47             // коды кнопок пульта
    #define BUTTON_2          0x80B47
    #define BUTTON_4          0xC0B47
    #define BUTTON_5          0x20B47
    #define BUTTON_7          0x60B47
    #define BUTTON_8          0xE0B47
    #define BUTTON_3          0x40B47
    #define BUTTON_6          0xA0B47
    #define BUTTON_A          0xA90
    #define BUTTON_B          0x3EE
    #define BUTTON_PLUS       0xC90
    #define BUTTON_MINUS      0x490

    const byte receiverPin  = 6;                // пин для подключения выхода ИК-приемника
    const byte motorPin[20] = {22,23,24,25,
                               26,27,28,29,
                               30,31,32,33,
                               34,35,36,37,
                               38,39,40,41};    // массив пинов всех моторов

    const byte ledPin[5] =    {15,16,17,18,19}; // индикаторы активного мотора
    byte currentMotor;                         // переменная для хранения текущего (активного) мотора
    const byte motorPause = 3;                 // длительность четверти шага

    IRrecv irrecv(receiverPin);
    decode_results results;

    void setup()
    {
      for(byte i = 0; i < 20; i++) pinMode(motorPin[i], OUTPUT);
      for(byte i = 0; i < 5; i++) pinMode(ledPin[i], OUTPUT);
      irrecv.enableIRIn();
    }

    void loop()
    {
      if (irrecv.decode(&results)) // получен сигнал с пульта
      {
        switch(results.value)
        {
        case BUTTON_1:         // кнопки 1-5 выбирают движок
          currentMotor = 1;
          break;

        case BUTTON_2:
          currentMotor = 2;
          break;

        case BUTTON_3:
          currentMotor = 3;
          break;

        case BUTTON_4:
          currentMotor = 4;
          break;

        case BUTTON_5:
          currentMotor = 5;
          break;

        case BUTTON_PLUS:
          stepRight();     // делаем 1 шаг в одну сторону
          break;

        case BUTTON_MINUS:
          stepLeft();      // делаем 1 шаг в другую сторону
          break;

        case BUTTON_A:     // эта кнопка сбрасывает все активные движки
          currentMotor = 0;
          break;

        case BUTTON_B:     // эта кнопка активирует следующий движок
          currentMotor = currentMotor > 4 ? 1 : currentMotor=+1;
          break;
        } // switch
        irrecv.resume();
      }
      // гасим все индикаторы
      for(byte i = 0; i < 5; i++) digitalWrite(ledPin[i], LOW);
      // включаем индикатор выбранного движка
      if (currentMotor > 0) digitalWrite(ledPin[currentMotor - 1], HIGH);

    } // loop


    void stepLeft()
    {
      byte startPin = (currentMotor - 1) * 4;
      if (currentMotor > 0)
      {
        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], HIGH );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], HIGH );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], HIGH );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], HIGH );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);
      }
    }

    void stepRight()
    {
      byte startPin = (currentMotor - 1) * 4;
      if (currentMotor > 0)
      {
        digitalWrite( motorPin[startPin], HIGH );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], HIGH );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], HIGH );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], HIGH );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);
      }
    }
     
     
    Последнее редактирование: 6 июн 2016
    Иropь нравится это.
  14. Иropь

    Иropь Нерд

    Спасибо сегодня вечером попробую
     
  15. fogary

    fogary Гик

    Чисто из любопытства, здесь и ниже, разве не вылезет ошибка когда currentMotor = 0?
     
  16. Tomasina

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

    да, там две строчки надо поменять местами:
    Код (C++):
    void stepLeft()
    {
      if (currentMotor > 0)
      {
        byte startPin = (currentMotor - 1) * 4;

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], HIGH );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], HIGH );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], HIGH );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], HIGH );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);
      }
    }

    void stepRight()
    {
      if (currentMotor > 0)
      {
        byte startPin = (currentMotor - 1) * 4;

        digitalWrite( motorPin[startPin], HIGH );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], HIGH );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], HIGH );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], HIGH );
        delay(motorPause);

        digitalWrite( motorPin[startPin], LOW );
        digitalWrite( motorPin[startPin + 1], LOW );
        digitalWrite( motorPin[startPin + 2], LOW );
        digitalWrite( motorPin[startPin + 3], LOW );
        delay(motorPause);
      }
    }
     
    Иropь нравится это.
  17. Иropь

    Иropь Нерд

    Такой вопрос хочу сделать автоматическое отключение усилителя в отсутствии входного сигнала,самый простой способ при нуле на входе сделать задержку delay, но многие не советуют так делать, может это возможно реализовать на АЦП входах?
     
  18. fogary

    fogary Гик

    Как именно Вы определяете отсутствие сигнала?
    Какую функцию выполняет задержка и почему для этого не советуют использовать delay()?
    То именно нужно реализовать на АЦП входах?
     
  19. Иropь

    Иropь Нерд

    Если просто делать то не сложная схема на двух транзисторах,усиливает сигнал от предусилителя до постоянных +5вольт,и подается на вход ардуино,если на вход усилителя сигнал не идет то на вход ардуино 0 вольт этими напряжениями управляем реле которое при 0 вольт отключает реле . A delay задает время выключения реле после подачи 0 вольт на вход ардуино. это сделать на АЦП входах ардуины то можно избавиться от схемы на транзисторах которая задает +5 вольт.Как то так....
     
  20. fogary

    fogary Гик

    Ну, с аналоговым входом (АЦП) принцип будет примерно тот же. Только вместо "0", будет некая величина, соответствующая уровню паузы/отсутствия сигнала. Схема все равно понадобиться, в простейшем случае - два резистора и конденсатор. Насколько это принципиально, относительно того, что у Вас уже есть?

    Примеров замены delay() на millis() - масса. Если в процессе задержки, никаких других действий выполняться не должно, то нет смысла отказываться от delay().