#1 2015-05-10 22:32:39

cako79
Учасник
З Минск
Зареєстрований: 2015-05-10
Повідомлень: 10

управление сервоприводом нужен ваш совет.

Добрый день форумчане, нужна ваша объективная оценка кода,это мой первый код.
Суть кода в следующем , есть три режима управление сервоприводом:1 режим это изменение положения сервы кнопками,2 режим это изменения положения сервы от реле(реле разомкнуто одно положение сервы, при замкнутых контактах серва переходит в другое положение. 3 режим управление удаленно) код работает ,но коряво..(1. пока не переключишь все режимы, серва плохо отзывается на нажатие кнопок 2. есть дрожание сервы в крайних положениях)Пока на железку не переносил, делал симуляцию в программе Proteus 7.Буду рад дельным советам.



#include <Servo.h> 


int angle = 0;          //Текущий угол поворота (при запуске программы будет автоматический вставать в указаное положение)
int maxAngle = 170;      //Максимальный угол поворота сервомотора (градусов)
int minAngle = 10;        //Минимальный угол поворота сервомотора (градусов)
int angleStep = 2;       //Угол единичного шага (градусов)
int stepSpeed = 15;      //Скорость шага (скорость поворота)(задержка шага
int valM; //переменная для блютуза подпрограммы

int ButPinR = 7; // Подключаем реле входа  к выходу 7

int R_LedPin = 13; // Подключаем красный светодиод к порту 13
int G_LedPin = 12; // Подключаем зеленый светодиод к порту 12
int B_LedPin = 11; // Подключаем синий светодиод к порту 11
int ButPin = 10; // Подключаем кнопку управление режимами  к выходу 10
int L  = 5; // Подключаем кнопку  управление сервой вверх к выходу 5
int R  = 4; // Подключаем кнопку к управлению сервой вниз к выходу 4
int flag = 0; // флаг состояния
int regim = 0; // Переключалка

int valL = 0;            //Переменная вверх кнопки
int valR = 0;            //Переменная вниз кнопки

Servo servoMain;   // название сервомашины
int servoPin = 3;   // сервомотор подключен на пин 3

void setup()
{
Serial.begin(9600);
servoMain.attach(3);
servoMain.write(90); // выставляем начальный угол сервы
pinMode(L,INPUT);        //Цифровой PIN 2 входной сигнал для кнопки "Влево"
pinMode(R,INPUT);        //Цифровой PIN 3 входной сигнал для кнопки "Вправо"
pinMode(R_LedPin, OUTPUT);
pinMode(G_LedPin, OUTPUT);
pinMode(B_LedPin, OUTPUT);
pinMode(ButPinR,INPUT);        // реле
}

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

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

if(digitalRead(ButPin) == LOW && flag == 1)
{
flag = 0;
}

// ======= Вполняем задачу при выборе режима =======

// РЕЖИМ 1: R                                     // РЕЖИМ УПРАВЛЕНИЕ СЕРВЫ кнопками
if(regim == 1)
{
digitalWrite(R_LedPin, HIGH);
digitalWrite(G_LedPin, LOW);
digitalWrite(B_LedPin, LOW);


{
valR=digitalRead(L);      //Читает и запоминает положение левой кнопки
valL=digitalRead(R);      //Читает и запоминает положение правой кнопки

if((valL==HIGH)&&(valR==LOW))       //Если левая кнопка нажата а правая нет тогда:
{angle=angle+angleStep;             //тогда угол поворота сервомотора меняется по шагово на величину шага (то есть движется  влево по 2 градуса до максималтного угла 180 градусов)
if(angle>maxAngle)                  //Если угол поворота достиг максимального равного 180 градусам,тогда:
{angle=maxAngle;} 
                //он остается равным максимальному
}



if((valL==LOW)&&(valR==HIGH))       //Все тоже самое как для предыдущей функции но с !инверсией
{angle=angle-angleStep;             //
if(angle<minAngle)                  //
{angle=minAngle;} 
                   //
}

{servoMain.write(angle);
delay(stepSpeed);}                 //Скорость шагов (задержки шагов)


}
}
// РЕЖИМ 2: G
if(regim == 2)                           // РЕЖИМ УПРАВЛЕНИЕ СЕРВЫ ОТ  РЕЛЕ
{
digitalWrite(R_LedPin, LOW);
digitalWrite(G_LedPin, HIGH);
digitalWrite(B_LedPin, LOW);




     if(digitalRead(ButPinR)==HIGH)//если контакты реле  замкнуты ...

     {
        servoMain.write(5);
     }

     else//если не замкнуты...

     {

     servoMain.write(90);
         delay(500);
     }}

      

    


// РЕЖИМ 3: B                          // РЕЖИМ УПРАВЛЕНИЕ СЕРВЫ ПО COM-порту         
if(regim == 3)
{digitalWrite(R_LedPin, LOW);
digitalWrite(G_LedPin, LOW);
digitalWrite(B_LedPin, HIGH);
if (Serial.available())
{
valM = Serial.read();

if (valM == 'W')
{
  servoMain.write(5),Serial.println("серва w "); // При символе "W" серва принимает нулевую позицию
}

if ( valM == 'S')
{
  servoMain.write(170),Serial.println("серва s "); //При символе "S" серва принимает 90 градусов позицию
delay(250);
}

}

}}

Неактивний

#2 2015-05-11 00:09:36

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 878

Re: управление сервоприводом нужен ваш совет.

кнопки у вас не борются с дребезгом - отсюда могут быть проблемки с управлением
как организовано питание сервы
ну и от делеев надо уходить
и неплохо бы код приводить в читабельный вид

Неактивний

#3 2015-05-11 00:55:32

cako79
Учасник
З Минск
Зареєстрований: 2015-05-10
Повідомлень: 10

Re: управление сервоприводом нужен ваш совет.

питание сервы отдельной линией идет... а насчет дребезга я кнопки подключал через  подтягивающий резистор номиналом 10к. А каким образом от делеев  можно уйти?

Остання редакція cako79 (2015-05-11 00:57:29)

Неактивний

#4 2015-05-11 08:05:44

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 878

Re: управление сервоприводом нужен ваш совет.

резистор 10 ком к дребезгу контактов кнопки не имеет никакого отношения и пока эту проблему программно не решите (примеров в сети тьма, есть библиотекa Bounce) будут глюки.
от делеев избавляемся используя millis()
посмотрите пример в IDE  Blink without delay

Неактивний

#5 2015-05-11 13:48:41

cako79
Учасник
З Минск
Зареєстрований: 2015-05-10
Повідомлень: 10

Re: управление сервоприводом нужен ваш совет.

спасибо огромное. я так понял  используя функцию  millis() , мне понадобиться переписывать весь код.. sad  Буду разбираться

Неактивний

#6 2015-05-12 09:18:03

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 878

Re: управление сервоприводом нужен ваш совет.

ага smile

Неактивний

#7 2015-05-16 17:48:17

cako79
Учасник
З Минск
Зареєстрований: 2015-05-10
Повідомлень: 10

Re: управление сервоприводом нужен ваш совет.

кстати насчет функции millis, насколько я понял у ее есть предел примерно  50 дней. потом счет переполняться. Как быть  что бы устройство работало допустим около года?

Неактивний

#8 2015-05-17 09:50:39

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 878

Re: управление сервоприводом нужен ваш совет.

у вас сервопривод год работать будет? big_smile

Неактивний

#9 2015-05-17 21:16:49

cako79
Учасник
З Минск
Зареєстрований: 2015-05-10
Повідомлень: 10

Re: управление сервоприводом нужен ваш совет.

если брать не из дешевых, и если он включается  пару раз за день, то почему и нет?)

Неактивний

#10 2015-06-16 10:43:51

Саша Паскаль
Гість

Re: управление сервоприводом нужен ваш совет.

vvr пише:

кнопки у вас не борются с дребезгом - отсюда могут быть проблемки с управлением
как организовано питание сервы
ну и от делеев надо уходить
и неплохо бы код приводить в читабельный вид

Совершенно верно! Могу дать дельный совет (проверено на практике) Используй реле. Борется с дребезгом без проблем. И надо уходить от delay. Когда выполняется delay arduino не реагирует на кнопки. Вместо delay можно сделать что-то типа этого:

void loop()
{
   //bla_bla_bla
  unsigned long a = millis()
  while(millis()-1000 < a);
  //bla_bla_bla
}

(вместо delay(1000).)

И ксати, можно использовать прерывания.

#11 2015-06-18 20:29:05

DesignMSP
Учасник
Зареєстрований: 2014-06-23
Повідомлень: 15

Re: управление сервоприводом нужен ваш совет.

"-есть дрожание сервы в крайних положениях" - изменить тайминги сервы, не давать ей работать за пределами допустимых углов. Вы даже не представляет как они прекрасно выгорают из-за этого  smile Каждая серва имеет свой "тайминг" (вбить в гугле). 0-180гр. означает что ардуино пошлет свой тайминг по умолчанию и может случится так (обычно так и происходит) что серва либо не довернет до установленного угла или уйдет за пределы диапазона (вы легко это узнаете по температуре сервомотора).
upd также не забывайте про "рычаг". Если исполнительный рычаг слишком велик, а серва расчитана к примеру на 3кг/см, а вы повесили на нее рычаг 10 см с грузом 1 кг, то конечно сервомотор будет пытатся довернуть на заданый угол, но ему не будет хватать мощности сделать это, отсюда и дрожание.
на последок, дрожание также часто бывает из-за дефекта сервомотора - а именно некачественного полотна подстроечного резистора ООС внутри сервы. Действие - поменять мотор.

Остання редакція DesignMSP (2015-06-18 20:33:26)

Неактивний

#12 2015-10-15 16:34:16

wildamd
Гість

Re: управление сервоприводом нужен ваш совет.

ну реле использовать как решение от дребезга это как молится богу и в паре-тройке случаев если прокатило думать что он есть big_smile

на самом деле решение с дребезгом самое простое

делаешь таймер, и 2 глобальных переменные.
в таймере накручиваешь логику: если нажата кнопка, увеличивать переменную1 до ххх, где ххх - значение в зависимости от частоты таймера иначе переменная1=0, переменная2=0. и тут же проверяешь - если значение переменной1 достигло максимума тогда переменная2=1.

результатом такой логики будет ожидание заполнения переменной1 временем ххх, что исключает дребезг кнопки. и в таком случае можно не использовать фильтр в виде конденсатора, а подтягивать достоточно не внешними резисторами, а режимом "входа" ножек МК. на С это ddra=0x00, porta=0x01 - пин0 будет входом, подтянутым к +.

#13 2015-10-15 16:34:27

wildamd
Гість

Re: управление сервоприводом нужен ваш совет.

ну реле использовать как решение от дребезга это как молится богу и в паре-тройке случаев если прокатило думать что он есть big_smile

на самом деле решение с дребезгом самое простое

делаешь таймер, и 2 глобальных переменные.
в таймере накручиваешь логику: если нажата кнопка, увеличивать переменную1 до ххх, где ххх - значение в зависимости от частоты таймера иначе переменная1=0, переменная2=0. и тут же проверяешь - если значение переменной1 достигло максимума тогда переменная2=1.

результатом такой логики будет ожидание заполнения переменной1 временем ххх, что исключает дребезг кнопки. и в таком случае можно не использовать фильтр в виде конденсатора, а подтягивать достоточно не внешними резисторами, а режимом "входа" ножек МК. на С это ddra=0x00, porta=0x01 - пин0 будет входом, подтянутым к +.

#14 2015-10-15 16:34:55

wildamd
Гість

Re: управление сервоприводом нужен ваш совет.

ну реле использовать как решение от дребезга это как молится богу и в паре-тройке случаев если прокатило думать что он есть big_smile

на самом деле решение с дребезгом самое простое

делаешь таймер, и 2 глобальных переменные.
в таймере накручиваешь логику: если нажата кнопка, увеличивать переменную1 до ххх, где ххх - значение в зависимости от частоты таймера иначе переменная1=0, переменная2=0. и тут же проверяешь - если значение переменной1 достигло максимума тогда переменная2=1.

результатом такой логики будет ожидание заполнения переменной1 временем ххх, что исключает дребезг кнопки. и в таком случае можно не использовать фильтр в виде конденсатора, а подтягивать достоточно не внешними резисторами, а режимом "входа" ножек МК. на С это ddra=0x00, porta=0x01 - пин0 будет входом, подтянутым к +.

#15 2015-10-20 13:12:51

Alex Wels
Гість

Re: управление сервоприводом нужен ваш совет.

wildamd пише:

ну реле использовать как решение от дребезга это как молится богу и в паре-тройке случаев если прокатило думать что он есть big_smile

на самом деле решение с дребезгом самое простое

делаешь таймер, и 2 глобальных переменные.
в таймере накручиваешь логику: если нажата кнопка, увеличивать переменную1 до ххх, где ххх - значение в зависимости от частоты таймера иначе переменная1=0, переменная2=0. и тут же проверяешь - если значение переменной1 достигло максимума тогда переменная2=1.

результатом такой логики будет ожидание заполнения переменной1 временем ххх, что исключает дребезг кнопки. и в таком случае можно не использовать фильтр в виде конденсатора, а подтягивать достоточно не внешними резисторами, а режимом "входа" ножек МК. на С это ddra=0x00, porta=0x01 - пин0 будет входом, подтянутым к +.

А то есть добавить библиотеку Debounce ну никак ни разу.
Нееее надо городить хламокод.

#16 2015-10-20 13:13:05

Alex Wels
Гість

Re: управление сервоприводом нужен ваш совет.

wildamd пише:

ну реле использовать как решение от дребезга это как молится богу и в паре-тройке случаев если прокатило думать что он есть big_smile

на самом деле решение с дребезгом самое простое

делаешь таймер, и 2 глобальных переменные.
в таймере накручиваешь логику: если нажата кнопка, увеличивать переменную1 до ххх, где ххх - значение в зависимости от частоты таймера иначе переменная1=0, переменная2=0. и тут же проверяешь - если значение переменной1 достигло максимума тогда переменная2=1.

результатом такой логики будет ожидание заполнения переменной1 временем ххх, что исключает дребезг кнопки. и в таком случае можно не использовать фильтр в виде конденсатора, а подтягивать достоточно не внешними резисторами, а режимом "входа" ножек МК. на С это ddra=0x00, porta=0x01 - пин0 будет входом, подтянутым к +.

А то есть добавить библиотеку Debounce ну никак ни разу.
Нееее надо городить хламокод.

#17 2017-03-04 18:23:34

no
Гість

Re: управление сервоприводом нужен ваш совет.

слушай, а ты это всё когда писал - то ?!!! yikes  neutral  cool

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму