Здравствуйте! Мне понадобилось запустить моторчик от cd дисковода, для этого купил драйвер a4988 и ардуино нано. Поскольку я сам не особо разбираюсь в программировании, посмотрел несколько статьей в интернете и написал такой код: Код (C++): int step = 4; int dir = 5; int en = 6; int wait; int val; int c; int state; boolean down = true; boolean up = true; void setup() { pinMode(step, OUTPUT); pinMode(dir, OUTPUT); pinMode(en, OUTPUT); pinMode(7, INPUT_PULLUP); digitalWrite(en, HIGH); } void loop() { wait=20; state = digitalRead(7); if (digitalRead(state) == HIGH && c == 0) { c = 1; } if (digitalRead(state) == LOW && c == 1) { val == ++val; if (val == 2) { val = 0; } c = 0; } if (val == 0) { digitalWrite(en, HIGH); } if (val == 1) { digitalWrite(en, LOW); digitalWrite(dir, LOW); for(int i=0; i<2600; i++){ digitalWrite(step, HIGH); delayMicroseconds(wait); digitalWrite(step, LOW); delayMicroseconds(wait); } digitalWrite(en, HIGH); } if (val == 2) { digitalWrite(en, LOW); digitalWrite(dir, HIGH); for(int i=0; i<2800; i++){ digitalWrite(step, HIGH); delayMicroseconds(wait); digitalWrite(step, LOW); delayMicroseconds(wait); } digitalWrite(en, HIGH); } } Смысл заключается в том что когда схема просто запитана то на выход en подаётся 1 дабы отключить выходные масфеты драйвера, что бы просто так не грел мотор блокировкой. После того как будет нажата первый раз кнопка он должен подать 0 на en и 0 на dir, потом сделать 2600 импульсов со скоростью 10мс на step, после чего опять подать 1 на en. Когда кнопка будет нажата 2 раз: на en 0 а на dir 1 и потом 2800 импульсов. Проблема заключается в том что почему-то после 2600 импульсов он запускает этот же цикл заново и как я понимаю, из-за этого он не переключается на 3 режим. Есть какие нибудь мысли почему так происходит и как от это решить?
lool вызывается постоянно. Как только закончится, вызывается снова. Вот он отработал, val осталось 1, он вызывается снова и, поскольку val равно 1 снова отрабатывает то же самое и так бесконечно.
Правильно писать. Вы попытались реализовать автомат с состояниями "начальное (val==0)", "делаем 2600 шагов (val==1)" и "делаем 2800 шагов (val==2)". Но у Вас нет состояния "ждём нажатия кнопки". Оно бы выручило. Ну, кроме того, специфика модели программирования с функциями setup / loop не предполагает наличия каких-либо циклов в самом loop (а у Вас их два). Как только Вы пихаете цикл внутрь loop, знайте, Вы что-то делаете неправильно и это будет потом источником проблем. Каких проблем? Ну, например, Вы подумаете и решите развить свою задачу так: если в процессе "2600 шагов" поступило новое нажатие кнопки, бросаем этот режим (не доходя до конца) и сразу переключаемся на режим "2800 шагов". Если бы программа была сделана правильно (без циклов в loop) сделать такую модификацию было бы легко, а так - гороху наедитесь добавляя проверку нажатия кнопки внутрь цикла. В общем, это не так пишется.
У вас в коде есть есть такие строчки: Код (C++): val == ++val; if (val == 2) { val = 0; } а дальше: Код (C++): if (val == 2) { digitalWrite(en, LOW); digitalWrite(dir, HIGH); for(int i=0; i<2800; i++){ ............................ То есть, вы увеличиваете val проверяете, если она равна "2" то сразу скидываете ее в 0, а дальше ниже еще раз проверяете не равна ли она "2". А она уже сброшена в "0" По этой причине вы в это условие уже не попадаете. Уберите первую проверку val совсем, а val = 0; перенесите во вторую. Строчка val == ++val; у вас работает, но не так как вы думаете. Да, val увеличивается на 1, но первая часть "val ==" не имеет смысла. "==" - это оператор сравнения. Вместо val == ++val; нужно: Код (C++): ++val; или val++; или val=val+1; Ну и инициализация переменных. Всегда инициализируйте переменные независимо от их типа и места хранения, это поможет избежать мучительного поиска ошибок в случае их изменения. Сделали вы переменную вместо глобальной - локальной, а проинициализировать забыли. И все, ищите, что происходит, почему она не "0".