Как остановить зацикливание сервопривода, если датчик не обнаруживает движения?
У меня есть этот проект с моим Arduino UNO, где я хочу, чтобы мой серводвигатель SG90 шел на полной скорости до 180 градусов, когда датчик PIR посылает ВЫСОКОЕ значение, и медленно возвращался к нулю, когда значение НИЗКОЕ.
У меня есть этот код, работающий там, где сервопривод возвращается на полную скорость к нулю:
#include <Servo.h>
Servo myservo; //создает объект servo
int pos = 0; //переменная для хранения положения сервопривода
//количество времени, которое мы даем датчику для калибровки(10-60 секунд в соответствии с таблицей данных)
int calibrationTime = 30;
//время, когда датчик выдает низкий импульс
long unsigned int lowIn;
//количество миллисекунд датчик должен быть низким
//прежде чем мы предположим, что все движение остановилось
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int pir = 12; //цифровой вывод, подключенный к выходу PIR
int pirPos = 13; //подключается к выводу 5V PIR
void setup() {
myservo.attach(4); //прикрепляет сервопривод к контакту 4
Serial.begin(9600); //начинает последовательную связь
pinMode(pir, INPUT);
pinMode(pirPos, OUTPUT);
digitalWrite(pirPos, HIGH);
//время калибровки
Serial.println("calibrating sensor ");
for (int i = 0; i < calibrationTime; i++) {
Serial.print(calibrationTime - i);
Serial.print("-");
delay(1000);
}
Serial.println();
Serial.println("done");
//это ждет, пока выход PIR не станет низким, прежде чем завершить настройку
while (digitalRead(pir) == HIGH) {
delay(500);
}
Serial.print("SENSOR ACTIVE");
}
void loop() {
if (digitalRead(pir) == HIGH)
myservo.write(180); // скажите сервоприводу перейти в позицию в переменной 'pos'
Serial.print("Motion detected!");
if (digitalRead(pir) == LOW)
myservo.write(0); // скажите сервоприводу перейти в позицию в переменной 'pos'
Serial.print("Motion ended!");
}
Мне бы хотелось, чтобы сервопривод медленно возвращался к нулю, поэтому я попробовал следующее :
#include <Servo.h>
Servo myservo; //создает объект servo
int pos = 0; //переменная для хранения положения сервопривода
//количество времени, которое мы даем датчику для калибровки(10-60 секунд в соответствии с таблицей данных)
int calibrationTime = 30;
//время, когда датчик выдает низкий импульс
long unsigned int lowIn;
//количество миллисекунд датчик должен быть низким
//прежде чем мы предположим, что все движение остановилось
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int pir = 12; //цифровой вывод, подключенный к выходу PIR
int pirPos = 13; //подключается к выводу 5V PIR
void setup() {
myservo.attach(4); //прикрепляет сервопривод к контакту 4
Serial.begin(9600); //начинает последовательную связь
pinMode(pir, INPUT);
pinMode(pirPos, OUTPUT);
digitalWrite(pirPos, HIGH);
//время калибровки
Serial.println("calibrating sensor ");
for (int i = 0; i < calibrationTime; i++) {
Serial.print(calibrationTime - i);
Serial.print("-");
delay(1000);
}
Serial.println();
Serial.println("done");
//это ждет, пока выход PIR не станет низким, прежде чем завершить настройку
while (digitalRead(pir) == HIGH) {
delay(500);
}
Serial.print("SENSOR ACTIVE");
}
void loop() {
if (digitalRead(pir) == HIGH)
myservo.write(180); // скажите сервоприводу перейти в позицию в переменной 'pos'
Serial.print("Motion detected!");
if (digitalRead(pir) == LOW)
for (pos = 180; pos >= 0; pos -= 1) { // переходит от 180 градусов к 0 градусам
myservo.write(pos); // скажите сервоприводу перейти в позицию в переменной 'pos'
delay(15); // ждет 15 мс, пока сервопривод достигнет нужного положения.
}
Serial.print("Motion ended!");
}
Проблема в том, что с этим кодом сервопривод медленно возвращается к нулю, но затем набирает полную скорость до 180 и снова, и снова ...
Есть идеи? Я новичок в Arduino, поэтому предполагаю, что это не так уж трудно понять. Спасибо.
@Nathan Ghali, 👍0
Обсуждение1 ответ
Не устанавливайте pos на 180 в ветви (digitalRead(pir) == LOW)
, если вы не хотите, чтобы он многократно подскакивал до 180 до тех пор, пока условие истинно.
void loop() {
if (digitalRead(pir) == HIGH)
pos = 180;
myservo.write(pos); // скажите сервоприводу перейти в позицию в переменной 'pos'
Serial.print("Motion detected!");
if (digitalRead(pir) == LOW)
for (; pos > 0; pos -= 1) { // распад до 0 градусов
myservo.write(pos); // скажите сервоприводу перейти в позицию в переменной 'pos'
delay(15); // ждет 15 мс, пока сервопривод достигнет нужного положения.
}
Serial.print("Motion ended!");
}
С другой стороны, вы можете использовать pos
в качестве переменной состояния и упростить ситуацию:
void loop() {
if (digitalRead(pir) == HIGH)
pos = 180;
elif (pos > 0 ){
pos--;
delay(15);
}
myservo.write(pos);
}
Если значение pir
НИЗКОЕ, то управляемый скоростью код ОП будет снова и снова циклически переключаться между 180 и нулем., @Dave X
"до тех пор, пока условие истинно" или, может быть, "до тех пор, пока входные данные остаются НИЗКИМИ
". Я собираюсь удалить свои предыдущие комментарии выше (и этот позже), потому что с вашими хорошими разъяснениями они будут выглядеть более несинхронизированными., @timemage
Я вставил код, работает как шарм, большое спасибо вам двоим, ребята !!, @Nathan Ghali
Похоже, вы должны "принять" этот ответ., @timemage
- Вращающийся серводвигатель с использованием Arduino
- Невозможно выйти из цикла while
- Вопросы по сервопрограмме
- Как сбросить/завершить ввод данных с помощью клавиатуры? Arduino Uno кормушка для домашних животных
- Tower Pro MG996R сервопривод с высоким крутящим моментом 180 °, управляющий с помощью Arduino
- Как заставить сервопривод вращаться на угол больше 180°
- Пповорот сервопривода на 90 градусов
- Как синхронно управлять двумя сервоприводами?
Если
(digitalRead(pir) == LOW)
, то вы приказываете сервоприводу перейти на 180 с помощью этой строки:for (pos = 180; pos >= 0; pos -= 1)
, @Dave XЯ бы запустил ваш код через "Инструменты" / "Автоматический формат" в IDE, что вы должны сделать перед публикацией в будущем, для здравомыслия ваших читателей, если не для вашего собственного., @timemage
Ладно, спасибо за подсказку, ребята !!, @Nathan Ghali