Помогите дописать скетч по управлению сервоприводом

son32
Offline
Зарегистрирован: 04.12.2017

Всем доброго времени суток!!! Прошу помощи дописать скетч!!! Суть моего проекта такова: есть Ардуина, к ней подключенна скажем кнопка, и сервопривод. Работать все это дело должно так: ход привода от 40 до 0 град, при нажатии на кнопку и или ее удержании сервопривод отрабатывает с 40 до 0, в нуле находится пол секунды(500) и возвращается в положение 40, и более не двигается, пока не будет отпущена и нажата кнопка. то есть за одно нажатие кнопки один цикл работы сервопривода 40 0 40. самому что то пока сложновато понять как это сделать, пробовал какие то варианты и либо вообще скетч не работает или идет зациклиная бесконечная работа сервы((

вот мой скетч:

#include <Servo.h>
Servo servo;
int angle = 40;
int swPin = 30;
int buttonState = 0;
 
void setup() {
    pinMode(swPin, INPUT);
    digitalWrite(swPin, HIGH);
    servo.attach(22);
}
 
void loop() {
  buttonState = digitalRead(swPin);
   if (buttonState == HIGH) {
    servo.write(angle);
    delay (100);
    servo.write(0);
    }
}
но при таком скетче при нажатии на кнопку серва переходит в положение 0 и в нем находится пока зажата кнопка, только после отпускания кнопки возвращается в исходное положение 40.
b707
Offline
Зарегистрирован: 26.05.2017

son32 пишет:

но при таком скетче при нажатии на кнопку серва переходит в положение 0 и в нем находится пока зажата кнопка, только после отпускания кнопки возвращается в исходное положение 40.

он делает то, что описано в скетче. Последние три строчки - дернуть серву в положение 40 на 0.1 сек и вернутся в 0 - это оно и делает.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
#include <Servo.h>
Servo servo;

#define angle 40
#define swPin 30

uint8_t buttonState;
 
void setup() {
    pinMode(swPin, INPUT_PULLUP);
    servo.attach(22);
    servo.write(angle);
    buttonState = digitalRead(swPin);
}
 
void loop() {
   if (buttonState != digitalRead(swPin)) {
      servo.write(0);
      delay(500);
      servo.write(angle);
      buttonState = digitalRead(swPin);    
   } 
}

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

son32, у Вам в коде объявлено 3 глобальные простые переменные. Две из них никогда не изменяют значения, следовательно, это - константы. Третья, по сути, - переменная локальная.

Т.е. глобальных переменных то у Вас и нет совсем.

А должны быть.

Если Вам нужно произвести некоторую последовательность действий, следует разбить эту последовательность на простейшие фазы, ввести переменную состояния, значение которой будет номером текущей фазы, а потом, в процессе выполнения для текущей фазы выполнять характерные для нее действия и проверять условия для перехода к следующей фазе.

Например:

0 фаза - ожидание нажатия на кнопку, серво в положении 40, при нажатии на кнопку переходит в фазу 1,

1 фаза - движение сервы от 40 до 0, при достижении 0 переходит в фазу 2,

2 фаза - ожидание 0.5 сек, по истечение вреиени - переходит в фазу 3,

3 фаза - движение от 0 до 40, по достижении 40 переходит в фазу 4,

4 фаза - ожидание отпускания кнопки, при отпускнии переходит в фазу 0.

Примечание: с фазы 1 до начала фазы 4 кнопку не анализируем.

son32
Offline
Зарегистрирован: 04.12.2017

brokly. Огромное СПАСИБО!!! Это то что нужно, но только вот маленькая проблемка))) когда сигнал на 30 пин появляется серва отрабатывает как нужно 40 0 40 и более не двигается пока сигнал на 30 пине висит, но когда я сигнал размыкаю она серва повтора отрабатывает заданные параметры. есле вам не трудно можее подсказать как исключить это пвторное срабатывание при размыкании сигнала?

son32
Offline
Зарегистрирован: 04.12.2017

andriano, Большое спасибо за разьяснение!!! мне пока сложно вникать в написание кодов, а вот на примерах вроде чего то получается))) сейчас просто учеба и экзамены и голова совсем другим забита, а свой строящийся проэкт хочется по немногу делать))) но все равно СПАСИБО за разъяснения!!!

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

son32 пишет:

brokly. Огромное СПАСИБО!!! Это то что нужно, но только вот маленькая проблемка))) когда сигнал на 30 пин появляется серва отрабатывает как нужно 40 0 40 и более не двигается пока сигнал на 30 пине висит, но когда я сигнал размыкаю она серва повтора отрабатывает заданные параметры. есле вам не трудно можее подсказать как исключить это пвторное срабатывание при размыкании сигнала?

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

son32 пишет:

... при нажатии на кнопку и или ее удержании сервопривод отрабатывает с 40 до 0, в нуле находится пол секунды(500) и возвращается в положение 40, и более не двигается, пока не будет отпущена ...

Это же вы писали.

#include <Servo.h>
Servo servo;
 
#define angle 40
#define swPin 30
 
void setup() {
    pinMode(swPin, INPUT_PULLUP);
    servo.attach(22);
    servo.write(angle);
}
 
void loop() {
   if (LOW == digitalRead(swPin)) {
      servo.write(0);
      delay(500);
      servo.write(angle);
   } 
}

Как то так. Но тут есть определенная натяжка в работе с кнопкой. Повесте в параллель кнопке конденсатор от 0.01 до 0.1 мкф. Ну или быстрее отпускайте кнопку.

 

son32
Offline
Зарегистрирован: 04.12.2017

на самом деле в конечном устройстве кнопки не будет(кнопка нужна временно для отладки механизма), то есть с абсолютно с другого устройства будет подаваться сигнал, то есть по проводу будет появлятся минус на 30 пин ардуино, при появлении сигнала нужно что бы отработал серво привод однакратно 40 0 40. и нужно что бы серва больше не двигалась до условий пока сигнал не повторится. просто в моем устройстве сигнал(минус) на 30 пин может висеть долго и когда он пропадает серва не должна двигаться, ее движение только однократно и при появлении сигнала(минуса) на пин. больше все таки ваш первый скеч подходит.

Прошу прощение если как то не внятно и не правильно объясняю!!! 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Тогда так:

 

#include <Servo.h>
Servo servo;
 
#define angle 40
#define swPin 30
 
void setup() {
    pinMode(swPin, INPUT_PULLUP);
    servo.attach(22);
    servo.write(angle);
}
 
void loop() {
   if (LOW == digitalRead(swPin)) {
      servo.write(0);
      delay(500);
      servo.write(angle);
      while (LOW == digitalRead(swPin));
   } 
}

 

son32
Offline
Зарегистрирован: 04.12.2017

brokly, ОГРОМНОЕ ВАМ СПАСИБО ОТ ВСЕЙ ДУШИ!!! ЭТО ТО ЧТО НУЖНО!!! РАБОТАЕТ ОТЛИЧНО!!! При этом этот же скетч я использую для второго привода только с другим условием работы, сигнал приходит серва стоит, как только сигнал ушол серва однократно отрабатывает и стоит. всего лишь изменил в скетче LOW на HIGH))) Еще раз огромное СПАСИБО!!!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ПС: Это альтернатива.

/**/
unsigned long mill; // переменная под millis()
typedef void (*pDo)(); // тип - функция обработчик
//--------------------------------
// класс сервопривод
#include <Servo.h>
class Cl_Servomotor {
  protected:
    const int angle = 40;
    byte pin;
    unsigned long past;
    Servo servo;
    byte state;//состояние сервомотора
    /*устатановить сервомотора в состояние*/
    void stand(byte state_) {
      state = state_;
      past = mill;
      switch (state) {
        case 0:
          servo.write(angle);
          Serial.println("Servo 40");
          break;
        case 1:
          servo.write(0);
          Serial.println("Servo 0");
          break;
      }
    }
  public:
    /*конструктор*/
    Cl_Servomotor(byte pin_): pin(pin_) {
      Servo servo;
    }
    /*инициализация- вставить в setup*/
    void init() {
      servo.attach(pin);
      stand(0);
    }
    /*работа- вставить в loop*/
    void run() {
      if (state == 1 && mill - past >= 500) stand(0);
    }
    /*сработать*/
    void work() {
      stand(1);
    }
};
//--------------------------------
// класс кнопка
class Cl_Btn {
  protected:
    byte pin;
    pDo Do;
    bool bounce = 0;
    bool btn = 1, oldBtn;
    unsigned long past;
  public:
    /*конструктор*/
    Cl_Btn(byte pin_, pDo Do_)
      : pin(pin_), Do(Do_) {}
    /*инициализация- вставить в setup*/
    void init() {
      pinMode(pin, INPUT_PULLUP);
    }
    /*работа- вставить в loop*/
    void run() {
      bool newBtn = digitalRead(pin);
      if (!bounce && newBtn != btn) {
        bounce = 1;
        past = mill;
      }
      if (bounce && mill - past >= 10) {
        bounce = 0 ;
        oldBtn = btn;
        btn = newBtn;
        if (!btn && oldBtn) Do();
      }
    }
};
//---Компоновка-----------------------------
Cl_Servomotor Servomotor(/*пин*/5);
void DoBtn1() {
  Servomotor.work();
}
Cl_Btn Btn1(/*пин*/2,/*обработчик*/&DoBtn1);
//---main-----------------------------
void setup() {
  Serial.begin(9600);
  Servomotor.init();
  Btn1.init();
}

void loop() {
  mill = millis();
  Servomotor.run();
  Btn1.run();
}
/*Скетч использует 3570 байт (11%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 265 байт (12%) динамической памяти, оставляя 1783 байт для локальных переменных. Максимум: 2048 байт.
*/

 

son32
Offline
Зарегистрирован: 04.12.2017

qwone, пасибо, я попробую разобраться с вашим кодом, как время будет))) но код brokly мне больше подходит из за компактности и простоты)) А вообе всем спасибо за помощь, поддержку и внимание!!! как чуток подсоберу свой проект постараюсь не забыть выложить его здесь или ссылку оставить))