Управление двумя устройствами от 1 ардуино - ФОРУМ ДВ Робот dvrobot.ru
Вторник, 16.10.2018, 02:04
Главная Мой профиль Регистрация Выход
  • НАШ МАГАЗИН
  • Вы вошли как Гость | Группа "Гости"Приветствую Вас, Гость
    [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
    • Страница 1 из 1
    • 1
    Модератор форума: Serg, GRACH  
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Arduino - вопросы и ответы. » Управление двумя устройствами от 1 ардуино (Переключение блоков программы кнопкой)
    Управление двумя устройствами от 1 ардуино
    fakirr999Дата: Пятница, 24.05.2013, 18:35 | Сообщение # 1
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 10
    Репутация: 0
    Статус: Offline
    Есть 2 устройства: операторский кран и установка для съемок Тайм лэпс. Оба управляются Ардуино. Цель: объединить коды управления и заставить одну дуинку в зависимости от состояния переключателя выполнять либо 1 либо 2 блок. Это реализовано через прерывание, но в функции void swap выдает ошибку и не могу понять в чем. Может кто-нить объяснит?
    
    Код
    #include <AccelStepper.h>

    // Установка пинов двигателей

    #define MOTOR1_DIR_PIN  8
    #define MOTOR2_DIR_PIN  11

    #define MOTOR1_STEP_PIN 9
    #define MOTOR2_STEP_PIN 10

    #define MOTOR1_LS_PIN 6
    #define MOTOR2_LS_PIN 7

    #define MOTOR1_SPR 200  // Кол-во шагов на 1 оборот вала двигателя
    #define MOTOR2_SPR 200   

    #define MOTOR1_MAX_SPEED 50000.0
    #define MOTOR2_MAX_SPEED 50000.0

    #define MOTOR1_INIT_SPEED -200.0
    #define MOTOR2_INIT_SPEED 800.0

    #define MOTOR1_JOY_IN 0 // Ось Y джойстика
    #define MOTOR2_JOY_IN 1 // Ось X джойстика

    AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
    AccelStepper stpMotor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);

    int nMotor1SP, nMotor2SP;            // Задание направления от джойстика
    int battonInt = 0; // Установка кнопки прерывания на пин 2
    int fotoPin = 3; // Установка выхода спуска затвора на пин 3

    void setap()
    {
       // Установка выходов пинов  
       pinMode(MOTOR1_DIR_PIN, OUTPUT);
       pinMode(MOTOR2_DIR_PIN, OUTPUT);
       pinMode(MOTOR1_STEP_PIN, OUTPUT);
       pinMode(MOTOR2_STEP_PIN, OUTPUT);
       
       pinMode(MOTOR1_LS_PIN, INPUT_PULLUP);
       pinMode(MOTOR2_LS_PIN, INPUT_PULLUP);
        
       pinMode(fotoPin, OUTPUT);
        
       // Добавление прерывания
       attachInterrupt(battonInt, swap, RISING);
    }

    void swap()// Функция выполняемая при приревании (нажатии кнопки)
    {
       stpMotor1.setSpeed(5);  // скорость вращения по оси Y 5 оборотов в минуту
       stpMotor2.setSpeed(5);  // скорость вращения по оси X 5 оборотов в минуту
        
       digitalWrite(fotoPin, HIGH); //сигнал 5 В на порт затвора камеры
       delay (200); //длительность импульса
       digitalWrite(fotoPin, LOW); //выключение сигнала 5 В на порт затвора камеры
       nMotor2SP.step(2); //поворот Ш.двигателя Х платформы на 4 градуса
       nMotor2SP.release(); //снятие питания Ш.двигателя Х платформы
    }

    void loop() // Основная программа
    {
      phGetCommand();
      phMotorRun();   
    }
    void phGetCommand()
    {
       nMotor1SP = analogRead(MOTOR1_JOY_IN) - 512;
       nMotor2SP = analogRead(MOTOR2_JOY_IN) - 512;
        
         if (nMotor1SP > 100) {
         nMotor1SP = nMotor1SP;
       } else if (nMotor1SP < -100) {
         nMotor1SP = -nMotor1SP;
       } else {
         nMotor1SP = 0;
       }
        
       nMotor1SP = nMotor1SP / 5;
        
       if (nMotor2SP > 100) {
         nMotor2SP = nMotor2SP;
       } else if (nMotor2SP < -100) {
         nMotor2SP = -nMotor2SP;
       } else {
         nMotor2SP = 0;
       }
        
       nMotor2SP = nMotor2SP * -1;
    }  

    void phMotorRun()  
    {
       stpMotor1.setSpeed(nMotor1SP);  // Задаем скорость по оси Y
       stpMotor2.setSpeed(nMotor2SP);  // Задаем скорость по оси X
        
       stpMotor1.runSpeed();
       stpMotor2.runSpeed();   
    }

    Добавлено (24.05.2013, 18:35)
    ---------------------------------------------
    Ну вроде допилил, компилятор ошибок не выдает. Остался вопрос как заставить функцию void swap() выполняться определенное количество раз?

    Код
    #include <AccelStepper.h>
       
      // Установка пинов двигателей
       
      #define MOTOR1_DIR_PIN  8
      #define MOTOR2_DIR_PIN  11
       
      #define MOTOR1_STEP_PIN 9
      #define MOTOR2_STEP_PIN 10
       
      #define MOTOR1_LS_PIN 6
      #define MOTOR2_LS_PIN 7
       
      #define MOTOR1_SPR 200  // Кол-во шагов на 1 оборот вала двигателя
      #define MOTOR2_SPR 200    
       
      #define MOTOR1_MAX_SPEED 50000.0
      #define MOTOR2_MAX_SPEED 50000.0
       
      #define MOTOR1_INIT_SPEED -200.0
      #define MOTOR2_INIT_SPEED 800.0
       
      #define MOTOR1_JOY_IN 0 // Ось Y джойстика
      #define MOTOR2_JOY_IN 1 // Ось X джойстика
       
      AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
      AccelStepper stpMotor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);
       
      int nMotor1SP, nMotor2SP;            // Задание направления от джойстика
      int battonInt = 0; // Установка кнопки прерывания на пин 2
      int fotoPin = 3; // Установка выхода спуска затвора на пин 3
       
      void setup()
      {
        // Установка выходов пинов   
        pinMode(MOTOR1_DIR_PIN, OUTPUT);
        pinMode(MOTOR2_DIR_PIN, OUTPUT);
        pinMode(MOTOR1_STEP_PIN, OUTPUT);
        pinMode(MOTOR2_STEP_PIN, OUTPUT);
          
        pinMode(MOTOR1_LS_PIN, INPUT_PULLUP);
        pinMode(MOTOR2_LS_PIN, INPUT_PULLUP);
           
        pinMode(fotoPin, OUTPUT);
           
        // Добавление прерывания
        attachInterrupt(battonInt, swap, RISING);
      }
       
      void swap()// Функция выполняемая при приревании (нажатии кнопки)
      {
             
        digitalWrite(fotoPin, HIGH); //сигнал 5 В на порт затвора камеры
        delay (200); //длительность импульса
        digitalWrite(fotoPin, LOW); //выключение сигнала 5 В на порт затвора камеры
        stpMotor2.setSpeed(5);  // скорость вращения по оси X 5 оборотов в минуту
        stpMotor2.runToNewPosition(20); //поворот Ш.двигателя Х платформы на 4 градуса
                        //подбирается экспериментально
      }
       
      void loop() // Основная программа
      {
       phGetCommand();
       phMotorRun();    
      }
      void phGetCommand()
      {
        nMotor1SP = analogRead(MOTOR1_JOY_IN) - 512;
        nMotor2SP = analogRead(MOTOR2_JOY_IN) - 512;
           
          if (nMotor1SP > 100) {
          nMotor1SP = nMotor1SP;
        } else if (nMotor1SP < -100) {
          nMotor1SP = -nMotor1SP;
        } else {
          nMotor1SP = 0;
        }
           
        nMotor1SP = nMotor1SP / 5;
           
        if (nMotor2SP > 100) {
          nMotor2SP = nMotor2SP;
        } else if (nMotor2SP < -100) {
          nMotor2SP = -nMotor2SP;
        } else {
          nMotor2SP = 0;
        }
           
        nMotor2SP = nMotor2SP * -1;
      }   
       
      void phMotorRun()   
      {
        stpMotor1.setSpeed(nMotor1SP);  // Задаем скорость по оси Y
        stpMotor2.setSpeed(nMotor2SP);  // Задаем скорость по оси X
           
        stpMotor1.runSpeed();
        stpMotor2.runSpeed();    
      }


    Сообщение отредактировал fakirr999 - Пятница, 24.05.2013, 04:49
     
    SergДата: Пятница, 24.05.2013, 19:03 | Сообщение # 2
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    в этой функции можно обьявить локальную переменную. При каждом выполнении добавлять к ней единицу и следить, что бы она не превысила необходимого количества раз.
     
    Ivan-771Дата: Пятница, 24.05.2013, 19:13 | Сообщение # 3
    5 Вольт
    Группа: Пользователи
    Сообщений: 39
    Репутация: 0
    Статус: Offline
    Код
     for (a= 1; a <= 90; a++)

       {
      void swap()// Функция выполняемая при приревании (нажатии кнопки)  
       {  
                
         digitalWrite(fotoPin, HIGH); //сигнал 5 В на порт затвора камеры  
         delay (200); //длительность импульса  
         digitalWrite(fotoPin, LOW); //выключение сигнала 5 В на порт затвора камеры  
         stpMotor2.setSpeed(5);  // скорость вращения по оси X 5 оборотов в минуту  
         stpMotor2.runToNewPosition(20); //поворот Ш.двигателя Х платформы на 4 градуса  
                         //подбирается экспериментально  
       }  
          
    }


       
    Только я не знаю, в убогом интерпретаторе Arduino СИ, можно делать так, ибо в норм компиляторах работает.
     
    SergДата: Пятница, 24.05.2013, 19:21 | Сообщение # 4
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    после void swap() уже лишний код. Функция описана выше. Зачем второй раз повторять?
     
    fakirr999Дата: Пятница, 24.05.2013, 19:47 | Сообщение # 5
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 10
    Репутация: 0
    Статус: Offline
    так выдает ошибку, а вот так нет
    Код
    void swap()// Функция выполняемая при приревании (нажатии кнопки)
       {
         for (int a=0; a <= 90; a++){     
         digitalWrite(fotoPin, HIGH); //сигнал 5 В на порт затвора камеры
         delay (200); //длительность импульса
         digitalWrite(fotoPin, LOW); //выключение сигнала 5 В на порт затвора камеры
         stpMotor2.setSpeed(5);  // скорость вращения по оси X 5 оборотов в минуту
         stpMotor2.runToNewPosition(20); //поворот Ш.двигателя Х платформы на 4 градуса
                         //подбирается экспериментально
         delay (1000);   
         }     
       }

    теперь проблема, внутри прерывания функция delay не работает (если я правильно понял). И как ее заменить?


    Сообщение отредактировал fakirr999 - Пятница, 24.05.2013, 20:08
     
    DuZeRДата: Суббота, 25.05.2013, 00:03 | Сообщение # 6
    5 Вольт
    Группа: Пользователи
    Сообщений: 42
    Репутация: 2
    Статус: Offline
    вместо delay() можно использовать тот же for(;;), если количество произвольное - передать в функцию int, или float, если нужно больше, и использовать в ограничении цикла.

    Возможности машины зависят от фантазии человека...
     
    SergДата: Суббота, 25.05.2013, 01:25 | Сообщение # 7
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    А почему вдруг delay перестал работать? Откуда такая уверенность?
     
    fakirr999Дата: Суббота, 25.05.2013, 03:13 | Сообщение # 8
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 10
    Репутация: 0
    Статус: Offline
    Цитата (Serg)
    А почему вдруг delay перестал работать? Откуда такая уверенность?
    Дык, сначала пытаюсь Гугл шерстить... а там
    Цитата
    Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания
    Конкретно тут: http://arduino.ru/Reference/AttachInterrupt Замечание по использованию
     
    Ivan-771Дата: Суббота, 25.05.2013, 06:26 | Сообщение # 9
    5 Вольт
    Группа: Пользователи
    Сообщений: 39
    Репутация: 0
    Статус: Offline
    Код
    for (int a=0; b <= 90; a++)
    Так у тебя условие  будет выполнено  91 раз то, что я поставил  a=1; не от балды.

    Задержку можно как угодно выполнить. К примеру  при 16 мегагерцах,
    выполнение данного кода, потребуется 8 ms.  Один проход всего 250 нс.

    Код
    for (b=0; b <= 32000; b++)
    {
    }


    Сообщение отредактировал Ivan-771 - Суббота, 25.05.2013, 11:10
     
    SergДата: Суббота, 25.05.2013, 11:39 | Сообщение # 10
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    fakirr999, а нужно ли прерывание вообще ??? Неужели эта кнопка такая важная? Поставь опрос кнопки в основной цикл программы.
     
    fakirr999Дата: Суббота, 25.05.2013, 13:49 | Сообщение # 11
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 10
    Репутация: 0
    Статус: Offline
    Сама суть данного девайса - получить универсальный пульт управления. В данной ситуации это операторский кран и установка Тайм Лэпс. Во время съемки, скажем, свадьбы и так куча железа с собой и таскать еще и 3-4 пульта не удобно, а так, поставил кран, воткнул пульт и работаешь. Надо золото в ювелирке поснимать - перевоткнул в установку и работай. Как его заставить выполнять разные функции по переключению без прерывания я не нашел (честно говоря про Ардуино узнал первый раз месяц назад)
     
    SergДата: Суббота, 25.05.2013, 14:09 | Сообщение # 12
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    Суть прерывания- это когда нужно срочно выполнить важную задачу в то время, пока выполняется второстепенная. Например- крутануть третий двигатель по нажатию кнопки, если в это время ардуина управляет двумя другими двигателями по определенной программе. Эти два двигателя в момент нажатия кнопки остановятся, крутанется третий, и двигатели продолжат вращение с остановленной позиции. Ну как то так...
     
    DuZeRДата: Воскресенье, 26.05.2013, 03:40 | Сообщение # 13
    5 Вольт
    Группа: Пользователи
    Сообщений: 42
    Репутация: 2
    Статус: Offline
    fakirr999 :  я так понял - тебе нужен один пульт на дуине для разных устройств, которыми ты управляешь не одновременно ?
    если так - пиши управление для всех своих устройств ( ну насколько памяти хватит в дуине ) и делай в setup() проверку какого либо ( или нескольких ) пина.
    То есть при включении будет происходить проверка - нажата ли кнопка на этом пине или нет, и в зависимости от этого выбирай, какие куски кода в данном сеансе работы выполнять.

    как то так:

    
    Код
    ...
    char mode=0;
    ...
    void setup()
    {
         ...

         pinMode(x,INPUT);
         if(digitalRead(x)>0) // х - номер пина на кнопку выбора девайса
         {
             mode=1;
         }
         else
         {
             mode=0;
         }

         ...
    }

    void loop()
    {
         ...
         if(mode==1)
         {
             ... //код для управления девайсом 1
         }
         else
         {
             ... //код для управления девайсом 2
         }

         ...

    }
    как то так. если конкретные девайсы и конкретные задачи сюда прилетят - тоды и скетч конкретнее будет )  happy


    Возможности машины зависят от фантазии человека...
     
    fakirr999Дата: Понедельник, 27.05.2013, 01:05 | Сообщение # 14
    3.5 Вольт
    Группа: Пользователи
    Сообщений: 10
    Репутация: 0
    Статус: Offline
    Думаю, что это проще чем через прерывания. Девайсы описаны в 11 сообщении, код в Первом

    Добавлено (27.05.2013, 01:05)
    ---------------------------------------------
    Ну, наверное, так
    
    Код
    #include <AccelStepper.h>
    #include <Servo.h>

    Servo servo123;

    #define MOTOR1_DIR_PIN  8
    #define MOTOR2_DIR_PIN  11

    #define MOTOR1_STEP_PIN 9
    #define MOTOR2_STEP_PIN 10

    #define MOTOR1_LS_PIN 6
    #define MOTOR2_LS_PIN 7

    #define MOTOR1_SPR 200  // Кол-во шагов на 1 оборот вала двигателя
    #define MOTOR2_SPR 200     

    #define MOTOR1_MAX_SPEED 50000.0
    #define MOTOR2_MAX_SPEED 50000.0

    #define MOTOR1_INIT_SPEED -200.0
    #define MOTOR2_INIT_SPEED 800.0

    #define MOTOR1_JOY_IN 0 // Ось Y джойстика
    #define MOTOR2_JOY_IN 1 // Ось X джойстика

    AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
    AccelStepper stpMotor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);

    int nMotor1SP, nMotor2SP;            // Задание направления от джойстика
    int potensiometr = A4;
    int val;
    int battonInt = 4; // Установка кнопки переключения на пин 4
    int fotoPin = 3; // Установка выхода спуска затвора на пин 3
    char mode=0;
    int a=0;

    void setup()    
    {                   
         pinMode(MOTOR1_DIR_PIN, OUTPUT);
         pinMode(MOTOR2_DIR_PIN, OUTPUT);
         pinMode(MOTOR1_STEP_PIN, OUTPUT);
         pinMode(MOTOR2_STEP_PIN, OUTPUT);

         pinMode(MOTOR1_LS_PIN, INPUT_PULLUP);
         pinMode(MOTOR2_LS_PIN, INPUT_PULLUP);
         servo123.attach(12);
         pinMode(4,INPUT);
         if(digitalRead(4)>0) // читаем кнопку выбора девайса
            {
                mode=1;
            }
            else
            {
                mode=0;
            }
    }

    void loop()
    {
         if(mode==1)
          for (int a=0; a <= 89; a++){      
          digitalWrite(fotoPin, HIGH); //сигнал 5 В на порт затвора камеры
          delay (200); //длительность импульса
          digitalWrite(fotoPin, LOW); //выключение сигнала 5 В на порт затвора камеры
          stpMotor2.setSpeed(5);  // скорость вращения по оси X 5 оборотов в минуту
          stpMotor2.runToNewPosition(20); //поворот Ш.двигателя Х платформы на 4 градуса
                          //подбирается экспериментально
          delay (1000);    
            
    }
         else
    {
    val = analogRead(potensiometr);
    val = map(val, 0, 1023, 0, 179);
    servo123.write(val);
    delay(15);
    }
    {
         nMotor1SP = analogRead(MOTOR1_JOY_IN) - 512;
         nMotor2SP = analogRead(MOTOR2_JOY_IN) - 512;
            
           if (nMotor1SP > 100) {
           nMotor1SP = nMotor1SP;
         } else if (nMotor1SP < -100)    
         {
           nMotor1SP = -nMotor1SP;
         } else    
         {
           nMotor1SP = 0;
         }
    }
            
         nMotor1SP = nMotor1SP / 5;
            
         if (nMotor2SP > 100) {
           nMotor2SP = nMotor2SP;
         } else if (nMotor2SP < -100) {
           nMotor2SP = -nMotor2SP;
         } else {
           nMotor2SP = 0;
         }
            
         nMotor2SP = nMotor2SP * -1;
         stpMotor1.setSpeed(nMotor1SP);  // Задаем скорость по оси Y
         stpMotor2.setSpeed(nMotor2SP);  // Задаем скорость по оси X
            
         stpMotor1.runSpeed();
         stpMotor2.runSpeed();     
    }

    DuZeR: Чтение кнопки как происходит? Должен быть фиксированный переключатель?


    Сообщение отредактировал fakirr999 - Понедельник, 27.05.2013, 01:14
     
    DuZeRДата: Понедельник, 27.05.2013, 12:38 | Сообщение # 15
    5 Вольт
    Группа: Пользователи
    Сообщений: 42
    Репутация: 2
    Статус: Offline
    fakirr999: кнопка любая - опрос состояния кнопки происходит только один раз - в setup(), при включении питания.

    Возможности машины зависят от фантазии человека...
     
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Arduino - вопросы и ответы. » Управление двумя устройствами от 1 ардуино (Переключение блоков программы кнопкой)
    • Страница 1 из 1
    • 1
    Поиск:

    ДВ Робот - Чат