Нужна помощь в работе с сервой

Ruslan82
Offline
Зарегистрирован: 21.05.2012

 зашел в тупик , нужно  чтобы  при нажатии на кнопку , включалось питание сервы (через  транзисторный ключ),  серва поворачивалась на заданный угол  , возвращалась обратно  и отключалось питание . (без  цикла  - 1 раз туда и обратно )

моих  изысканий  хватило  только на это  (вариант без  ключа)

/*
Arduino test
Written by: makray
*/
#include <Servo.h> 
Servo myservo;   
int switchPin = 8;

int ledPin = 13;


void setup()
{
  pinMode(switchPin, INPUT);
  pinMode(ledPin, OUTPUT);
  myservo.attach(9);  // серва подключена к 9-му пину
}

void loop()
{
  if (digitalRead(switchPin) == HIGH)
  {
    digitalWrite(ledPin, HIGH);
    
    delay(1);
    
  {                                   
     
    myservo.write(80);    
    delay(150);   
    
  }                                                 
}  
    else
  {
    digitalWrite(ledPin, LOW);
    delay(50);
    myservo.write(45);
    delay(15);
    
  }
}

 

 

 

Ruslan82
Offline
Зарегистрирован: 21.05.2012

 переделал  , но  нужно  добавить управление ключем 

/*
arduino test
written by makray
*/
#define button 8
#define ledPin 13
#include <Servo.h> //библа
Servo myservo;
boolean buttonState = 0;
void setup() {                
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if(digitalRead(button)){ 
    if(!buttonState){
      digitalWrite(ledPin, HIGH);
      myservo.attach(9); 
    myservo.write(180);
      delay(200);  
      digitalWrite(ledPin, LOW);
      myservo.write(45);
    delay(50);
    myservo.detach();
      buttonState = 1;
    }
  }
  else{
    buttonState = 0;
  }
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

> переделал , но нужно добавить управление ключем

А вы таки уверенны что оно вам нужно? :)

По крайней мере на тех сервах что я пробовал,  myservo.detach(); как раз и давало эффект "отключили мотор от питания". Вибрация сервы "На удержание" пропадала, попыткам крутить ее руками - она больше не сопротивлялась. То есть подобный "ключ" у нее уже имеется внутри  и срабатывает он "по отсутсвию PWM" на управляющем входе, ничего городить дополнительного - не нужно.

 

maksim
Offline
Зарегистрирован: 12.02.2012

Так а в чем вопрос?  добавьте

/*
arduino test
written by makray
*/
#define button 8
#define ledPin 13
#define switchPin 28
#include <Servo.h> //библа
Servo myservo;
boolean buttonState = 0;
void setup() {                
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, OUTPUT);
}

void loop() {
  if(digitalRead(button)){ 
    if(!buttonState){
      digitalWrite(ledPin, HIGH);
      digitalWrite(switchPin, HIGH);
      delay(200); // Задержка, что бы серва успела запуститься
      myservo.attach(9); 
    myservo.write(180);
      delay(200);  
      digitalWrite(ledPin, LOW);
      myservo.write(45);
    delay(50);
    myservo.detach();
    digitalWrite(switchPin, LOW);
      buttonState = 1;
    }
  }
  else{
    buttonState = 0;
  }
}

 Да действительно, а зачем?

Ruslan82
Offline
Зарегистрирован: 21.05.2012

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

весь код будет  записан в  attiny 45/85  

===

maksim

 в вашем примере кода  switchPin - 8  , но в то же  время этот  пин определен за  кнопкой,  это опечатка ?

 

maksim
Offline
Зарегистрирован: 12.02.2012

Так измените на какой вам нужно. 

Ruslan82
Offline
Зарегистрирован: 21.05.2012

maksim пишет:

Так измените на какой вам нужно. 

спасибо  догадался

уже попробовал -не работает  такой способ .   серва коротко срабатывает по 20 градусов примерно при каждом нажатии и дойдя до  конца назад не  возвращается

maksim
Offline
Зарегистрирован: 12.02.2012

Это потому что у вас задержка очень маленькая и серва не успевает. 

/*
arduino test
written by makray
*/
#define button 8
#define ledPin 13
#define switchPin 28
#include <Servo.h> //библа
Servo myservo;
boolean buttonState = 0;
void setup() {                
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, OUTPUT);
}

void loop() {
  if(digitalRead(button)){ 
    if(!buttonState){
      digitalWrite(ledPin, HIGH);
      digitalWrite(switchPin, HIGH);
      delay(300); // Задержка, что бы серва успела запуститься
      myservo.attach(9); 
    myservo.write(180);
      delay(800);  
      digitalWrite(ledPin, LOW);
      myservo.write(45);
    delay(800);
    myservo.detach();
    digitalWrite(switchPin, LOW);
      buttonState = 1;
    }
  }
  else{
    buttonState = 0;
  }
}

 

Ruslan82
Offline
Зарегистрирован: 21.05.2012

 пробовал играться с задержкой - не помогло . 

и кстати увеличение задержки  приводит лишь  к  бОльшему  промежутку во времени между нажатием кнопки и  реакцией сервы. это плохо .. 

leshak
Offline
Зарегистрирован: 29.09.2011

 

Ruslan82 пишет:

нужно максимально уменьшить энергопотребление в ожидании нажатия кнопки,

А вы все-таки проверте сколько кушает ваша серва после detach. Не факт что больше чем ваш ключик в режиме ожидания. В нее, с большой вероятностью уже встроен ключ, а вы городите еще один. Поэтому есть веротность не снизить, а увелчичить вероятность потребления. В зависимости от того насколько характеристики вашего внешнего ключа лучше/хуже встроенного.

>серва коротко срабатывает по 20 градусов примерно при каждом нажатии и дойдя до конца назад не возвращается

И это начала проявлятся только при использовании ключа? По идее ключ ничего не добавил в логику. 

Что делаеть ваш скетч:

Говорит серве: "стань в позицию 180". Серва начинает поворачиватся, но через 200 милесекунд ей говорят "не, крутись на позицию 45" (и совсем не факт что она уже успела занять позицию 180). Серва начинает выполнять новую команду (крутится к 45-ти), на это ей дают 50 милисекунд и вырубают питанию. Куда успела докрутится, туда и успела. если вообще усепела хоть как-то повернутся.

Так что увеличивайте задержки после myservo.write(), дайте серве время на выполнение ваших комманд.

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Ruslan82 пишет:

 пробовал играться с задержкой - не помогло . 

и кстати увеличение задержки  приводит лишь  к  бОльшему  промежутку во времени между нажатием кнопки и  реакцией сервы. это плохо .. 

Это только первая задержка к этому приводит, а остальные пробовали?

/*
arduino test
written by makray
*/
#define button 8
#define ledPin 13
#define switchPin 28
#include <Servo.h> //библа
Servo myservo;
boolean buttonState = 0;
void setup() {                
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, OUTPUT);
}

void loop() {
  if(digitalRead(button)){ 
    if(!buttonState){
      digitalWrite(ledPin, HIGH);
      digitalWrite(switchPin, HIGH);
      delay(300); // Задержка, что бы серва успела запуститься
      myservo.attach(9); 
      myservo.write(180);
      delay(800);  
      digitalWrite(ledPin, LOW);
      myservo.write(45);
      delay(800);
      myservo.detach();
      digitalWrite(switchPin, LOW);
      buttonState = 1;
    }
  }
  else{
    buttonState = 0;
  }
}

 

Ruslan82
Offline
Зарегистрирован: 21.05.2012

 Да это и понятно . буду  запехивать  то  что есть в аттиньку и мерять  ток потребления с ключем и без него .
а пока с ардуино уно мы  кушаем в режиме детача сервы  - 22mA  , когда серва крутит - 170mA

померял и с ключем  в поке - 48mA ,  нефиг , как говорится  забор городить , будем юзать то  что есть 

Спасибо за помощь ребята !

Ruslan82
Offline
Зарегистрирован: 21.05.2012

maksim пишет:

 

Это только первая задержка к этому приводит, а остальные пробовали?


да  это все очень  медленно  , все оставляю как есть , лучше уже не явно будет 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну быстрее чем серва крутится - точно ничего не выйдет, но применял такой подход.

Засекал время сколько занимает поворот от 0 до 180 гр. Отсюда знал время вычисляем время поворота на один градус (делим время на 180).

Вводим переменную где храним "в каком положении сейчас серва" (после каждого myservo.write()), запоминаем куда же мы ее повернули.

И при следующем повороте вычисляем необходимую_задержку=abs(текущие_положение - нужное_положение)*время_поворота_на_градус+небольшой_запас.

Единственный минус - при включении контроллера (в setup()) нужно развернуть серву в 0 и дать задержку "скольколь занимает поворот от 0 до 180"+плюс запас. Что-бы знать "от чего отсчитывать" текущие положение.

При этом подходе, я добивался что "на глаз" серва включалась ровно на время необходимое для поворота и сразу выключалась.

Ruslan82
Offline
Зарегистрирован: 21.05.2012

вот так работает  сейчас , большой  градус не нужен  нужно максимальное  быстродействие  

http://www.youtube.com/watch?v=5CZuKix9sxc

leshak
Offline
Зарегистрирован: 29.09.2011

 >большой градус не нужен нужно максимальное быстродействие

"Большой градус" - понятие растяжимое.

Быстродействие - я вам уже описал общий подход. Как вычислять время необходимое на поворот, что-бы не "тупить больше чем реально необходимо".

Если у вас будет всего две позиции - можно опустить "вычисления" и просто опытно подобрать минимально необходимую задержку перехода межда позициями. Только тогда нужно будет выствлять изначально в setup, серву на одну из этих позиций, что-бы потом не тратить время на "выход в известную позицию".

Дальше - уменьшать угол поворота (например гонять серву не 45 - 180), а 45-90 или еще меньше.

Дальше - искать более быструю серву или еще больше уменьшать угол между позициями и придумывать какой-то рычаг, который будет 5% поворота сервы преобразоывавать в 90% реальных (но тут тоже есть предел - точность сервы).