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

В проекте есть импровизированный счетчик (с вырезом в виде полукруга и рычагом с сервоприводом). При запуске программы (кнопка 2) рычаг переместится влево в положение «9 часов». Оказавшись на месте, после короткой задержки программа примет ввод с кнопки 1 и будет вести счет, перемещая рычаг в положение «3 часа», останавливаясь на 10-2 Вт с задержкой 2 секунды. Когда он достигает позиции, он останавливает счет и запоминает ее.

Повторите то же самое, но с кнопками 4 и 5 соответственно. Очень важно, чтобы счетчик сохранялся для обеих кнопок 1 и 5.

Нажатие кнопки 3 будет измерять входы кнопки 5 и отображать их на счетчике как соотношение нажатий кнопки 5 к количеству нажатий кнопки 1 и кнопки 5. Если он наклонен вправо, это означает, что вы сделали больше жимов на первом этапе, чем на втором (для простоты понимания у меня, вероятно, будут инструкции, в которых говорится, что нужно начинать с правой руки, так что наклон вправо означает доминирование правой руки, а левая — левша). Ниже приведено изображение моей установки.

*Я пронумеровал кнопки 1–5 слева направо, а не по номеру контакта.

Проблема заключается в том, что после нажатия кнопки 2 или 4 сервопривод снова и снова перемещается в семь позиций, которые я установил в качестве таймера.

#include <Servo.h>

const int button1 = 2;   // кнопка 1 контакт/левый главный контакт
const int button2 = 3;   // кнопка 2 контакт/левый стартовый контакт
const int button3 = 4;   // кнопка 3 контакт/правый главный контакт
const int button4 = 5;   // кнопка 4 пин/правый стартовый пин
const int button5 = 6;   // кнопка 5 пин/результаты пин
const int servoPin = 9;  // вывод серводвигателя

int count1 = 0;          // счетчик для кнопки 1
int count2 = 0;          // счетчик для кнопки 5

Servo servo;             // объект серводвигателя

void setup() {
  // устанавливаем контакты кнопок в качестве входов
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);

  servo.attach(servoPin); // прикрепляем серводвигатель к штифту
}

void loop() {
  if (digitalRead(button2) == HIGH) {  // если нажата кнопка 2
    // переместить серводвигатель в положение 9 часов
    servo.write(180);
    delay(500);  // ждем пока сервопривод достигнет позиции

    // начинаем принимать ввод с кнопки 1
    while (digitalRead(button1) == LOW) {
      count1++;  // увеличиваем счетчик
      // переместить серводвигатель в положение на 3 часа
      servo.write(180);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(150);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(120);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(90);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(60);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(30);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(0);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      
    }

    // повторяем тот же процесс для кнопки 4
    while (digitalRead(button4) == LOW) {
      count2++;  // увеличиваем счетчик
      // переместить серводвигатель в положение на 3 часа
      servo.write(180);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(150);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(120);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(90);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(60);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(30);
      delay(2000);  // ждем пока сервопривод достигнет позиции
      servo.write(0);
      delay(2000);  // ждем пока сервопривод достигнет позиции
    }
  }

  if (digitalRead(button3) == LOW) {  // если нажата кнопка 3
    // рассчитываем соотношение нажатий кнопки 4 к общему количеству нажатий кнопки
    float ratio = (float)count2 / (count1 + count2);

    // Отображение коэффициента на счетчике
    servo.write(90 + (int)(ratio * 90));
  }
}

Настройка Arduino

, 👍-1

Обсуждение

вести счет, перемещая рычаг в сторону 3 часов... ваш код не ведет счет, пока сервопривод движется, @jsotola

Не могли бы вы объяснить, пожалуйста?, @user87900

ваш код: «переместить сервопривод, пауза, переместить сервопривод, пауза и т. д.» во время движения сервопривода другого кода нет, @jsotola

Вы можете узнать о [конечных автоматах](https://en.wikipedia.org/wiki/Finite-state_machine) и поэкспериментировать с ними. Такой подход, скорее всего, будет правильным., @the busybee

Вы не будете правильно считать нажатия кнопок, если не выполните какое-либо [устранение дребезга](https://learn.adafruit.com/make-it-switch/debouncing). Есть библиотеки, которые могут справиться с этим за вас. Кроме того, как указал Busbee, вам придется узнать о конечных автоматах. Я рекомендую этот [учебник Majenko](https://majenko.co.uk/blog/finite-state-machine)., @Edgar Bonet


1 ответ


0

У вас есть подтягивающие резисторы на всех ваших кнопках, поэтому все ваши входные контакты имеют НИЗКИЙ уровень, когда никто не прикасается к кнопкам. Когда вы нажимаете кнопку, вход становится ВЫСОКИМ. В вашем коде, когда вы делаете

  if (digitalRead(button2) == HIGH) {  // если нажата кнопка 2

он входит в блок if, если кнопка нажата, потому что вход button2 имеет высокий уровень, когда кнопка нажата. Затем вы перемещаете сервопривод в положение 180 и немного ждете. Следующая строка

    while (digitalRead(button1) == LOW) {

входит в цикл while, если на входном контакте низкий уровень. Входной контакт - это то, что когда кнопка НЕ нажата, из-за подтягивающего резистора, и поэтому сервопривод начинает двигаться при нажатии кнопки 2, если только кнопка 1 не нажата, когда вы нажимаете кнопку 2. Чтобы остановить это, измените LOW на HIGH в условии цикла while. Тогда он войдет в цикл while только при нажатии кнопки и пропустит его, если она не нажата..

Как подсказал Busybee, вам может быть полезно изучить конечные автоматы.

,

Та же проблема в в то время как (digitalRead (button4) == LOW) { и if (digitalRead(button3) == LOW) { // если нажата кнопка 3, @jkp