Концевики и шаговый двигатель

Тема в разделе "Arduino & Shields", создана пользователем Airo, 4 июн 2023.

  1. Airo

    Airo Нерд

    Я поигрался с 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 ;
        }
    начал работать не всегда правда. Иногда дребезг бывает, но это уже почти успех.
     
  2. ivan_alexoff

    ivan_alexoff Гик

    Конечно ничего не даст. Сначала разберитесь со своими датчиками. Что они выдают при срабатывании. Что это за бред
    Код (C++):
    pinMode(leftSensor, INPUT_PULLUP);
      pinMode(rightSensor, INPUT_PULLUP);
    ?
    Во-вторых, либо задайте начальные значения флагов либо поменяйте их значения в условиях. Иначе они у вас и не будут выполняться.
    А это для сравнения. В симуляторе кнопки (ваши концевики) с дребезгом
    https://wokwi.com/projects/366966220335461377
    https://wokwi.com/projects/366966263686742017
     
  3. Airo

    Airo Нерд

    Они выдают тоже что в симуляторе. Второй вариант работает. Спасибо. Осталось только настроить время переключения обмоток
    motorDelay. Я не пойму как его можно уменьшить. С минимальным значением мотор сильно шумит, а чем выше тем хуже.
     
  4. Airo

    Airo Нерд

    Судя по всему еще старый вариант рабочий.
    Код (C++):
    if(digitalRead(leftSensor)){
            processTmr = millis();
            currentDirection = true;
        }

        if(digitalRead(rightSensor)){
            processTmr = millis();
            currentDirection = false ;
        }
    Ему мешала неоткалиброванное время переключения обмоток.
     
  5. ivan_alexoff

    ivan_alexoff Гик

    Плохому танцору всегда что-то мешает
     
  6. Sergku

    Sergku Нерд

    https://arduino.ru/Reference/Micros
     
    BOOM нравится это.
  7. BOOM

    BOOM Нерд

  8. ivan_alexoff

    ivan_alexoff Гик

    Это у ТС-а спроси, я его код просто скопировал, поправил только инпуты на остальное не смотрел
     
  9. Airo

    Airo Нерд

    Я и не говорил что хорошо разбираюсь. Я с ардуино знаком всего 3 месяца. И многое с чем впервые сталкиваюсь.
     
  10. Airo

    Airo Нерд

    Спасибо, что помогли с программой. Я знаком с функциями времени. Мне просто не ясно как вы заменили 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?
     
    Последнее редактирование: 9 июн 2023
  11. Airo

    Airo Нерд

    Я экспериментировал с motorDelay что бы уменьшить его ниже целого числа 1 поменял с int на float. К сожалению, результата это не дало. А потом просто забыл поменять обратно.
     
  12. Sergku

    Sergku Нерд

    вся работа по вращению мотора происходит тут:

    Код (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. В общем почитайте про это
     
  13. Airo

    Airo Нерд

    Все разобрался. Надо было перевести 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; // Для обмоток мотора
     
  14. Sergku

    Sergku Нерд

    Именно. Но, опять же, драйвер мотора, это инерциальная штука, может там надо шаманить с переходным процессом...
     
    Последнее редактирование: 9 июн 2023
  15. Airo

    Airo Нерд

    Протестировал пол часа.
    processDelay =500, // Общее вращение
    motorDelay =500;// Для обмоток мотора
    Это максимум, что смог выжать из него. 1 цикл туда обратно проходит за 480 млсек. Это даже больше чем я рассчитывал. Шумный правда, но тут уже драйвер виноват А4988. В будущем хочу поменять на TMC2208. В принципе работает без перебоев не греется. Я доволен. Еще раз Большое спасибо за помощь. Маялся с кодом 2 недели до того как решил написать на форуме.