Код для сервы MG 996R, работающей от датчика движения

Coder8
Offline
Зарегистрирован: 29.08.2020
Хотелось бы сделать так, чтобы серва крутилась только в одну сторону при засечении движения.
Сейчас она крутится вообще все время.
Код ниже.
Что в нем не так?
Coder8
Offline
Зарегистрирован: 29.08.2020
/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#define pirPin 7
#define servoPin 6
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  Serial.begin(9600); // Объявляем работу com порта со скоростью 9600
  pinMode(pirPin, INPUT); // Объявляем пин, к которому подключен датчик движения, входом
  pinMode(servoPin, OUTPUT); // Объявляем пин, к которому подключен сервомотор, выходом
  
  myservo.attach(6);  // attaches the servo on pin 2 to the servo object

  for (pos = 0; pos <= 360; pos += 180) { // goes from 0 degrees to 360 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  /*for (pos = 360; pos >= 0; pos -= 1) { // goes from 360 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }*/
}

void loop() {
  int pirVal = digitalRead(pirPin); // Считываем значение с датчика движения. Если обнаружили движение, 
                                    // то транслируем сигнал тревоги в монитор порта и включаем сервомотор

  if(pirVal == HIGH)
  {
    digitalWrite(servoPin, HIGH);
    Serial.print("Тревога ");
    delay(2000);
  }
  else
  {
    Serial.print("Сканирую ");
    digitalWrite(servoPin, LOW);
    delay(1000);  
  }                                   
  /*for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }*/
}

 

Coder8
Offline
Зарегистрирован: 29.08.2020

Причина скорее всего не в датчике движения. Проверил на 2-х датчиках.

В коде же есть HIGH и LOW для servoPin.

Почему тогда серво крутится постоянно?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Coder8 пишет:

В коде же есть HIGH и LOW для servoPin.


Для чего?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Господи! Неужели реально всех в гугле забанили???

https://coolcode.ru/arduino-upravlenie-servoprivodom-na-primere-sg90/

Coder8
Offline
Зарегистрирован: 29.08.2020

sadman41 пишет:
Coder8 пишет:

В коде же есть HIGH и LOW для servoPin.

Для чего?

Чтобы подавать и убирать напражение на/с сервы.

Coder8
Offline
Зарегистрирован: 29.08.2020

BOOM пишет:

Господи! Неужели реально всех в гугле забанили???

https://coolcode.ru/arduino-upravlenie-servoprivodom-na-primere-sg90/

 

Ну да, это то же самое, что я закомментил в строки 53 - 60.

Так тоже пробовал.

Вот:

Coder8
Offline
Зарегистрирован: 29.08.2020
#define pirPin 7
#define servoPin 6
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  Serial.begin(9600); // Объявляем работу com порта со скоростью 9600
  pinMode(pirPin, INPUT); // Объявляем пин, к которому подключен датчик движения, входом
  pinMode(servoPin, OUTPUT); // Объявляем пин, к которому подключен сервомотор, выходом
  
  myservo.attach(6);  // attaches the servo on pin 2 to the servo object
}

void loop() {
  int pirVal = digitalRead(pirPin); // Считываем значение с датчика движения. Если обнаружили движение, 
                                    // то транслируем сигнал тревоги в монитор порта и включаем сервомотор

  if(pirVal == HIGH)
  {
    digitalWrite(servoPin, HIGH);
    Serial.print("Тревога ");
    delay(2000);
  }
  else
  {
    Serial.print("Сканирую ");
    digitalWrite(servoPin, LOW);
    delay(1000);  
  }                                   
  for (pos = 0; pos <= 360; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 360; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

 

Coder8
Offline
Зарегистрирован: 29.08.2020

Здесь серво крутится по и против часовой стрелки и никак не реагирует на сигналы с датчика движения.

b707
Offline
Зарегистрирован: 26.05.2017

Coder8 пишет:

Чтобы подавать и убирать напражение на/с сервы.

а нахрена?   Вы явно вообще не понимаете, как работает серва.

Coder8 пишет:

серво крутится по и против часовой стрелки и никак не реагирует на сигналы с датчика движения.

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

Запомните, сервы НЕ УПРАВЛЯЮТСЯ НАПРЯЖЕНИЕМ!!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

Запомните, сервы НЕ УПРАВЛЯЮТСЯ НАПРЯЖЕНИЕМ!!

пневматическая что ли, али гидравлическая?

Coder8
Offline
Зарегистрирован: 29.08.2020

b707 пишет:

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

Запомните, сервы НЕ УПРАВЛЯЮТСЯ НАПРЯЖЕНИЕМ!!

Да, поменял код. Серва крутится против часовой стрелки. Это так и надо. Но почему-то очень медленно. Это особенность MG 996R 360 или что? По часовой крутится быстрее. Как сделать так, чтобы против часовой стрелки серва тоже быстро вращалась?

Вот код:

Coder8
Offline
Зарегистрирован: 29.08.2020
 if(pirVal == HIGH)
  {
      myservo.write(360);
      delay(10000);
      myservo.write(90);
      delay(10000);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

покажите весь код

sadman41
Offline
Зарегистрирован: 19.10.2016

Как мне помнится - серва 360 отличается от обычной тем, что цифирь во write() задаёт не градус поворота, а скорость и направление вращения. Отсюда и делайте выводы - как ускорить и как остановить.

Coder8
Offline
Зарегистрирован: 29.08.2020
#define pirPin 7
#define servoPin 6
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  Serial.begin(9600); // Объявляем работу com порта со скоростью 9600
  pinMode(13, OUTPUT);
  
  pinMode(pirPin, INPUT); // Объявляем пин, к которому подключен датчик движения, входом
  pinMode(servoPin, OUTPUT); // Объявляем пин, к которому подключен сервомотор, выходом
  
  myservo.attach(6);  // attaches the servo on pin 2 to the servo object
}

void loop() {
  
  int pirVal = digitalRead(pirPin); // Считываем значение с датчика движения. Если обнаружили движение, 
                                    // то транслируем сигнал тревоги в монитор порта и включаем сервомотор

  if(pirVal == HIGH)
  {
      digitalWrite(13, HIGH);
    //for(pos = 0; pos <= 360; pos += 180) {
      servoslow(myservo, 360, 10, 0);
      //delay(10000);
      //myservo.write(90);
      //delay(10000);
      
    Serial.print("Тревога ");
  }
  else
  {
    digitalWrite(13, LOW);
    digitalWrite(servoPin, LOW);
    Serial.print("Сканирую ");
  }                                   
}



void servoslow(Servo num, int pos, int time, int start) // Функция для управления скоростью сервопривода
{
  num.write(start);

  for(int i=start; i<pos; i++)
    {
      num.write(i);
      delay(time);
    }
}
Coder8
Offline
Зарегистрирован: 29.08.2020

Coder8 пишет:

#define pirPin 7
#define servoPin 6
#include <Servo.h>

Добавил функцию. Сейчас быстро крутится против часовой стрелки.

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

Как можно убрать движение по часовой стрелке?

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

Как ее можно остановить?

Вот снял на телефон

https://drive.google.com/file/d/1wV9qqQLHiWOzCaTzQccmIYUD5CpHNxU9/view?usp=sharing

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

Coder8 пишет:

Coder8 пишет:

#define pirPin 7
#define servoPin 6
#include <Servo.h>

Добавил функцию. Сейчас быстро крутится против часовой стрелки.

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

Как можно убрать движение по часовой стрелке?

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

Как ее можно остановить?

Вот снял на телефон

https://drive.google.com/file/d/1wV9qqQLHiWOzCaTzQccmIYUD5CpHNxU9/view?usp=sharing

Все эти вопросы следует разделить на три группы:

1. Какого поведения Вы хотите добиться от сервы?

2. Какие сигналы надо подавать, чтобы серва вела себя так, как нужно?

3. Как заставить МК подавать на серву нужные сигналы?

По сути дела к Ардуино здесь имеют отношения только вопросы группы 3.

Поэтому могу посоветовать для начала самостоятельно подробно расписать ответы на группы 1 и 2.

Coder8
Offline
Зарегистрирован: 29.08.2020

1. Какого поведения Вы хотите добиться от сервы?

Движение против часовой стрелки на полный оборот (360 градусов) при срабатывании датчика движения.

И остановка, если датчик движения ничего не засекает.

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

Coder8 пишет:

1. Какого поведения Вы хотите добиться от сервы?

Движение против часовой стрелки на полный оборот (360 градусов) при срабатывании датчика движения.

И остановка, если датчик движения ничего не засекает.

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

Coder8
Offline
Зарегистрирован: 29.08.2020
void loop() {
  
  int pirVal = digitalRead(pirPin); // Считываем значение с датчика движения. Если обнаружили движение, 
                                    // то транслируем сигнал тревоги в монитор порта и включаем сервомотор

  if(pirVal == HIGH)
  {
      digitalWrite(13, HIGH);
    //for(pos = 0; pos <= 360; pos += 180) {
      myservo.attach(6);  // attaches the servo on pin 2 to the servo object
      servoslow(myservo, 360, 10, 0);
      //delay(10000);
      //myservo.write(90);
      //delay(10000);
      
    Serial.print("Тревога ");
  }
  else
  {
    digitalWrite(13, LOW);
    myservo.detach();
    //digitalWrite(servoPin, LOW);
    Serial.print("Сканирую ");
  }                                   
}

 

Coder8
Offline
Зарегистрирован: 29.08.2020

Coder8 пишет:

void loop() {
  
  int pirVal = digitalRead(pirPin); // Считываем значение с датчика движения. Если обнаружили движение, 
                                    // то транслируем сигнал тревоги в монитор порта и включаем сервомотор

Как такой вариант?

Прописал attach и detach для сервы в цикле.

Сейчас останавливается, если датчик движения не срабатывает.

Правда отказ по часовой пока остался..

Coder8
Offline
Зарегистрирован: 29.08.2020

andriano пишет:

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

То есть покапаться в настройках датчика? Оранжевые подстроечные резисторы?

Coder8
Offline
Зарегистрирован: 29.08.2020

Мне кажется, его надо как-то выровнять на 0. То есть он откатывается на 0 или что-то в этом роде..

Подскажите пож-та ссылку на ролик Youtube, кто знает

Coder8
Offline
Зарегистрирован: 29.08.2020
Добавить myservo.write(0) ? 
Не помогает.
 
Подскажите плиз, кто знает
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Coder8 пишет:

andriano пишет:

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

То есть покапаться в настройках датчика? Оранжевые подстроечные резисторы?

Нет.

Сначала грамотно сформулировать задачу.

b707
Offline
Зарегистрирован: 26.05.2017

Coder8 пишет:

1. Какого поведения Вы хотите добиться от сервы?

Движение против часовой стрелки на полный оборот (360 градусов) при срабатывании датчика движения.

И остановка, если датчик движения ничего не засекает.

я не пойму, отчего вы все -  новички  - боитесь лишнее слово сказать?  Опасаетесь ляпнуть глупость и хотите казаться умнее? -бестолку!!, на этом форуме это не поможет, у нас тут слова "новичок" и "идиот" - тождественны.

Теперь к сути. Того, что вы написали выше - недостаточно. Допустим, серва повернулась на 360 при срабатывании датчика. Что она делает дальше? Остается в этом положении (360)? Откатывается назад на ноль?

Если первое - осталась на 360- что будет при следующем сигнале от датчика? - повернется еще на 360 с итоговым положением 720?

Если второе - возвращается на наль - то как быстро?

ну и так далее в том же стиле описывайте ВСЮ СВОЮ ПРОГРАММУ

Coder8
Offline
Зарегистрирован: 29.08.2020

andriano пишет:

Нет.

Сначала грамотно сформулировать задачу.

1. Какого поведения Вы хотите добиться от сервы?

Движение против часовой стрелки при срабатывании датчика движения. Движение в течение 5 секунд. 

И потом через 5 секунд остановка, если датчик движения ничего не засекает.

Без откатов на 0 градусов. Просто остановка через 5 секунд.

Потом, если датчик засекает движение, снова движение против часовой в течение 5 секунд и так далее по кругу.

Coder8
Offline
Зарегистрирован: 29.08.2020

b707 пишет:

Если второе - возвращается на наль - то как быстро?

ну и так далее в том же стиле описывайте ВСЮ СВОЮ ПРОГРАММУ

2. Какие сигналы надо подавать, чтобы серва вела себя так, как нужно?

При засечении движения нужно:
- включить серву,
- задать движение против часовой стрелки. Только вот на сколько градусов, если крутиться будет 5 секунд? То есть это нужно опытным путем расчитать, на сколько градусов поворачивается серва за 5 секунд и это значение проставить? И тогда не будет отката назад?
- задать задержку 5 сек.
 
Если движение не засекается, нужно отключить серву.
 
Coder8
Offline
Зарегистрирован: 29.08.2020

andriano пишет:

3. Как заставить МК подавать на серву нужные сигналы?

if(pirVal == HIGH)
  {
    digitalWrite(13, HIGH);
    myservo.attach(6);  // attaches the servo on pin 2 to the servo object
    servoslow(myservo, 360, 10, 0);
    delay(5000);
  }
  else
  {
    digitalWrite(13, LOW);
    myservo.detach();
  }              

Тут нужно вместо 360 градусов и/или 10 расчитать значения? 

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Так поставьте флаг на то, что серва уже повернулась. Снимите его, когда датчик будет неактивен (или через 5 сек., но тогда уберите delay из программы)

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

Coder8 пишет:

- задать движение против часовой стрелки. Только вот на сколько градусов, если крутиться будет 5 секунд? То есть это нужно опытным путем расчитать, на сколько градусов поворачивается серва за 5 секунд и это значение проставить? И тогда не будет отката назад?

Судя по Вашим вопросам , Вы неправильно выбрали "железо".
Серва нужна тогда, когда требуется повернуться на определенный угол (вне зависимости от времени), а если нужно крутиться определенное время, то выбирать следует не серву, а электромотор.
SAB
Offline
Зарегистрирован: 27.12.2016

andriano пишет:

 то выбирать следует не серву, а электромотор.

Я бы выбрал специальный электромотор - шаговый 

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

SAB пишет:

andriano пишет:

 то выбирать следует не серву, а электромотор.

Я бы выбрал специальный электромотор - шаговый 

А какая разница, если нужно только 5 секунд и только в одну сторону?

Coder8
Offline
Зарегистрирован: 29.08.2020

mykaida пишет:

Так поставьте флаг на то, что серва уже повернулась. Снимите его, когда датчик будет неактивен (или через 5 сек., но тогда уберите delay из программы)

И как это поможет убрать откат назад? Не совсем понимаю. Объясните пож-та.

Coder8
Offline
Зарегистрирован: 29.08.2020

andriano пишет:

Судя по Вашим вопросам , Вы неправильно выбрали "железо".
Серва нужна тогда, когда требуется повернуться на определенный угол (вне зависимости от времени), а если нужно крутиться определенное время, то выбирать следует не серву, а электромотор.

SAB пишет:

Я бы выбрал специальный электромотор - шаговый 

А разве нельзя просто градусы увеличить?

Например, если полный оборот 360 градусов серва делает за секунду,  то 360 x 5 = 1800 градусов и будет 5 секунд или нет?