2 кнопки, 1 сервопривод, поворот только при нажатии
У меня проблема с кодом. Мне нужно повернуть сервопривод по часовой стрелке или против часовой стрелки, используя 2 микропереключателя.
Проблема в том, что мой код работает нормально при запуске, но когда я нажимаю кнопку, сервопривод продолжает вращаться.
Как мне сделать так, чтобы он вращался только при нажатии кнопок и выключался, когда они не нажаты?
#include <Servo.h>
Servo myservo; // создаем сервообъект для управления сервоприводом
// КОНСТАНТЫ
// PIN-коды
const int crServo = 12; // устанавливает контакт 12 как сервопривод
const int buttonPinCW = 2; // устанавливает контакт 2 как кнопку; по часовой стрелке => по часовой стрелке => ФОКУС ДАЛЕКО
const int buttonPinCC = 3; // устанавливает контакт 3 как кнопку; СС => против часовой стрелки => ФОКУСИРОВАТЬ БЛИЖЕ
// СВОЙСТВА СЕРВО
const int crSpeedDefault = 0; // неподвижное положение, двигатель не должен вращаться
const int crSpeedCW = 110; // вращаем двигатель на полной скорости по часовой стрелке
const int crSpeedCC = 70; // поворачиваем двигатель на полную скорость против часовой стрелки
// УСТАНОВИТЬ СОСТОЯНИЯ КНОПКИ
int buttonStateCW = 0; //устанавливает кнопку 1 как выключенную
int buttonStateCC = 0; // отключаем кнопку 2
void setup()
{
myservo.attach(crServo); // прикрепляем сервопривод к контакту 12 к объекту сервопривода
pinMode (crServo, OUTPUT);
pinMode (buttonPinCW, INPUT); // устанавливает кнопку в качестве ввода
pinMode (buttonPinCC, INPUT); // устанавливает кнопку в качестве ввода
myservo.write(crSpeedDefault); // сервопривод по умолчанию crSpeedDefault
}
void loop()
{
crServo = digitalRead(crSpeedDefault);
buttonStateCW = digitalRead(buttonPinCW);
buttonStateCC = digitalRead(buttonPinCC);
// вращение по часовой стрелке
if (buttonStateCW == HIGH) {
myservo.write(crSpeedCW);
// вращение против часовой стрелки
}
if (buttonStateCC == HIGH) {
myservo.write(crSpeedCC);
}
}
@Richard, 👍0
Обсуждение2 ответа
Если вам нужна логика "если ни одна из двух кнопок не нажата, сервопривод немедленно остановится", то вы должны выразить это в своем цикле
как if
выражение, в котором вы проверяете, читаются ли обе кнопки LOW
:
void loop()
{
buttonStateCW = digitalRead(buttonPinCW);
buttonStateCC = digitalRead(buttonPinCC);
// вращение по часовой стрелке
if (buttonStateCW == HIGH) {
myservo.write(crSpeedCW);
// вращение против часовой стрелки
}
if (buttonStateCC == HIGH) {
myservo.write(crSpeedCC);
}
// Обе кнопки не нажаты?
if(buttonStateCC == LOW && buttonStateCW == LOW) {
// Остановить сервопривод.
myservo.write(0);
}
}
Это предполагает, что ваши кнопки снабжены подтягивающими резисторами к GND с одной стороны и +5 В с другой стороны, как подробно описано в Учебное пособие по Arduino. Вкратце это означает, что ненажатая кнопка читается как 0
, а нажатая читается как 1
(HIGH
). Это необычно, потому что мы обычно используем внутренние подтягивающие резисторы через параметр INPUT_PULLUP
pinMode
с переключаемой логикой (1
= не нажат, 0
= нажато).
Я также удалил строку crServo = digitalRead(crSpeedDefault);
, потому что, на мой взгляд, это не имеет смысла, как я подробно описал в своем комментарии.
спасибо, Максимилиан, я думаю, что это должно быть в проводке моего переключателя, редактирование кода, которое вы прислали, заставляет их непрерывно вращаться в любом направлении при нажатии кнопки. Я думаю, мне нужно посмотреть, как я подключаю их к Uno, так как здесь что-то не так., @Richard
Пожалуйста, отредактируйте свой вопрос, чтобы показать свою схему., @Maximilian Gerhardt
извините за задержку, хорошо, кнопки идут к GND и к входным контактам 2 и 3 (есть 2 кнопки с 1 по 2 и с 1 по 3), @Richard
затем сервопривод отрывается от 12 и также подключается к GND и +5v, @Richard
@Richard Когда вы редактируете свой вопрос, вы заметите кнопку инструмента «Схема», с помощью которой вы можете точно представить свою схему., @Maximilian Gerhardt
@Richard, в моем ответе в операторе if была ошибка копирования-вставки, которая могла привести к сбою. Повторите попытку., @Maximilian Gerhardt
Это решение похоже на решение @Maximilian Gerhardt. Так что его комментарии о подтягивающих/понижающих резисторах применимы.
Я предполагаю, что вы хотите вращать только CW или CC и не колебаться между ними.
Тогда вы должны выполнить 4 условия кнопки:
Ни один из них не нажат, только CW, только CC, оба нажаты.
Нам нужно беспокоиться только об условиях "только нажатие" и состоянии по умолчанию при кодировании.
Вот мое решение:
void loop()
{
buttonStateCW = digitalRead(buttonPinCW);
buttonStateCC = digitalRead(buttonPinCC);
// нажата только кнопка CW
if (buttonStateCW == HIGH && buttonStateCC == LOW) {
myservo.write(crSpeedCW); // вращение по часовой стрелке
}
// Только нажата кнопка CC
else if (buttonStateCW == LOW && buttonStateCC == HIGH) {
myservo.write(crSpeedCC); // вращение против часовой стрелки
}
// Условие по умолчанию
else {
myservo.write(crSpeedDefault);
}
}
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Как справиться с rollover millis()?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'
У вас есть внешний выпадающий список на кнопках?, @Maximilian Gerhardt
Привет, Максимилиан. Да, у меня есть колесо, которое вручную вращается пользователем. Идея в том, что когда руль поворачивается на 180 градусов, нажимается микропереключатель. Это поворачивает сервопривод в одном направлении, противоположное — поворачивает сервопривод в противоположном направлении., @Richard
Я имел в виду подтягивающий резистор. Логика вашей прошивки заключается в том, что если на контакте кнопки написано «HIGH», он нажат. Таким образом, у вас должна быть кнопка, подключенная через выпадающее меню к GND, а другая сторона к + 5 В, верно? Также: почему там есть строка
crServo = digitalRead(crSpeedDefault);
? Приconst int crServo = 12
переменная не может быть изменена. Нет смысла перезаписывать вывод сервопривода в 0 или 1, используя результатdigitalRead
, который считывается с вывода 0, который является последовательным TX Arduino., @Maximilian Gerhardt