РЕШЕНО Запретить движение в одну сторону

Тема в разделе "Arduino & Shields", создана пользователем dmb, 27 дек 2021.

  1. dmb

    dmb Нерд

    Доброе время, есть скетч вращения мотора по вращению энкодера - как в одну, так и в другую сторону. Но нужно, чтобы при нажатии кнопки (пока кнопка нажата) - движение было только в одну сторону, а вращение энкодера в другую сторону попросту игнорировалось. Как это можно реализовать? Заранее благодарен за ответ!
    Код (C++):
    #include <AccelStepper.h>
    #define encoder_pin_A 8
    #define encoder_pin_B 9
    int encoder_pin_A_last = LOW;
    int encoder_pos = 0;
    int n = LOW;
    #define stepper_pin_step 6
    #define stepper_pin_dir  5
    // Enc have 24 steps per revolution
    // The motor have 800 steps per revolution
    // Want: 1 encoder rev = 1 stepper rev
    // 800 / 24 = 33.3333333333...
    float steps_per_pulse = 33.3333333333;
    AccelStepper stepper(AccelStepper::DRIVER, stepper_pin_step, stepper_pin_dir);
    void setup() {
      stepper.setMaxSpeed(800.0);
      stepper.setAcceleration(300.0);
     
      pinMode(encoder_pin_A, INPUT_PULLUP);
      pinMode(encoder_pin_B, INPUT_PULLUP);
    }
    void loop() {
      // read encoder
      n = digitalRead(encoder_pin_A);
     
      if ((encoder_pin_A_last == LOW) && (n == HIGH)) {
        if (digitalRead(encoder_pin_B) == LOW) {
          encoder_pos--;
        } else {
          encoder_pos++;
        }
        // set stepper to the new calculated position
        stepper.moveTo((long) round(encoder_pos*steps_per_pulse));
      }
     
      encoder_pin_A_last = n;
      stepper.run();
    }
     
  2. parovoZZ

    parovoZZ Гуру

    через флаг.
     
  3. dmb

    dmb Нерд

    А куда его поставить, извините? )
     
  4. parovoZZ

    parovoZZ Гуру

    В то место кода, где необходимо ветвление алгоритма.
     
  5. dmb

    dmb Нерд

    Спасибо. А можете показать на примере? Я полагаю, что где-то перед "void loop". Правильно? И как выглядит синтаксис этого флага...?
     
  6. a1000

    a1000 Гуру

    Вы понимаете, что написано в вашем коде? Можете прокоментировать каждую строчку?
    Разберитесь в коде и вопрос отпадёт сам собой.
    И ещё, метод обработки вращения энкодера у вас весьма несовершенен. Если у вас оптический энкодер лишенный дребезга, то пойдёт. Но если такой китайский девайс,
    [​IMG]
    то шаговый двигатель будет дёргаться как угодно, но не так как вы задумали. В чисто учебных целях, для понятия процесса, пойдёт. Но потом надо будет освобождаться от дребезга.
     
    vvr нравится это.
  7. dmb

    dmb Нерд

    К сожалению, я не очень хорошо понимаю код - скорее, очень плохо: никак программирование не дается, может самых основ не понимаю..? По поводу метода обработки энкодера - перепробовал несколько десятков разных скетчей - этот работает лучше всего, хотя он довольно примитивен. Энкодер не китайский - это дисковый оптический энкодер и оптопара, мотор отрабатывает все как надо (возможно, может и лучше - но этого достаточно). Нужно только, по нажатию кнопки запретить крутиться в определенном направлении. Пробовал "разорвать пин "dir" - да, мотор крутится только в одном направлении, пока цепь разорвана - но мне нужно, чтобы во время удержания кнопки (или концевого выключателя) он крутился не в обратном направлении - а просто молчал (стоял на месте). Отсоединение одного из пинов от энкодера тоже не приводит к нужному результату. Ответ конечно же очень прост - нужно запрограммировать эту функцию и объявить отвечающий за это пин, подтянуть его сопротивлением к GND - и дело в шляпе - но для меня это сложный вопрос, собственно по этому и обратился в Амперку - очень часто тут выручали, за что заранее благодарен!
     
  8. Рокки1945

    Рокки1945 Гуру

    надо создать условие при значении флага = 1 только в одну сторону обрабатывается энкодер
     
  9. a1000

    a1000 Гуру

    В таком миниатюрном коде, да плюс длительное нажатие, флаг и нафиг не нужен. Сразу проверяем состояние кнопки и если нажата пропускаем encoder_pos-- либо encoder_pos++, в зависимости от необходимого направления.
     
    dmb нравится это.
  10. dmb

    dmb Нерд

    О да! Меня этот флаг только сбил с толку... Заблокировал encoder_pos++ , чтобы энкодер игнорировался при вращении против часовой стрелки - и ура, все работает! Огромное спасибо, а1000!
     
  11. parovoZZ

    parovoZZ Гуру

    Состояние кнопки и есть флаг.
     
  12. a1000

    a1000 Гуру

    Скорее всего я не совсем правильно понимаю терминологию, но флаг я представляю так:
    Объявляем булевую переменную и где-то, например в прерывании, выставляем её в 1 или 0 в зависимости от состояния пина, пришедших по UART данных, или любых других условий. Потом в другом месте кода, ну скажем в основном цикле, мы идём по одной или другой ветви кода в зависимости от состояния флага.
    А вот если это выглядит так
    Код (C++):
    if (digitalRead(button_pin) == HIGH)
      {
        //делаем что-то важное
        //если button_pin в состоянии HIGH
        //или пропускаем если button_pin в состоянии LOW
      }
    то назвать что-то тут флагом у меня язык не поворачивается.
     
    dmb нравится это.
  13. akl

    akl Гуру

    digitalRead всего лишь считывает флаг из определенного бита определенного регистра
     
    a1000 нравится это.
  14. a1000

    a1000 Гуру

    По большому счёту наверное вы правы. Вся магия происходит внутри функции digitalRead, которая проверяет состояние нужного бита в регистре PINx, и в зависимости от его состояния возвращает нам 0 или 1, которые и можно назвать флагом, с которым мы в последствии работаем.
    В очередной раз убедился, на сколько всё проще и нагляднее в ASM. Есть инструкции SBIC и SBIS, которыми можно сразу выполнить ветвление, не создавая никаких флагов и не занимая память. А тут, в лучшем случае флаг сохраняется в переменной типа boolean величиной в байт, а то и в интовой переменной, размером в 2 байта.
     
    dmb нравится это.
  15. ИгорьК

    ИгорьК Гуру

    +100500, давно говорю все остальные языки надо запретить. Ну кроме языка ардуино, ибо ардуинщегов зело много, бунт поднимут. Коньяк однако...
     
  16. SergeiL

    SergeiL Оракул Модератор

    Ну при желании или непонимании можно и 4-х байтную переменную под bool задействовать, Кто больше? :)
    Можно подумать на ASM можно выделить битовую булевую переменную :)

    А на С++ как раз можно сгруппировать N-е количество булевых переменных в (N+7)/8 целочисленных байт, и обращаться к каждой по имени.
    @Asper Daffy объяснял как это сделать.
     
  17. ИгорьК

    ИгорьК Гуру

    Я больше.
    И вот кто здесь делает проекты, те что из истории про один байт, который не влез?
    Ну, расскажите.

    Тупоконечники, остроконечники ... Вместо доброго DIY, занимаетесь выпасом сферических коней. Как только творческий потенциал заканчивается, начинаются нравоучения да схоластические споры.
    Кстати, как только слышу от кого-то слово "говнокод" - 100% человек исчерпался. Ибо тот кто творит - тот делает ошибки и чушь, это нормально. А кто запалом сдох и не развивается - тому ничего не остаётся как "учить жизни".
     
  18. SergeiL

    SergeiL Оракул Модератор

    Так дело не в том, что байт не влез.
    А как же тяга к прекрасному, к оптимальности?
    Каждый по своему видит свою цель, у каждого свои интересы, кому-то DIY проекты в принципе не нужны.

    На счет "говокода" - все относительно, смотря с какой позиции смотреть.
    Если устройство работает, не глючит, создатель устройства доволен - нормальный код для его целей.
    Ошибки делают все. Ошибки, скопированные и не подправленные куски кода, да много чего. Даже профессионалы.
    Иначе не было бы тестовых версий, предрелизных и т.д.
     
    Рокки1945 нравится это.
  19. dmb

    dmb Нерд

    философы... Тему можно закрывать, вопрос решен, все большое спасибо!
     
    Airbus нравится это.
  20. ИгорьК

    ИгорьК Гуру

    Модератор, удалите сообщение флудера.