Код (C++): const int dirPin = 3; const int stepPin = 2; #define ENABLE_PIN 4 const int stepsPerRevolution = 2000; unsigned long myTimer6, myTimer7; unsigned long myTimer1,myTimer2, myTimer3, myTimer4, myTimer5; #define CLK 5 // пин энкодера #define DT 6 // пин энкодера #define SW 7 #include <GyverEncoder.h> Encoder enc (CLK, DT, SW); int val = 0; void setup() { pinMode(ENABLE_PIN , OUTPUT); pinMode(8, INPUT_PULLUP);//ставить вдали от двигателя pinMode(9, INPUT_PULLUP);//ставить возле двигателя pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); Serial.begin (9600); enc.setType(TYPE2); } void loop() { if (millis() - myTimer3 > 0 && millis() - myTimer3 < 300) {digitalWrite(ENABLE_PIN , LOW); if(digitalRead(8)){ digitalWrite(ENABLE_PIN , HIGH); } else{ digitalWrite(dirPin, LOW); digitalWrite(stepPin, HIGH); delayMicroseconds(390+val); digitalWrite(stepPin, LOW); delayMicroseconds(390+val); } } if (millis() - myTimer4 > 350 && millis() - myTimer4 < 650) { digitalWrite(ENABLE_PIN , LOW); if(digitalRead(9)){ digitalWrite(ENABLE_PIN , HIGH); } else{ digitalWrite(dirPin, HIGH); digitalWrite(stepPin, HIGH); delayMicroseconds(390+val); digitalWrite(stepPin, LOW); delayMicroseconds(390+val); } } if (millis() - myTimer5 > 700){ myTimer3= millis(); myTimer4= millis(); myTimer5= millis(); } enc.tick(); if (enc.isTurn()) { if (enc.isRight ()) val++; //крутим увеличиваем на 1 if (enc.isLeft ()) val--; //крутим уменьшаем на 1 if (enc.isRightH ()) val += 5; //удерживаем кнопку и крутим увеличиваем на 5 if (enc.isLeftH ()) val -= 5; //удерживаем кнопку и крутим уменьшаем на 5 Serial.println (val); } if (enc.isClick()) Serial.println ("click"); if (enc.isHolded()) Serial.println ("holded"); if (enc.isDouble()) Serial.println ("double"); if (enc.isFastR ()) val += 10; //быстро крутишь увеличивается на 10 if (enc.isFastL ()) val -= 10; //быстро крутишь уменьшается на 10 } Здравствуйте! Нужно помощь в доработке скетча. Создал направляющую по которой двигается коретка. Задача состоит в том что бы двигатель вращался 1, сек в оду и 1 сек в другую сторону (время будет еще меняться). И в случае если коретка достигает концевика менялось направление движения коретки. В данный момент при контакте с концевиком двигатель выключается в ожидании следующего цикла.
Если вы имеете ввиду что то вроде этого кода Код (C++): if(digitalRead(8)) { digitalWrite(dirPin, HIGH); digitalWrite(stepPin, HIGH); delayMicroseconds(390); digitalWrite(stepPin, LOW); delayMicroseconds(390); } else{ digitalWrite(dirPin, LOW); digitalWrite(stepPin, HIGH); delayMicroseconds(390); digitalWrite(stepPin, LOW); delayMicroseconds(390); } Уже побывал не работает. Когда задевает концевик коретка на мгновение движится в другую сторону до того момента пока не выйдет с зоны действия оптического концевика, а потом опять движится к нему обратно и по сути происходит баг движится дуда сюда на месте пока не закончится время if(millis()- myTimer3 >0&& millis()- myTimer3 <300).
У Вас в коде строка if(digitalRead(8)); будет все время TRUE пртому как кнопки подтянуты к питанию. На них всегда единица тобишь HIGH. И блок кода следующий за ним { digitalWrite(dirPin, HIGH); digitalWrite(stepPin, HIGH); delayMicroseconds(390); digitalWrite(stepPin, LOW); delayMicroseconds(390); } Будет выполнятся всегда а блок кода после else-никогда. Попробуйте так if(digitalRead(8)==LOW); Ну или как Вам уже сказали
кстати, я бы сначала просто моторами покрутил (туды, сюды), вот рыба: Код (C++): unsigned long motorTmr = 0, processTmr= 0; int processDelay = 1000, // Общее вращение motorDelay = 10; // Для обмоток мотора boolean currentDirection = false; void setup(){ motorTmr = processTmr = millis(); } void loop(){ if (millis() - processTmr <= processDelay){ if(millis() - motorTmr >= motorDelay){ motorTmr = millis(); if(currentDirection){ // Крутим вправо } else{ // Крутим влево } } } else { processTmr = millis(); currentDirection = !currentDirection; } }
Я понял что вы имеете в виду, но вы не правы. Все как раз наоборот. Код (C++): if(digitalRead(8)){ digitalWrite(dirPin, HIGH); digitalWrite(stepPin, HIGH); delayMicroseconds(390); digitalWrite(stepPin, LOW); delayMicroseconds(390); } else{ digitalWrite(dirPin, LOW); digitalWrite(stepPin, HIGH); delayMicroseconds(500); digitalWrite(stepPin, LOW); delayMicroseconds(500); } На постоянке используется то что в else а есле я сделаю инверсию как предлагали выше if(!digitalRead(8)). То в этом случае будет на постоянке использоваться то что под ним, а уже в случае если активируется концевик то будет работать, то что в else. Я так понимаю это потому что используется не обычная кнопка, а оптический датчик и он как раз срабатывает на разрыве.
С вращением проблем нет. Все работает как я и хотел. Проблема в том что когда концевик активируется и идет движение обратно, но только до тех пор, пока его не отожмут. тогда опять идет движение к нему и по кругу пока не закончится время if (millis() - myTimer3 > 0 && millis() - myTimer3 < 3000).
Может я не достаточно понятно разъясняю конечно. Попробую привести аналогию когда кнопка не нажата работает движение влево. Когда кнопка зажата идет движение вправо. И получается что кнопка нажимается и отжимается КЛАЦ-КЛАЦ-КЛАЦ-КЛАЦ-КЛАЦ-КЛАЦ. Использую вот такие концевики.
Сейчас пытаюсь сделать вот так Код (C++): const int dirPin = 3; const int stepPin = 2; #define ENABLE_PIN 4 unsigned long myTimer6, myTimer7; unsigned long myTimer1,myTimer2, myTimer3, myTimer4, myTimer5; void setup() { pinMode(8, INPUT_PULLUP);//ставить вдали от двигателя pinMode(9, INPUT_PULLUP);//ставить возле двигателя pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); Serial.begin (9600); } void loop() { if(digitalRead(8)){ Serial.println (1); myTimer3 = 3100; myTimer5 = 3000; } if(digitalRead(9)){ myTimer3 = 0; myTimer5 = 0; myTimer3= millis(); myTimer4= millis(); myTimer5= millis(); } if (millis() - myTimer3 < 3000){ Serial.println (3); } if (millis() - myTimer3 > 3000){ Serial.println (4); } if (millis() - myTimer5 > 6000){ myTimer5 = 0; myTimer3 = 0; myTimer3= millis(); myTimer5= millis(); } } Что то вроде если if(digitalRead(8) то время становится больше 3000 и тогда начинает работать Serial.println (4); ну и если if(digitalRead(9) то меньше 3000 и работает Serial.println (3);. Но почему то работает только с 9 пином он переводит в Serial.println (3);. А 8 пин почему то тоже переводит к Serial.println (3);. По сути хочу что бы при контакте с концевиком принудительно переходил к другому условию. Если задет 8 пин то что бы вкючался Serial.println (4);, а если 9 то Serial.println (3);
Непонятно, что вы вообще хотите... думаю это поможет определить Код (C++): if(digitalRead(8)) Serial.println("digitalRead(8) NOT PUSH"); else Serial.println("digitalRead(8) PUSH");
Флаги используй, кртуиш в одну сторону - ставишь флаг "крутим туды", сработал концевик - поднимаешь флаг " крутим сюды" и т.д туды-сюды-обратно ...
Да вы почти поняли то что я хочу только с еще одним условием. Попробую пояснить. Есть ость Х по ней движется объект, управляется все шаговым двигателем. Он движется туда-сюда с периодичностью в 3сек (это значение будет еще меняться, но пака для удобства 3 сек на движение в одном направление после чего 3 сек в другое направление). Концевики нужны для того что бы если объект дотронется до концевика он должен сменить направление движения. Условие: 1)Объект движется вправо и не дотрагивается до концевика, заканчивается время (3сек) он разворачивается влево. 2)Объект движется влево и не дотрагивается до концевика, заканчивается время (3сек) он разворачивается вправо. 3) Если при движении влево задевается левый концевик даже если время (3сек) не прошло он должен начать движение вправо. 4) Если при движении вправо задевается правый концевик даже если время (3сек) не прошло он должен начать движение влево. Концевики своего рода крайние точки оси. До них объект в идеале не должен доходить, но если случиться это он должен пойти в противоположном направление. Концевики используются как предохранитель, что бы объект не уперся в край ОСИ и не начал об нее биться (это может случиться по разным причинам к примеру не ровность ОСИ или какое-то воздействие на объект).
Я пробовал. digitalWrite(dirPin, HIGH); это по сути и есть флаг (HIGH-враво, LOW-влево). Но проблема в том что при контакте с концевиком флаг меняется, но только до того момента пока кнопка не отожмется (так как используется оптический концевик у него кнопку заменяет лазер. В активном состоянии он выдает Folse, если лазер прерывается True.) и как только лазер становиться опять Folse движение объекта опять стремиться к нему.
Допустим, он встретил концевик, и развернулся, время обратного движения снова в 3 секунды устанавливается?
на основе шаблона, что я кидал выше, должно заработать: Код (C++): unsigned long motorTmr = 0, processTmr= 0; int processDelay = 3000, // Общее вращение motorDelay = 10; // Для обмоток мотора boolean currentDirection = false; const byte leftSensor = 8, rightSensor = 9, dirPin = 3, stepPin = 2; void setup(){ pinMode(leftSensor, INPUT_PULLUP); pinMode(rightSensor, INPUT_PULLUP); pinMode(dirPin, OUTPUT); pinMode(stepPin, OUTPUT); motorTmr = processTmr = millis(); } void loop(){ if(!digitalRead(leftSensor)){ processTmr = millis(); currentDirection = !currentDirection; } if(!digitalRead(rightSensor)){ processTmr = millis(); currentDirection = !currentDirection; } if (millis() - processTmr <= processDelay){ if(millis() - motorTmr >= motorDelay){ motorTmr = millis(); digitalWrite(dirPin, currentDirection); digitalWrite(stepPin, !digitalRead(stepPin)); } } else { processTmr = millis(); currentDirection = !currentDirection; } }
Вы должны ущучивать не только текущее состояние сенсора, но и момент перехода состояния, и направление перехода. Например в цикле - считать текущее состояние сенсора - запомнить его. В очередной итерации - считать состояние, сравнить с запомненным, и снова запомнить новое состояние. Если оно не изменилось - игнорировать. Если изменилось (напр. 0->1) - предпринять действие. Если изменилось наоборот - снова игнорировать и тд. ПС. При использовании механизма прерываний - можно как раз настроить пин входа на отслеживание - либо уровня на пине, либо направления изменения уровня на пине. ППС. В случае мех. сенсоров, вам придется бороться с дребезгом, но в вашем случае оптических сенсоров - вряд ли это надо.