|
Управление двумя устройствами от 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 }
...
} как то так. если конкретные девайсы и конкретные задачи сюда прилетят - тоды и скетч конкретнее будет )
Возможности машины зависят от фантазии человека...
|
| |
| |
| 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(), при включении питания.
Возможности машины зависят от фантазии человека...
|
| |
| |