повтор задач с кнопкой (Troyka-модуль)

Тема в разделе "Arduino & Shields", создана пользователем Avazi, 1 апр 2015.

  1. Avazi

    Avazi Нуб

    Добрый вечер, всем!
    Помогите пожалуйста новичку с переделкой программы "предметного стола для фотосъемки", который показан в блоге. Только вместо RESET я хочу использовать кнопку для начала задания и повтора, т.к. сейчас при включении arduino автоматически начинает выполнять задачу. Кнопку (troyka-модуль) подключил на A5 в Troyka Shield.

    Код (Text):
    // Характеристика двигателя,
    // количество шагов на один оборот вала
    #define MOTOR_STEPS_REVOLUTION 200

    // Передаточный коэффициент шестерёнок
    #define GEAR_COEFFICIENT 2

    // Итоговое количество шагов на один оборот столика
    #define STEPS_REVOLUTION GEAR_COEFFICIENT * MOTOR_STEPS_REVOLUTION

    // Необходимое количество кадров за один оборот
    #define SHOTS 40

    // Количество шагов двигателя между снимками
    #define STEPS_ON_SHOT STEPS_REVOLUTION/SHOTS

    // Выдержка времени между шагами.
    // Чем больше это число, тем медленнее вращается двигатель
    #define DELAY_TIME 8

    // Назначим пины
    // Troyka-Stepper:
    // Шаг двигателя
    #define STEP 5
    // Направление вращения
    #define DIR  6
    // Включение двигателя
    #define EN  7

    // Реле. При срабатывании включает затвор фотоаппарата
    #define SHOT 8

    void setup() {
      // Настроим все необходимые пины на выход
      for (int i = STEP; i <= SHOT; ++i) {
        pinMode(i, OUTPUT);
      }
    }

    void loop() {
      // Включаем мотор
      digitalWrite(EN, HIGH);

      // Для каждого из необходимого количества снимков...
      for (int i = 0; i < SHOTS; ++i) {
        // Ждём 500 мс, чтобы столик остановился
        delay(500);

        // Замыкаем реле, происходит съёмка
        digitalWrite(SHOT, HIGH);
        delay(200);
        // Размыкаем реле
        digitalWrite(SHOT, LOW);

        // Выдержка, чтобы фотоаппарат успел записать снимок на карту
        delay(1000);

        // Поворачиваем столик на необходимое количество шагов
        for (int i = 0; i < STEPS_ON_SHOT; ++i) {

          // Один шаг
          digitalWrite(STEP, HIGH);
          delay(DELAY_TIME);
          digitalWrite(STEP, LOW);
          delay(DELAY_TIME);
        }
      }

      // После завершения съёмки отключаем двигатель
      digitalWrite(EN, LOW);

      // Завершаем работу.
      // Чтобы возобновить работу нужно нажать кнопку RESET
      while (true) {
        ;
      }
    }
     
    Последнее редактирование: 2 апр 2015
  2. vvr

    vvr Инженерище

    А чем ресет не устраивает?
     
  3. Avazi

    Avazi Нуб

    Пока кнопку подключил на reset и землю, работает. Хочу собрать в корпусе, и мешает автоматический запуск.
     
  4. 9xA59kK

    9xA59kK Гик

    Если есть свободный вход подключи кнопку , дописать программу ручного запуска с этой кнопки.
     
  5. Avazi

    Avazi Нуб

    Попытался дописать, но пока не работает. Второй день как с ардуином :(
    Код (Text):
    // Характеристика двигателя,
    // количество шагов на один оборот вала
    #define MOTOR_STEPS_REVOLUTION 200

    // Передаточный коэффициент шестерёнок
    #define GEAR_COEFFICIENT 2

    // Итоговое количество шагов на один оборот столика
    #define STEPS_REVOLUTION GEAR_COEFFICIENT * MOTOR_STEPS_REVOLUTION

    // Необходимое количество кадров за один оборот
    #define SHOTS 40

    // Количество шагов двигателя между снимками
    #define STEPS_ON_SHOT STEPS_REVOLUTION/SHOTS

    // Выдержка времени между шагами.
    // Чем больше это число, тем медленнее вращается двигатель
    #define DELAY_TIME 8

    // Назначим пины
    // Troyka-Stepper:
    // кнопка запуска
    #define BUTTON 4

    // Шаг двигателя
    #define STEP 5
    // Направление вращения
    #define DIR  6
    // Включение двигателя
    #define EN  7

    // Реле. При срабатывании включает затвор фотоаппарата
    #define SHOT 8

    void setup() {
      // Настроим все необходимые пины на выход
      for (int i = BUTTON; i <= SHOT; ++i) {
        pinMode(i, OUTPUT);
      }
    }

    void loop() {
     
      if (BUTTON == HIGH) {
      // Включаем мотор
      digitalWrite(EN, HIGH);

      // Для каждого из необходимого количества снимков...
      for (int i = 0; i < SHOTS; ++i) {
        // Ждём 500 мс, чтобы столик остановился
        delay(500);

        // Замыкаем реле, происходит съёмка
        digitalWrite(SHOT, HIGH);
        delay(200);
        // Размыкаем реле
        digitalWrite(SHOT, LOW);

        // Выдержка, чтобы фотоаппарат успел записать снимок на карту
        delay(1000);

        // Поворачиваем столик на необходимое количество шагов
        for (int i = 0; i < STEPS_ON_SHOT; ++i) {

          // Один шаг
          digitalWrite(STEP, HIGH);
          delay(DELAY_TIME);
          digitalWrite(STEP, LOW);
          delay(DELAY_TIME);
        }
      }

      // После завершения съёмки отключаем двигатель
      digitalWrite(EN, LOW);
      }
      // Завершаем работу.
      // Чтобы возобновить работу нужно нажать кнопку RESET
      while (true) {
        ;
      }
    }
     
  6. 9xA59kK

    9xA59kK Гик

    Вход для кнопки не инициализировал в Setup. И возможно не правильно подключил кнопку. Еще не помешает написать защиту от дребезга контактов кнопки.
    В ВиКи есть много примеров , да и в инете еще больше, как подключить кнопку к ардуине. Вот тут отличная библиотека для подавления дребезга, и пример кода есть. вот такой к примеру

    Код (Text):
    #include <Bounce.h>      // библиотека ,наличие ее в ардуино IDE обязательно

    #define BUTTON 4        // пин на ардуино  к которому подключена кнопка

    #define LED 13              //  нагрузка пин 13 к которому подключен светодиод


    int ledValue = LOW;

    // This example changes the state of the LED everytime the button is pushed

    // Build the circuit indicated here: http://arduino.cc/en/Tutorial/Button

    Bounce bouncer = Bounce( BUTTON, 5 );    // 5 миллисекунд антидребезг

    void setup() {

      pinMode(BUTTON,INPUT);  // кнопка BUTTON та что на пине 4  определяем ее как ВХОД

      pinMode(LED,OUTPUT);        // светодиод как выход
    }

    void loop() {

    //  пример ниже делает вот что: Одно нажатие на кнопку включает светодиод второе нажатие выключает светодиод

      if ( bouncer.update() ) {            //  постоянное опрос(обновление состояния) входа кнопки

      if ( bouncer.read() == HIGH) {    // если  вход т.е кнопка нажата(притянута к +5вольтам) то

      if ( ledValue == LOW ) {          //если светодиод был выключен  то

      ledValue = HIGH;              // включаем светодиод

      } else {                  // иначе (это если он был включен) то

      ledValue = LOW;                      // то выключаем светодиод

      }                                                    //

      digitalWrite(LED,ledValue);  // записываем в наш порт-выход состояние наших переменных

      }

      }

    }
     
    Последнее редактирование: 3 апр 2015
  7. Avazi

    Avazi Нуб

    С дребезгом получилось.
    Нашел другой вариант, но переходит сразу на режим 1, и крутит мотор без остановки.
    с этой командой остановил while (true) {digitalWrite(EN, LOW);}, но теперь при нажатии на кнопку не переключает на режим 2. Если уберу действия с режима 1. то кнопка срабатывает, запускает режим 2, но тоже без переключения.
    Код (Text):
    // Характеристика двигателя,
    // количество шагов на один оборот вала
    #define MOTOR_STEPS_REVOLUTION 200

    // Передаточный коэффициент шестерёнок
    #define GEAR_COEFFICIENT 2

    // Итоговое количество шагов на один оборот столика
    #define STEPS_REVOLUTION GEAR_COEFFICIENT * MOTOR_STEPS_REVOLUTION

    // Необходимое количество кадров за один оборот
    #define SHOTS 5

    // Количество шагов двигателя между снимками
    #define STEPS_ON_SHOT STEPS_REVOLUTION/SHOTS

    // Выдержка времени между шагами.
    // Чем больше это число, тем медленнее вращается двигатель
    #define DELAY_TIME 8

    // Назначим пины
    // Troyka-Stepper:
    // Шаг двигателя
    #define STEP 5
    // Направление вращения
    #define DIR  6
    // Включение двигателя
    #define EN  7

    // Реле. При срабатывании включает затвор фотоаппарата
    #define SHOT 8

    int ButPin = 10; // Подключаем кнопку к выходу 10
    int flag = 0; // флаг состояния
    int regim = 0; // Переключалка

    void setup() {
      // Настроим все необходимые пины на выход
        for (int i = STEP; i <= SHOT; ++i) {
        pinMode(i, OUTPUT);
        }
    }

    void loop() {

    if(digitalRead(ButPin) == HIGH && flag == 0)
    {
    regim ++;
    flag = 1;

    if(regim > 2) // Если номер режима превышает требуемого
    { // то отсчет начинается с нуля
    regim = 0;
    }
    }

    if(digitalRead(ButPin) == LOW && flag == 1)
    {
    flag = 0;
    }
    // ======= Вполняем задачу при выборе режима =======
    // РЕЖИМ 0: OFF
    if(regim == 0)
    {
    }
    // РЕЖИМ 1: R
    if(regim == 1)
    {
      // Включаем мотор
      digitalWrite(EN, HIGH);
     
      // Поворачиваем столик
      for (int i = 0; i < STEPS_REVOLUTION; ++i) {

      digitalWrite(STEP, HIGH);
      delay(DELAY_TIME);
      digitalWrite(STEP, LOW);
      delay(DELAY_TIME);
      }
      while (true) {
      digitalWrite(EN, LOW);
      }
    }

    // РЕЖИМ 2: G
    if(regim == 2)
    {
      digitalWrite(EN, HIGH);
      // Для каждого из необходимого количества снимков...
      for (int i = 0; i < SHOTS; ++i) {
        // Ждём 500 мс, чтобы столик остановился
        delay(500);

        // Замыкаем реле, происходит съёмка
        digitalWrite(SHOT, HIGH);
        delay(200);
        // Размыкаем реле
        digitalWrite(SHOT, LOW);

        // Выдержка, чтобы фотоаппарат успел записать снимок на карту
        delay(1000);

        // Поворачиваем столик на необходимое количество шагов
        for (int i = 0; i < STEPS_ON_SHOT; ++i) {

          // Один шаг
          digitalWrite(STEP, HIGH);
          delay(DELAY_TIME);
          digitalWrite(STEP, LOW);
          delay(DELAY_TIME);
        }
      }
      // После завершения съёмки отключаем двигатель
      while (true) {
      digitalWrite(EN, LOW);
      }
    }
    }
     
  8. 9xA59kK

    9xA59kK Гик

    Идея правильная. счетчик режимов. НО без обработки дребезга кнопки(в программе выше его не видно), у тебя должны быть проблемы с переключением режимов. И при использовании функции delay() в качестве задержек, тоже.
    В режиме OFF почему пусто, нечего обрабатывать? Этот режим предполагает что то выключить, остановить двигатель например, сбросить.

    Не знаю как у тебя вообще кнопка работает. по нормальному надо в void setup() пин этой кнопки объявить как вход, иначе digitalRead( пин кнопки) будет что попало выдавать.
    void setup() {
    pinMode(10,INPUT);
    //остальные пины как выход. к которым подключен двигатель и что там еще
    }
    ps\ А из какого блога пример, ссылку нарисуй глянуть.
     
    Последнее редактирование: 8 апр 2015
  9. vvr

    vvr Инженерище

    так уже посоветовали Bounce, поле для деятельности открыто:)
     
  10. 9xA59kK

    9xA59kK Гик

    Вот ссылка с примером управления шаговым двигателем там и остановка его есть. Там в конце программы
    // Ничего не делаем до перезагрузки
    while (true) {
    ;
    }
    Tебе это вообще не надо, просто остановил двигатель и все, это и есть твой OFF режим. Т.е. когда твой двигатель во втором режиме закончит вращение, его отключаешь и переходишь в OFF.
     
  11. 9xA59kK

    9xA59kK Гик

    Да согласен, он наверно еще до этого не дорос. Все впереди позже поймет.
     
  12. Avazi

    Avazi Нуб

    Спасибо, попробую сейчас. Взял пример отсюда http://linuxmd.net/avr/332-dejstviya-posle-nazhatiya-
     
  13. Avazi

    Avazi Нуб

    Bounce выдавал ошибку, тогда я не смог правильно настроить, сегодня скопировал этот код из примера, выдал снова кучу ошибок:

    Arduino: 1.6.2 (Mac OS X), Плата"Arduino Uno"

    Изменена опция сборки, пересобираем все
    sketch_bounce.ino:47:2: error: stray '#' in program
    sketch_bounce.ino:47:3: error: 'include' does not name a type
    sketch_bounce.ino:60:8: error: redefinition of 'Bounce bouncer'
    sketch_bounce.ino:14:8: error: 'Bounce bouncer' previously declared here
    sketch_bounce.ino: In function 'void setup()':
    sketch_bounce.ino:62:6: error: redefinition of 'void setup()'
    sketch_bounce.ino:16:6: error: 'void setup()' previously defined here
    sketch_bounce.ino: In function 'void loop()':
    sketch_bounce.ino:69:6: error: redefinition of 'void loop()'
    sketch_bounce.ino:23:6: error: 'void loop()' previously defined here
    Ошибка компиляции.

    Да, я пока новичок в программировании))
     
  14. Avazi

    Avazi Нуб

    Получилось! Все работает) Спасибо!

    Код (Text):
    #include <Bounce.h>

    // Характеристика двигателя,
    // количество шагов на один оборот вала
    #define MOTOR_STEPS_REVOLUTION 200

    // Передаточный коэффициент шестерёнок
    #define GEAR_COEFFICIENT 2

    // Итоговое количество шагов на один оборот столика
    #define STEPS_REVOLUTION GEAR_COEFFICIENT * MOTOR_STEPS_REVOLUTION

    // Необходимое количество кадров за один оборот
    #define SHOTS 25

    // Количество шагов двигателя между снимками
    #define STEPS_ON_SHOT STEPS_REVOLUTION/SHOTS

    // Выдержка времени между шагами.
    // Чем больше это число, тем медленнее вращается двигатель
    #define DELAY_TIME 8

    // Назначим пины
    // Troyka-Stepper:
    // Шаг двигателя
    #define STEP 5
    // Направление вращения
    #define DIR  6
    // Включение двигателя
    #define EN  7

    // Реле. При срабатывании включает затвор фотоаппарата
    #define SHOT 8

    #define BUTTON 9
    #define LED 13
    int ledValue = LOW;
    Bounce bouncer = Bounce( BUTTON, 5 );    // 5 миллисекунд антидребезг

    void setup() {
      pinMode(BUTTON, INPUT);
      pinMode(LED, OUTPUT);
      // Настроим все необходимые пины на выход
      for (int i = STEP; i <= SHOT; ++i) {
        pinMode(i, OUTPUT);
      }
    }

    void loop() {
      if ( bouncer.update() ) {            //  постоянное опрос(обновление состояния) входа кнопки
      if ( bouncer.read() == HIGH) {    // если  вход т.е кнопка нажата(притянута к +5вольтам) то
      if ( ledValue == LOW ) {          //если был выключен  то
      // Включаем мотор
      ledValue = HIGH;
      digitalWrite(EN, HIGH);
    for (int i = 0; i < STEPS_REVOLUTION; ++i) {

          // Один шаг
          digitalWrite(STEP, HIGH);
          delay(DELAY_TIME);
          digitalWrite(STEP, LOW);
          delay(DELAY_TIME);
        }
      delay(500);
          digitalWrite(EN, LOW);
      } else {
     
      // После завершения съёмки отключаем двигатель
      ledValue = LOW;
      digitalWrite(EN, HIGH);
      // Для каждого из необходимого количества снимков...
      for (int i = 0; i < SHOTS; ++i) {
        // Ждём 500 мс, чтобы столик остановился
        delay(500);

        // Замыкаем реле, происходит съёмка
        digitalWrite(SHOT, HIGH);
        delay(200);
        // Размыкаем реле
        digitalWrite(SHOT, LOW);

        // Выдержка, чтобы фотоаппарат успел записать снимок на карту
        delay(1000);

        // Поворачиваем столик на необходимое количество шагов
        for (int i = 0; i < STEPS_REVOLUTION; ++i) {

          // Один шаг
          digitalWrite(STEP, HIGH);
          delay(DELAY_TIME);
          digitalWrite(STEP, LOW);
          delay(DELAY_TIME);
        }
      }
      digitalWrite(EN, LOW);
      }
      digitalWrite(LED,ledValue);
    }
    }
    }
     
    Последнее редактирование: 8 апр 2015