Я поигрался с motorDelay и для меня лучшим стала это 1. А ниже 1 я поставить и не могу. В моем прошлом скетче идеальным был delayMicroseconds(390); а в motorDelay не могу добиться такого результата. Его можно заменить или как то уменьшить значение ниже 1? Я пробовал через float ставить числа с плавающей точкой, но результата не дало. И кстати при motorDelay=1 Код (C++): if(digitalRead(leftSensor)){ processTmr = millis(); currentDirection = true; } if(digitalRead(rightSensor)){ processTmr = millis(); currentDirection = false ; } начал работать не всегда правда. Иногда дребезг бывает, но это уже почти успех.
Конечно ничего не даст. Сначала разберитесь со своими датчиками. Что они выдают при срабатывании. Что это за бред Код (C++): pinMode(leftSensor, INPUT_PULLUP); pinMode(rightSensor, INPUT_PULLUP); ? Во-вторых, либо задайте начальные значения флагов либо поменяйте их значения в условиях. Иначе они у вас и не будут выполняться. А это для сравнения. В симуляторе кнопки (ваши концевики) с дребезгом https://wokwi.com/projects/366966220335461377 https://wokwi.com/projects/366966263686742017
Они выдают тоже что в симуляторе. Второй вариант работает. Спасибо. Осталось только настроить время переключения обмоток motorDelay. Я не пойму как его можно уменьшить. С минимальным значением мотор сильно шумит, а чем выше тем хуже.
Судя по всему еще старый вариант рабочий. Код (C++): if(digitalRead(leftSensor)){ processTmr = millis(); currentDirection = true; } if(digitalRead(rightSensor)){ processTmr = millis(); currentDirection = false ; } Ему мешала неоткалиброванное время переключения обмоток.
Я и не говорил что хорошо разбираюсь. Я с ардуино знаком всего 3 месяца. И многое с чем впервые сталкиваюсь.
Спасибо, что помогли с программой. Я знаком с функциями времени. Мне просто не ясно как вы заменили delayMicroseconds(50); на переменную motorDelay. И что еще важнее как правильно ее можно менять. Так как с motorDelay я не смог добиться тех же результатов, что дал delayMicroseconds(50). Я заменил участок с направлением движения и все стало работать как я и хотел. Код (C++): if (millis() - processTmr <= processDelay){ digitalWrite(dirPin, currentDirection); digitalWrite(stepPin, HIGH); delayMicroseconds(390); digitalWrite(stepPin, LOW); delayMicroseconds(390); } Но ваш вариант мне нравиться больше. Я просто не понимаю как можно работать с motorDelay что бы добиться тех же результатов. Я для этого пробовал менять его с int на float что бы просто уменьшать ниже целого числа. Я понимаю что motorDelay 1 = delayMicroseconds(1000) Но как можно уменьшить motorDelay до 0,390?
Я экспериментировал с motorDelay что бы уменьшить его ниже целого числа 1 поменял с int на float. К сожалению, результата это не дало. А потом просто забыл поменять обратно.
вся работа по вращению мотора происходит тут: Код (C++): if(millis() - motorTmr >= motorDelay){ motorTmr = millis(); digitalWrite(dirPin, currentDirection); digitalWrite(stepPin, !digitalRead(stepPin)); millis() возвращает время в миллисекундах micros() в микро. Берем, например, секунду, millis() вернет 1000 а вот micros() уже 1 000 000. Т.е. повышается разрешение, эти 1000 мс бьются на 1 000 000 и можно извращаться с этим. motorDelay просто константа, которая смотрит какая разница прошла с момента millis() - motorTmr. В общем почитайте про это
Все разобрался. Надо было перевести millis в micros. Спасибо большое. Вот что вышло в итоге: Код (C++): unsigned long motorTmr = 0, processTmr= 0; int processDelay = 630, // Общее вращение motorDelay = 390; // Для обмоток мотора bool currentDirection = false, left_flag = 1,//false, right_flag = 1;//false; const byte leftSensor = 8, rightSensor = 9, dirPin = 3, stepPin = 2; void setup(){Serial.begin(9600); pinMode(leftSensor, INPUT); pinMode(rightSensor, INPUT); pinMode(dirPin, OUTPUT); pinMode(stepPin, OUTPUT); motorTmr = micros(); processTmr = millis(); } void loop(){ if(digitalRead(leftSensor)){ processTmr = millis();Serial.println("left"); currentDirection = true; } if(digitalRead(rightSensor)){ processTmr = millis();Serial.println("right"); currentDirection = false ; } if (millis() - processTmr <= processDelay){ if(micros() - motorTmr >= motorDelay){ motorTmr = micros(); digitalWrite(dirPin, currentDirection); digitalWrite(stepPin, !digitalRead(stepPin)); } } else { processTmr = millis(); currentDirection = !currentDirection; } } Сейчас поставлю на длительную проверку, а потому буду добавлять сюда енкодер с LCD дисплеем, что бы регулировать это: processDelay = 630, // Общее вращение motorDelay = 390; // Для обмоток мотора
Именно. Но, опять же, драйвер мотора, это инерциальная штука, может там надо шаманить с переходным процессом...
Протестировал пол часа. processDelay =500, // Общее вращение motorDelay =500;// Для обмоток мотора Это максимум, что смог выжать из него. 1 цикл туда обратно проходит за 480 млсек. Это даже больше чем я рассчитывал. Шумный правда, но тут уже драйвер виноват А4988. В будущем хочу поменять на TMC2208. В принципе работает без перебоев не греется. Я доволен. Еще раз Большое спасибо за помощь. Маялся с кодом 2 недели до того как решил написать на форуме.