Добрый день имеем скетч для для управления пятью шаговыми двигателями при помощи пульта ДУ , но так как для пяти двигателей надо 10 кнопок пульта, хочу немного разгрузить пульт и переключаться между двигателями или одной кнопкой по кругу,или назначить на пульте кнопки, 0т 1 до 5 ,по числу двигателей,а кнопками + и - управлять вращением выбранного двигателя, но что то не пойму как это осуществить , ибо конструкция switch case уже есть?
Да вот как раз не могу сообразить как будет выглядеть сама конструкция скетча, так бы саму программу написать было бы гораздо проще...
Я бы написал примерно так: Код (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; } } }
не надо себя привязывать ни к конструкции скетча, ни к синтаксису языка C++, эти ограничения тебя только тормозят. Нужен пошаговый алгоритм (текстовый, графический - неважно): если нажата кнопка "1" - делаем что? проверяем какое условие? Цель - "вслепую" запустить двигатель, не привязываясь к операторям языка После этого структура в коде сама всплывет.
Я больше склоняюсь к покнопочному алгоритму,нажал кнопку 1 крутим двиг 1 , нажал кнопку 2 , крутим двиг 2, и т.д. чтобы было точно понятно без доп индикации какой двиг крутим, хотя большой разницы с одной кнопкой нет, я так понимаю кнопкой 1 мы включаем двиг 1, но он не крутится на выходах пинов все нули, нужно включить его второй раз чтобы начал крутится кнопкой + или - , в зависимости от направления....а вот как его включить второй раз не пойму никак...
ну ё-мое... Тебя сейчас не должно волновать что там на пинах. Проблема: НЕТ ЖЕСТКО ПРОПИСАННОЙ ЛОГИКИ ПОВЕДЕНИЯ. Ибо даже сейчас получается две возможных ветки поведения: 1. Кнопки 1-5 включают/выключают конкретные движки, кнопки "+/-" изменяют только направление движения последнего выбранного движка. Последовательность нажатия кнопок неважна. 2. Кнопки 1-5 выбирают текущий движок, но не управляют им, кнопки "+/-" стопорят/стартуют текущий движок в нужном направлении. Причем в обеих вариантах даже не учтена обработка нештатных ситуаций (при полном вращении вперед двигло врубили назад, без паузы на остановку) - это проблемы оператора или программы? Ибо нет алгоритма. Вот поэтому и нужен точный алгоритм поведения. Не состояние пинов, не вопросы "включить его второй раз". Нет МК, нет проводов, нет пинов. Есть только 7 кнопок и 5 движков. Нужна четко прописанная последовательность шагов для запуска движка.
1) Включение/выключение устройства и переключение входов, в конкретном случае они не нужны,2 ) на одном пульте ...
Кнопками 1-5 выбираем один из движков, а кнопками +/ - , включаем движение мотора, мотор крутится пока нажата кнопка +/- , нештатные ситуации не актуальны , ибо скорость там маленькая , точное кол-во шагов тоже...он просто крутит переменный резистор
во, появилось еще одно условие: пока нажата кнопка. Каким кнопкам соответствуют коды? 0xC90 0x490 0xB47 0x80B47 0xC0B47 0x20B47 0x60B47 0xE0B47 0x40B47 0xA0B47 0xA90 0x3EE
0хС90 и 0х490 плюс минус, потом по порядку 1,2 4,5 7,8 3,6..в принципе все кнопки и все двигатели имеют идентичный алгоритм..две последние реле
т.е. одновременно может крутиться только один из моторов? Тогда как-то так: Код (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); } }
да, там две строчки надо поменять местами: Код (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); } }
Такой вопрос хочу сделать автоматическое отключение усилителя в отсутствии входного сигнала,самый простой способ при нуле на входе сделать задержку delay, но многие не советуют так делать, может это возможно реализовать на АЦП входах?
Как именно Вы определяете отсутствие сигнала? Какую функцию выполняет задержка и почему для этого не советуют использовать delay()? То именно нужно реализовать на АЦП входах?
Если просто делать то не сложная схема на двух транзисторах,усиливает сигнал от предусилителя до постоянных +5вольт,и подается на вход ардуино,если на вход усилителя сигнал не идет то на вход ардуино 0 вольт этими напряжениями управляем реле которое при 0 вольт отключает реле . A delay задает время выключения реле после подачи 0 вольт на вход ардуино. это сделать на АЦП входах ардуины то можно избавиться от схемы на транзисторах которая задает +5 вольт.Как то так....
Ну, с аналоговым входом (АЦП) принцип будет примерно тот же. Только вместо "0", будет некая величина, соответствующая уровню паузы/отсутствия сигнала. Схема все равно понадобиться, в простейшем случае - два резистора и конденсатор. Насколько это принципиально, относительно того, что у Вас уже есть? Примеров замены delay() на millis() - масса. Если в процессе задержки, никаких других действий выполняться не должно, то нет смысла отказываться от delay().