Управление мотором с IK датчика

Тема в разделе "Arduino & Shields", создана пользователем Sergey AV, 5 ноя 2016.

  1. Sergey AV

    Sergey AV Нуб

    Доброго всем дня! вожусь с arduino всего полторы недели, до этого не было похожего опыта.
    Вот поставил себе задачу, но пока ни где не могу найти решения, если поможете буду очень признателен!.
    идея: есть (arduino UNO)+(Инфракрасный датчик препятствий E18-D80NK)+(электродвигатель обычный на 12 вольт).
    Датчик дает значение (1) когда нет препятствия и (0) когда перед ним появляется объект.
    Мне нужно чтобы:
    моторчик запускался при значение (0) но с определенной задержкой во времени, которую нужно будет подбирать практическим путем.
    И останавливался как вкопанный как только значение будет (1)
    Еще нужна переменная которая задает скорость двигателя, она тоже подбирается методом тыка )

    Итог: двигатель работает четко по датчику (1) LOW, (0) HIGH.

    В чем я не могу разобраться:
    1. моторчик запускается сразу как получает значение (0), а мне нужно что бы он запускался с определенной задержкой в микросекундах. если я пишу:
    digitalWrite (MOTOR_PIN, LOW);
    delay(100);
    то получаю нужный процесс, но тогда и операция digitalWrite (MOTOR_PIN, HIGH); просит функцию delay() а мне нужно чтобы моторчик крутился до тех пор пока не получит значение (1)
    как мне с этим быть?
    2. не могу понять как задать скорость моторчика?

    сейчас заказал в amperka.ru шаговый мотор (42STH47-0406A) с драйвером (Troyka-модуль), может на нем будет проще достигнуть желаемого результата, (хотелось бы максимальной точности в работе двигателя)

    вод мой скетч:
    #define IK_PIN 3 //порт ик датчика
    #define MOTOR_PIN 9 //порт мотора

    int ik = 0;

    void setup()
    {
    pinMode(IK_PIN, INPUT);
    Serial.begin(9600);
    pinMode(MOTOR_PIN,OUTPUT);
    }

    void loop()
    {
    ik =digitalRead(IK_PIN);
    Serial.print(ik);
    Serial.println();

    if (ik==0)
    {
    digitalWrite (MOTOR_PIN, LOW);
    digitalWrite (MOTOR_PIN, HIGH);

    }

    if (ik== 1)
    {
    digitalWrite (MOTOR_PIN, LOW);
    }

    }
     
  2. rkit

    rkit Гуру

    Что? Как она может просить?

    Вообще связанные со временем задачи лучше решать с помощью конечных автоматов.
     
  3. qwone

    qwone Гик

    Рассказывать, как вам создавать Системы Реального Времени. Особенно когда у вас нет опыта проектирования и программирования. Скорее и проще возьмите задачу по легче.
     
  4. Sergey AV

    Sergey AV Нуб

    Только вернулся домой, привезли драйвер на шаговый двигатель (можно будет скоро переходить на него! )
    )))ну я же говорил что новичок, не просит а просто не работает )
    сейчас все прочитаю, если это о том что я говорил то спасибо за ссылку !
     
  5. Sergey AV

    Sergey AV Нуб

    А я бы рассказал Вам ) если бы знал.
    эта и так самая простая задача которая крутится у меня в голове!
     
  6. rkit

    rkit Гуру

    Это то, что надо знать в любом случае. И вообще, весь раздел "Программирование на C++" из вики рекомендую изучить и проработать.
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    #define MOTOR                   9     // любой пин с поддержкой ШИМ // пин напрямую к мотору НЕ ПОДКЛЮЧАТЬ!
    #define SENSOR                  3
    #define MAX_SPEED               200  // от 0 до 255
    const unsigned int startDelay = 2000;
    byte speed;

    void setup()
    {
      pinMode(MOTOR, OUTPUT);
      pinMode(SENSOR, INPUT);
    }

    void loop()
    {
      if (speed == 0 && digitalRead(SENSOR) == 0) delay(startDelay);

      if (digitalRead(SENSOR) == 0) speed = MAX_SPEED;
      else speed = 0;

      analogWrite(MOTOR, speed);
    }
    с коллекторным движком мгновенную остановку не сделать, при отключении питания он некоторое время будет вращаться по инерции (можно, конечно, подавать на него переменное напряжение, но: а) нужен мотор-шилд, б) это все равно не мгновенная остановка, хоть и быстрее простого снятия питания, в) звуки при этом будут мерзкие)
    С шаговым - электронный тормоз - реализуемо.

    P.S. можно и еще короче, но это не для новичков:
    Код (C++):
    void loop()
    {
      delay(!speed * !digitalRead(SENSOR) * startDelay);
      analogWrite(MOTOR, digitalRead(SENSOR) ? MAX_SPEED : 0);
    }
    В качестве домашнего задания - разобраться как это работает. В wiki всё разжевано.
     
    Последнее редактирование: 5 ноя 2016
    Sergey AV нравится это.
  8. qwone

    qwone Гик

    Ну драйвер шагового двигателя нужен и для колекторного двигателя. Передняя задняя скорость нужна по любому. А если еще правый и левый движки . Вот и 1 драйвер будет занят. Туда же и Шим пристенуть можно.
    ПС:http://ru.aliexpress.com/item/Free-...rd-module-stepper-motor-smart/1872427142.html
    Вот такую надо. Там где перемычки завести ШИМ.
     
  9. Sergey AV

    Sergey AV Нуб

    Большое спасибо! Все разобрал и понял как работает, но думаю без вас заняло бы намного больше времени ) наверное пытался бы чтото нагромоздить с кодом))
    Колекторный мотор я подключаю через транзистор полевой MOSFET, а шаговик через Драйвер шагового двигателя (Troyka-модуль)
    А про короткий код, да это пока сложновато для меня ! )
     
  10. ИгорьК

    ИгорьК Гуру

    Други! Давно Си не баловался, а вот понадобилось. Это, видимо, недавно стандарт вышел новый - писать код в одну строку?
    В JS есть минификаторы - они изымают из кода все пробелы, переводы строк, имена переменным режут и т.п. и скрипт становится монолитом. Правда только компу понятным.
    В Си теперь тоже компилятор отменили?
     
  11. rkit

    rkit Гуру

    Там speed не инициализирована. Работать будет как повезет.
     
  12. qwone

    qwone Гик

    Скорее вернулись к старому , к исходному. Вот только когда памяти стало много и популяризация среди начинающих, оплата за объем исходника привели к версии к которой вы привыкли. Раньше русское программирование отличалось краткостью и лаконичностью, которая ставит в тупик неподготовленых к этому.
     
  13. ИгорьК

    ИгорьК Гуру

    Улыбнуло. Спасибо :)
     
  14. Tomasina

    Tomasina Сушитель лампочек Модератор

    Пишут так как кому удобно.
    Мне, например, удобнее писать по идеологии линукса - одно действие - один оператор, все значения вынесены в дефы. Даже тернарные операторы разворачиваются в if. Банально потому, чтобы через год долго не вникать как оно работает. ;)
    Но иногда во мне просыпается перфекционист и тянет к клавиатуре свои шаловливые ручонки с целью навести минимализм.
     
  15. qwone

    qwone Гик

    Код это не художественное произведение. Он еще должен "работать". Но иногда он "не работает" или "работает не так". Код требует отладки. Разумеется, если программа большая, то отладку лучше проводить по частям. А еще лучше брать "проверенные тобой части" из своих же программ. От туда скопировать, а туда поставить. И чем короче это кусок , тем проще скопировать его и не потерять чего-то.
    ПС: И да русское программирование выросло из ТРИЗ https://goo.gl/CCYCoa
     
  16. ИгорьК

    ИгорьК Гуру

    Это расстраивает. Особенно в контексте данной темы.
    Да и перфекционизмом это не назвал бы. Скорее - остаться в тренде, задаваемом... Обычно ваш код прост и понятен. Это и есть русский стиль.
     
  17. Sergey AV

    Sergey AV Нуб

    Код (C++):
    #define SENSOR        3
    #define stepPin       9
    #define directionPin  8
    #define enablePin     11

    #define STATE_STOP    0
    #define STATE_DELAY   1
    #define STATE_START   2

    int motorState = STATE_STOP;
    int delayTime = 2;

    const unsigned int startDelay = 500;
    byte speed;

    void setup() {
      pinMode(stepPin, OUTPUT);
      pinMode(directionPin, OUTPUT);
      pinMode(enablePin, OUTPUT);
      pinMode(SENSOR, INPUT);
    }
    void loop()
    {
      digitalWrite( enablePin, HIGH);
      digitalWrite(directionPin, LOW);
    bool sensorIk = digitalRead(SENSOR);
      if (sensorIk ==  motorState)   digitalWrite(stepPin, (millis()/ delayTime)%2);
     
     
    }
    переделал код шаговик работает, останавливается когда нужно могу скорость регулировать ( int delayTime)
    но не как не могу вставить паузу перед запуском. подскажите может совсем не туда полез, уже третий рас перечитываю вики (программирование на С++) пытался сделать "Конечные автоматы" что то пока не получается сделать задержку перед запуском ((
     
  18. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    #define SENSOR        3
    #define stepPin       9
    #define directionPin  8
    #define enablePin     11

    enum {STATE_STOP, STATE_DELAY, STATE_START}; // возможные состояния конечного автомата
    byte motorState;                             // текущее состояние системы
    unsigned int delayTime = 2;
    const unsigned int startDelay = 500;

    void setup()
    {
      pinMode(stepPin, OUTPUT);
      pinMode(directionPin, OUTPUT);
      pinMode(enablePin, OUTPUT);
      pinMode(SENSOR, INPUT);
      motorState = STATE_STOP; // состояние системы при включении питания
    }

    void loop()
    {
      if (digitalRead(SENSOR) == HIGH) // перед датчиком нет препятствия
      {
        if (motorState == STATE_STOP) motorState = STATE_DELAY; // и до этого мотор не вращался
        else motorState = STATE_START;
      }
      else motorState = STATE_STOP;    // есть препятствие

      switch (motorState)
      {
        case STATE_STOP:
          digitalWrite(enablePin, LOW);     // блокируем работу драйвера ШД
          break;

        case STATE_DELAY:
          delay(startDelay);                // тупим немного
          digitalWrite(enablePin, HIGH);    // разрешаем работу драйвера ШД
          digitalWrite(directionPin, LOW);  // задаем направление вращения
          motorState = STATE_START;
          break;

        case STATE_START:
          digitalWrite(stepPin, (millis() / delayTime) % 2);
          break;
      }
    }
     
    Sergey AV нравится это.
  19. Sergey AV

    Sergey AV Нуб

    Большое спасибо, только почему то получилось наоборот мотор останавливается если видит препятствие, а так постоянно работает )
     
  20. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    if (digitalRead(SENSOR) == LOW)