roboforum.ru

Технический форум по робототехнике.
Текущее время: 30 ноя 2024, 05:03

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Подскажите с кодом
СообщениеДобавлено: 27 янв 2014, 16:10 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
Добрый день!
Я достаточно недавно начал заниматься программированием Arduino, и попробовав все простые примеры решил сделать что то свое. Мой взгляд остановился на манипулятора. Под рукой оказалась всего 4 сервы SG90. Поэтому движения у нас следующие: поднимаем, опускаем, поворот лево/право и соответственно захват и отпустить.
Написал вот такой скетч (захват клешни пока не написан):
Код:
#include <Servo.h>

Servo ser1; // серва 1
Servo ser2; // серва 2
Servo ser3; // серва 3
Servo ser4; // серва 4

byte pos = 0; // позиция сервы 1
byte pos2 = 0; // позиция сервы 2
byte pos3 = 0; // позиция сервы 3
byte pos4 = 0; // позиция сервы 4

const byte buttonPin1 = 8; // порт для кнопки вверх серва 1
const byte buttonPin = 12; // порт для кнопки вниз серва 1
const byte buttonPin2 = 7; // порт кнопки вправо серва 2
const byte buttonPin3 = 4; // порт кнопки влево серва 2
const byte buttonPin4 = 3; // порт кнопки захват сервы 3,4
const byte buttonPin5 = 2; // порт кнопки отпустить сервы 3,4

byte buttonState; // кнопка 1 серва 1 (вниз)
byte buttonState1; // кнопка 2 серва 1 (вверх)
byte buttonState2; // кнопка 3 серва 2 (вправо)
byte buttonState3; // кнопка 4 серва 2 (влево)
byte buttonState4; // кнопка 5 серва 3,4 захват
byte buttonState5; // кнопка 6 серва 3,4 отпустить

void setup ()
{
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buttonPin5, INPUT);
}

void loop ()
{
  buttonState = digitalRead (buttonPin);
  buttonState1 = digitalRead (buttonPin1);
  buttonState2 = digitalRead (buttonPin2);
  buttonState3 = digitalRead (buttonPin3);
  buttonState4 = digitalRead (buttonPin4);
  buttonState5 = digitalRead (buttonPin5);
 
  if (buttonState == HIGH) // опускаем
  for(pos = 1; pos < 80; pos += 1) 
  { 
    ser1.attach(9);   
    ser1.write(pos);         
    delay(20);
    ser1.detach();
    break;
  }
 
if (buttonState1 == HIGH) // поднимаем
for(pos = 80; pos > 1; pos-=1) 

    ser1.attach(9);
    ser1.write(pos);               
    delay(20);
    ser1.detach();
    break;               
}

   if (buttonState2 == HIGH) // поворот влево
   for(pos2 = 1; pos2 < 180; pos2 += 1) 
  { 
    ser2.attach(11);   
    ser2.write(pos2);           
    delay(20);
    ser2.detach();
    break;
  }
   if (buttonState3 == HIGH) // поворот вправо
   for(pos2 = 180; pos2 > 1; pos2 += 1) 
  { 
    ser2.attach(11);   
    ser2.write(pos2);           
    delay(20);
    ser2.detach();
    break;
  }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 27 янв 2014, 16:57 
Не в сети
Аватара пользователя

Зарегистрирован: 01 сен 2009, 14:58
Сообщения: 1142
Откуда: Чехия
прог. языки: C/С++, VHDL, Verilog, ASM, Python
А о чем вопрос?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 27 янв 2014, 17:02 
Не в сети

Зарегистрирован: 31 окт 2013, 01:04
Сообщения: 14
Откуда: Великий Новгород
прог. языки: Delphi
я конечно ни с Arduino ни с сервами неработал, поэтому не понимаю зачем полный цикл, но вот последний будет работать странно..
Код:
   if (buttonState3 == HIGH) // поворот вправо
   for(pos2 = 180; pos2 > 1; pos2 += 1) 
  { 
    ser2.attach(11);   
    ser2.write(pos2);           
    delay(20);
    ser2.detach();
    break;
  }
}

pos2 будет менятся от 180 до 255


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 27 янв 2014, 18:58 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
да без разницы, что там и как в этом цикле меняется. сервам нужно постоянно импульсы подавать, с подобным кодом ничего хорошего в принципе не может быть.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 28 янв 2014, 17:20 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
Цитата:
я конечно ни с Arduino ни с сервами неработал, поэтому не понимаю зачем полный цикл, но вот последний будет работать странно..

Ошибку нашел, код переделал. Вопрос в том как его правильно оформить, и как лучше написать продолжение для того чтобы захват работал (одновременно 2 сервы).

Код:
/* Рука манипулятор, с движениями вверх, вниз, поворотом манипулятора и захватом предметов. Работает на 4 сервоприводах с кнопочным управлением. */

#include <Servo.h>

Servo ser1; // серва 1
Servo ser2; // серва 2
Servo ser3; // серва 3
Servo ser4; // серва 4

byte pos = 0; // позиция сервы 1
byte pos2 = 0; // позиция сервы 2
byte pos3 = 0; // позиция сервы 3
byte pos4 = 0; // позиция сервы 4

const byte buttonPin1 = 8; // порт для кнопки вверх серва 1
const byte buttonPin = 12; // порт для кнопки вниз серва 1
const byte buttonPin2 = 7; // порт кнопки вправо серва 2
const byte buttonPin3 = 4; // порт кнопки влево серва 2
const byte buttonPin4 = 3; // порт кнопки захват сервы 3,4
const byte buttonPin5 = 2; // порт кнопки отпустить сервы 3,4

byte buttonState; // кнопка 1 серва 1 (вниз)
byte buttonState1; // кнопка 2 серва 1 (вверх)
byte buttonState2; // кнопка 3 серва 2 (вправо)
byte buttonState3; // кнопка 4 серва 2 (влево)
byte buttonState4; // кнопка 5 серва 3,4 захват
byte buttonState5; // кнопка 6 серва 3,4 отпустить



void setup ()
{
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buttonPin5, INPUT);
 
  ser1.attach(9);
  ser2.attach(11);
}



void loop ()
{
  buttonState = digitalRead (buttonPin);
  buttonState1 = digitalRead (buttonPin1);
  buttonState2 = digitalRead (buttonPin2);
  buttonState3 = digitalRead (buttonPin3);
  buttonState4 = digitalRead (buttonPin4);
  buttonState5 = digitalRead (buttonPin5);
 
if (buttonState == HIGH) // опускаем
int up = up_down1 ();
 
if (buttonState1 == HIGH) // поднимаем
int down = up_down2 ();

if (buttonState2 == HIGH) // поворот влево
int left = go_left ();

if (buttonState3 == HIGH) // поворот вправо
int right = go_right ();
}

int up_down1 ()
{
  for(pos = 1; pos < 80; pos += 1) 
  {   
    ser1.write(pos);         
    delay(20);
    return 0;
  }
}

int up_down2 ()
{
  for(pos = 80; pos > 1; pos-=1) 

    ser1.write(pos);               
    delay(20);
    return 0;   
}
}
 
int go_left ()
{
   for(pos2 = 1; pos2 < 180; pos2 += 1) 
  {     
    ser2.write(pos2);           
    delay(20);
    return 0;
  }
}

int go_right ()
{
   for(pos2 = 180; pos2 > 1; pos2 -= 1) 
  {     
    ser2.write(pos2);           
    delay(20);
    return 0;
  }
}


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


Можно подробнее? Я сделал отключение серв для того чтобы не дребезжали.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 28 янв 2014, 18:03 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
можно :) только с начала внятно опишите, что хотите сделать и что именно не получается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 28 янв 2014, 21:15 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
1) Как иправить код чтобы сервы при простое не дребезжали? Я рассматривал изначально вариант каждый раз в цикле for прописывать ser.attach()..........ser.detach()....break;Для того чтобы при отпускании кнопки серва отключалась и оставалась в той позиции до какой успела повернуться.
2) Можно ли захват сделать таким образом:
If(...........)
{
for(........) - серва 1
{
....
}
for(..............) - серва 2
{
....
}
}
Если нет то как лучше? (Клещи у манипулятора на 2х сервах).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 28 янв 2014, 22:15 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
не особо что-то прояснилось. :) значит и нет смысла напрягаться, особо детально/доходчиво описывать и вытягивать клещами.
при отключении питания или прекращении подачи импульсов, вал сервы может вращаться под внешним воздействием. на сколько легко - это вопрос ушатанности "разработанности" механики и собственно механики самой сервы, а они по факту очень разные. "оставалась в той позиции" - это ни о чём. если она ничего не удерживает, это одно - отключили питание или прекратили подавать импульсы и всё. а если нужно что-то удерживать, так смотря какая механика у клешни, нюансы с сервой, что нужно удерживать и в каком положении. с дрожанием аналогично - смотря как дрожит и как именно хочется что бы не дрожала. может достаточно будет подать другое напряжение или попытаться в коде с импульсами поиграться или попробовать номиналы деталек на плате поменять, а может эти сервы на большее не способны, по крайней мере без замены электроники и/или потенциометра. так может их лучше сразу на другие заменить и не мучаться.
как в коде реализовать - это ситуационно, вариантов море. попробуйте допустим со своим кодом одновременно 2 кнопки нажать. хотя бы подумайте что будет и устраивает ли это вас.
вот один ленивый вариант:
1) опрос кнопок
2) вылавливаине дребизга при нажатии, если это нужно
3) вычисление значения положения для каждой сервы
4) установка значения положения для каждой сервы
5) топаем в п. 1
если нужно добавляйте проверку на изменение значения переменных, что бы лишний раз лишний код не дёргать. можно подобавлять проверку времени, что бы слишком часто что-то не делать. и т.д. в общем что добавить, выкинуть, поменять местами, объединить, разделить,... это сами думайте. вариант далеко не единственный и при определённых условиях легко может оказаться очень неудобным или не эффективным. абсолютно нет желания гадать, что именно у вас там не получается, что и как сейчас хотите сделать и тем более что в будущем захотите.
дальше наверно сами :) вытягивать клещами каждый нюансик, который может всё кардинально менять нет никакого желания.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 03:56 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
Спасибо за советы. Но у нас немного получается разговор глухого с немым. :)
1) Вопрос был четкий будет ли приведенный выше код работать для захвата 2-х серв?
2)Сервы слабенькие SG-90, соответственно ничего тяжелого поднимать не будут. Идею с тем что отключать не желательно понял.
3) Можно ли использовать break в цикле for для остановки вращения при отпускании кнопки (при нажатии положение будет считываться и серва поворачиваться дальше)?
4) Никакой механики у клешни, 2 захвата крепятся на 2 сервы и ВСЕ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 05:37 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
1) вопрос так не звучал. в последней реинкарнации "будет ли приведенный выше код работать для захвата 2-х серв" могу только шутя - кодом сервы не захватишь
2) "слебенькие" и "тяжелое" очень относительно. смотря какой предмет и конструкция клешни. на них вполне реально сделать захват, способный удерживать некоторые предметы с весом в несколько кг
3) икс вас знает, для какого именно кода цикла вы про брэйк спрашивает. можно сделать прерывание по условию, но что за условие вы напишите и что это вам даст
4) сервы 4, степени свободы 3. если под "никакой механики" подразумевалось что-то такое
Вложение:
1.png
1.png [ 32.04 КиБ | Просмотров: 2246 ]

просто две каких пластинки на качалках :) ну... может и выживут
а если серьёзно, уже более-менее вырисовывается, что вы хотите и что не получается. икс с этим дрожанием - видео нет, что там с питанием серв непонятно. а для управления 4-мя сервами + что вы там ещё хотите делать, код на подобии того, что вы приводили выше мягко говоря очень плох. :) и вставите вы там в цикле(ах) брейк или нет, особо роли не играет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 12:49 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
Питание от 4х батареек (было напрямую от ардуины).
Видео выложу.
Несколько КГ это многовато :) конструкция не выдержит. Так как для меньшего гемороя он собран из конструктора LEGO реквизированного у ребенка.
Да пока что 2 пластинки на качалках (это макет). Когда разберусь во всем уже можно и нормальный манипулятор сделать и клешню другую.
Чем плох код? :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 13:36 
Не в сети

Зарегистрирован: 07 авг 2010, 21:29
Сообщения: 1725
Откуда: КМВ
прог. языки: C
ФИО: Андрей
Код ИМХО плох тем что не разделен процесс управления изменением значений и собственно генерация значений.
Я б писал так:

Инициализация таймера.
Лучше подобрать так чтоб весь счет таймера занимал 2000 мсек Если не точно все равно - считаем время тика, пригодится. Настраиваем на выхов прерывания по достижению установленного значения
Инициализация переменных, по одной для каждой сервы, даже лучше массивом. Одномерным, где 0 элемент - первая и так далее
int Servos[128,128,128]
int(или другой тип) Servostimer[XXX,XXX,XXX] //хранит длительность в тиках таймера
int step[1,1,1] //указатель на порядок обрабортки в таймере.
volatile int number=0; Номер текущей обрабатываемой сервы в таймере


Основной цикл
//Перебор номеров кнопок
фор i=0 то 2 (три кнопки "вверх")
Если кнопка нажата Servos[i]++
некст
фор i=3 то 5 (три кнопки "вниз")
Если кнопка нажата Servos[i-3]--
некст
Тут сортируем сервы чем угодно по длительности импульса (по возрастанию) и номера пишем в step[2,0,1] например и пересчитываем в массиве Servostimer значения
Конец основного цикла

Таймер(прерывание)
Если number==4 {Поднимаем все пины серв в "1" (начинаем генерацию импульсов для каждой сервы)
number=0; //обнуляем счетчик
Устанавливаем следующий вызов таймера на конец цикла (Количество тиков таймера на 2000 мсек)-Servostimer[0]-Servostimer[1]-Servostimer[2]
}
Иначе
{
если number>0 тогда {опускаем пин сервы step[number-1]} //Вот что меня глодало, поведение при обработке нулевого элемента. Так - правильно. Хоть и менее красиво.
если number<3 {Читаем Servostimer[step[number]] и пишем значение в счетчик для следующего вызова}
number++
}
конец таймера

Получается что таймер _постоянно__генерит_ импульсы сервам.
Длительность - можно менять кнопками.

_________________
Дым, идущий из всех устройств в помещении предвещает появление электрика.


Последний раз редактировалось RootAdmin 29 янв 2014, 15:58, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 14:39 
Не в сети

Зарегистрирован: 01 окт 2013, 17:37
Сообщения: 8
Спасибо. Попробую.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 15:33 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
>> Чем плох код?
а чем он хорош? что именно вы тем циклом хотите сделать непонятно. в конце цикла у вас то break, то return. перед тем как их в цикле написать, вы хоть пробовали почитать что это такое? если переделаете циклы, что бы они не прерывались, так у вас каждая итерация цикла будет очень долго выполняться. при 80-ти итерациях, с задержкой в 20мс это будет 1600мс, т.е. почти 2 секунды. при 180-ти итерациях 3600мс. нажали на кнопку и проверка, нажата ли кнопка будет через ~2-4 секунды. так чем хорош такой код?
kirill92, то, что RootAdmin написал... так то оно так, только судя по вашему коду можете не потянуть. если не будет получаться, настойчиво рекомендую поставить на компьютере какую среду разработки и хоть немного подучить основы си. для простоты изучения лучше создавать просто консольные приложения.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подскажите с кодом
СообщениеДобавлено: 29 янв 2014, 15:59 
Не в сети

Зарегистрирован: 07 авг 2010, 21:29
Сообщения: 1725
Откуда: КМВ
прог. языки: C
ФИО: Андрей
Можно и помочь. Для разминки ума просто нужно иногда писать что-то отвлеченное. А то OpenCV весь день разбирать - жуть...

_________________
Дым, идущий из всех устройств в помещении предвещает появление электрика.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO