3 сервы без delay

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем Papipa, 8 сен 2016.

  1. Papipa

    Papipa Гик

    Всем привет!

    Вопрос - могут ли работать 3 сервы на 1 Ардуино без ожиданий delay? Т.е., например, одну крутим постоянно, вторую каждые 20 секунд крутим 10 раз туда-сюда и т.п.
    Delay мешает тем, что выполняет команду на конкретную, одну, серву, остальные сервы ждут, в цикле, когда очередь дойдет до них...

    Может быть, этот вопрос можно решить с помощью Arduino Shield (есть v. 5.0)? Не работал с ней пока, функционал не изучал...

    Прошу дать совет. Спасибо!!
     
  2. ostrov

    ostrov Гуру

    Почитайте на тему заменяем delay() на millis() или просто откройте пример blink без delay() и сделайте так же только три раза.
     
  3. Onkel

    Onkel Гуру

    может, еще как. Даже 8 может, проверял. Заводим 8 переменных на 8 серв, вызываем прерывание по таймеру и по 8 выходным пинам формируем управляющие импульсы для серв. Ни миллис, ни дилэй, ничего не нужно.
     
  4. ostrov

    ostrov Гуру

    Но если нужно проще и нагляднее, а так же если МК не перегружен другими задачами, то заводим три unsigned long и в трех строках организовываем управление тремя сервами.

    Я проповедую использование прерываний там где это необходимо, а если можно обойтись без них, то обойтись без них. Знаю, что это тема для холивара. но я для себя выбрал эту сторону.

    Последний раз применял прерывания вчера для опроса энкодера. В цикле опрашивать качественно не получалось, слишком неравномерные были паузы из за других задач. Вот тут прерывание хороший выход, спору нет.
     
  5. Onkel

    Onkel Гуру

    нет, это не тема для холивара также как не тема для холивара знание таблицы умножения. Таблицу умножения надо знать, прерывания для того и сделаны, чтобы их использовать. А обходиться без прерываний - это как удалять гланды через задний проход. Можно, но неправильно. И нет никакой необходимости обходиться без прерываний- это инструмент, сделанный для того, чтобы им пользоваться, а не пыжиться обойтись без инструмента.
     
  6. ostrov

    ostrov Гуру

    Это ваше мнение, оставайтесь при нем. По мне так если можно удалить гланды через рот, так и надо сделать а не использовать инструмент для удаления гланд через задницу только потому что он есть.
     
  7. Onkel

    Onkel Гуру

    прерывания по таймерам как раз и созданы для того, чтобы отсчитывать нужные интервалы. Так что формирование импульсов миллисекундной длительности - задача как раз для таймеров и для прерываний по таймерам.
    кстати как это вам удалось с помощью millis() формировать импульсы 0,8-2,4 мс?
     
    Последнее редактирование: 11 сен 2016
  8. ostrov

    ostrov Гуру

    Зачем? У автора поста речь идет о периоде 20 сек.
     
  9. Onkel

    Onkel Гуру

    а что на серву посылать? как вы без таймера, используя "проповедуемый" вами millis(), сформируете импульс 0,8 мс, например?
    да и посылать на серву сигнал раз в 20 с - плохой тон, если серва не цифровая, она обязательно уползет.
     
  10. ostrov

    ostrov Гуру

    То есть предполагается, что автор вместо Servo.write(angle) будет формировать сигнал прерываниями то таймеру. При этом не разобравшись даже с millis().
     
  11. Papipa

    Papipa Гик

    Серва - MG995. Как понимаю, как минимум из опыта работы с ней - уползти она не может. Движок на одной из конструкций стоит уже месяца 2 - всё работает. Если бы серва уплыла хотя бы градусов на 7-10, конструкция перестала бы работать, т.к. там точно выставлено положение детали вручную (определенный угол), и прикручено на винт к оси сервы)

    Но вот есть еще серва постоянного вращения... Некая MG 996R... Как ею управлять, ума не приложу - при задании угла менее ~300 градусов (точно сейчас не вспомню, но примерно это значение) - крутит в одну сторону без остановки, при задании угла более 300 градусов - в другую сторону, также без остановки. А надо покрутить и остановиться )) Наверное отдельную тему, вопрос создам, в инете ничего не нашел по этим "переделанным" сервам....
     
  12. Papipa

    Papipa Гик

    Ну т.е. с mills() не решить вопрос с управлением сервой? Импульс-то действительно нужен, минимально где-то около 0,6-0,65 секунды...
    И приспрошусь еще - с помощью шилда или чего-то подобного - можно решить вопрос задержек? Что-то типа "отправил на шилду сигнал включения для определенного устройства, а также отправил время действия сигнала - ну и забыл" - дальше шилда или ему подобное само (сама) выполнит команду, без участия микрокомпьютера?
     
    Последнее редактирование: 12 сен 2016
  13. ostrov

    ostrov Гуру

    Попробуйте командой servo.writeMicroseconds(); воспользоваться. Она, в отличии от write, позволяет задать импульс любой ширины, а не в диапазоне эквивалентным на взгляд библиотеки от 0 до 180 градусов. Например, при работе с БК моторами каждый раз приходится вычислять минимальный импульс вручную, у одних начинается с 1500, у других с 1200 и так далее. Сервы тоже разные.
     
  14. Onkel

    Onkel Гуру

    если автор разберется с прерываниями по таймеру, то ему millis() и не понадобятся. Тем более что любители millis() частенько забывают, что через полтора месяца у millis() будет переполнение, и что тогда? Сколько писателей скетчей, использующих millis, учли возможность этого переполнение? А если не просто серва, а включен насос или растопка котла? millis() надо использовать для того, для чего она была создана - для освоения программирования на блинках, но не в реальной жизни.
     
  15. vvr

    vvr Инженерище

    сервой постоянного вращения управляете как обычной сервой
    servo.write(90); - стоит на месте
    servo.write(>90); - вращается в одну сторону, 180 макс скорость
    servo.write(<90); - вращается в другую сторону, 0 макс скорость
     
  16. ostrov

    ostrov Гуру

    Учесть возможное переполнение и нейтрализовать его последствия довольно просто. На этом форуме уже обсуждалось и не раз. Например так:
    Код (C++):
    if(curMillis - lastMillis > interval)
    {
        doTheJob();
    }
    Но 95% устройств, которые я делал, делаю и планирую расчитаны на работу в течении нескольких часов за один раз, там эта проблема вообще не грозит.

    И вот еще вопрос, допустим пероидических процессов не два и не три, а десять или двадцать, причем одни вызываются раз в 5 мс, другие раз в 20 минут. Как это легко и просто сделать на прерываниях? Городить ту же имитацию millis() в итоге? ИМХО прерывания хороши для вызова достаточно частых, точных по времени и коротких функций, причем в ограниченном количестве.
     
  17. Onkel

    Onkel Гуру

    а в оставшихся 5% дело окончится пожаром или гидроударом?
    ага. люди так и напишут.... А потом будут доставать полдюжины форумов вопросом "почему это не работает"...
    курите матчасть. Хорошо матчасть описана, например, тут http://easyelectronics.ru/avr-uchebnyj-kurs-operacionnaya-sistema-vvedenie.html
    Но если ваши задачи ограничиваются советами, работающими только в скетчах блинка, а ответы имеют стиль doTheJob(); , то конечно не читайте - оно вам не понадобится.
     
  18. ostrov

    ostrov Гуру

    Разговор потерял конструктивизм и приобрел смысл выяснения у кого блинк короче. Меня это не интересует.
     
  19. Onkel

    Onkel Гуру

    Вы напрасно приписываете мне несвойственную мне эмоциональность и желание чем- либо меряться, но дело в том, что вы даете людям советы, которые по крайней мере неполны (как "достаточно трех переменных long" - ведь недостаточно, нужно еще и doTheJob(), так ведь?) вот я об этом и пишу.
     
    Последнее редактирование: 14 сен 2016
  20. ostrov

    ostrov Гуру

    Тем, кто не поймет что такое doTheJob() в данном примере, этот совет не поможет. Такие только через прерывания смогут.