Операторы If и while не работают

Второй и третий "while" и "if" не работают, но первые "While" и "if" работают .. Я делаю что-то не так?

#include <DFMiniMp3.h> 

int sw1 = 3;
int sw2 = 4;
int sw3 = 5;

class Mp3Notify
{
  public:
    static void OnError(uint16_t errorCode)
    {
      // значение кода см. в разделе DfMp3_Error
      Serial.println();
      Serial.print("Com Error ");
      Serial.println(errorCode);
    }

    static void OnPlayFinished(uint16_t globalTrack)
    {
      Serial.println();
      Serial.print("Play finished for #");
      Serial.println(globalTrack);
    }

    static void OnCardOnline(uint16_t code)
    {
      Serial.println();
      Serial.print("Card online ");
      Serial.println(code);
    }

    static void OnCardInserted(uint16_t code)
    {
      Serial.println();
      Serial.print("Card inserted ");
      Serial.println(code);
    }

    static void OnCardRemoved(uint16_t code)
    {
      Serial.println();
      Serial.print("Card removed ");
      Serial.println(code);
    }
};
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial); //Создать подключение UART к модулю

void setup()
{

  //3 кнопки с подтягиваниями
  pinMode(sw1, INPUT); // Определите каждую кнопку как ввод с помощью pullup
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);

  digitalWrite (sw1, HIGH); // 12 источников питания Votls установлены в выключенное состояние
  digitalWrite (sw2, HIGH); // 5 источников питания Votls установлены в выключенное состояние
  digitalWrite (sw3, HIGH); // 3 источника питания Votls установлены в выключенное состояние

  Serial.begin(9600);
  mp3.begin(); //Начать связь с модулем DFPlayer
  uint16_t volume = mp3.getVolume(); //Получить фактический объем
  mp3.setVolume(30); //Установить новый объем (максимум 30)
  uint16_t count = mp3.getTotalTrackCount(); // Получаем общее количество треков на SD-карте на случай, если мы захотим подать в суд на это позже...
}

// просто функция, которую мы используем для создания задержек в "мс"
//без использования функции delay()
void waitMilliseconds(uint16_t msWait)
{
  uint32_t start = millis();

  while ((millis() - start) < msWait)
  {
    // периодический вызов mp3.loop() позволяет получать уведомления
    // обрабатывается без прерываний
    mp3.loop();
    delay(1);
  }
}

void loop()
{

  if (digitalRead(sw1) == LOW)
  {
    mp3.playMp3FolderTrack(1); // Воспроизведение звуковой дорожки 0001
    waitMilliseconds(5000); // 1 сек задержки
    while (digitalRead(sw1) == HIGH); // ничего не делать, пока состояние не изменится

  }

  if (digitalRead(sw2) == LOW)
  {
    mp3.playMp3FolderTrack(2); // Воспроизведение звуковой дорожки 0002
    waitMilliseconds(5000); // 1 сек задержки

    while (digitalRead(sw2) == HIGH); // ничего не делать, пока состояние не изменится

  }

  if (digitalRead(sw3) == LOW)
  {
    mp3.playMp3FolderTrack(3); // Воспроизведение звуковой дорожки 0002
    waitMilliseconds(5000); // 1 сек задержки

    while (digitalRead(sw3) == HIGH); // ничего не делать, пока состояние не изменится
  }


}

, 👍0

Обсуждение

* Я делаю что-то не так? * - если альтернативой является то, что операторы while / if не работают, то, конечно, вы делаете что-то не так. Пожалуйста, правильно отформатируйте свой код, и кто-нибудь поможет вам найти ошибку., @Sim Son

@SimSon, исходя из базовой концепции, все выглядит нормально. Мне нужен кто-то, кто помог бы мне с этим., @Habib Anwari

Спасибо за форматирование кода. Код просто ведет себя не так, как вы ожидаете, но эти утверждения определенно работают. Что заставляет вас думать, что они этого не делают? Пожалуйста, добавьте в вопрос свои наблюдения и ожидания., @Sim Son

@SimSon, после "void loop" у меня есть 3 оператора "if". Первый вариант работает, но не второй и не третий. Если я изменил порядок операторов "if", то сработает только первая работа. не имеет значения, какой из операторов "if" помещается после первого оператора "if", но после первого оператора другие не работают., @Habib Anwari

После нажатия sw1 строка while (digitalRead(sw1) == HIGH); просто заставляет его оставаться там, не продолжая работу с остальной частью кода, пока вы снова не нажмете sw1., @ocrdu

Вы должны заменить материал mp3 последовательными печатями в каждом предложении if и цикле while, чтобы отладить это., @Sim Son

@ocrdu, да, это прекрасно. но второе утверждение "если" не работает., @Habib Anwari

@ocrdu на самом деле нет. После того, как выполнение вводит любой из операторов if, цикл while теряет смысл, если состояние кнопки не изменилось, @Sim Son

@Sim-Son Это кнопки, которые меняют состояние при отпускании, и есть задержка, которая дает достаточно времени для этого выпуска., @ocrdu

Работает ли sw2, если вы вообще не нажимали sw1 с момента последнего сброса?, @ocrdu

Может быть, вам лучше взглянуть, как правильно читать кнопку. Цикл выполняется так быстро, что чтение такой кнопки все равно не даст никаких хороших результатов. Вы хотите определить, когда кнопка меняет свое состояние, а не находится ли она в определенном состоянии. Вам также лучше использовать неблокирующий код и избегать задержек, как в примере BlinkWithoutDelay. Если вы будете удерживать нажатыми несколько кнопок и отпускать их случайным образом, вы увидите, что 2. и 3. ifs также выполняются., @Sim Son

@ocrdu, нет. Sw2 и sw3 не работают. Если я изменю порядок на sw2, sw3, sw3. Теперь sw2 работает. Если я изменю порядок на sw3, sw2, sw1, тогда sw3 будет работать. Я продолжаю нажимать на все кнопки, но работает только первое утверждение "если", а не другие., @Habib Anwari

@ocrdu да, вы правы. Фактически, после завершения цикла while 1 соответствующий оператор if немедленно вводится повторно на следующей итерации цикла, если не нажата кнопка 2 или 3., @Sim Son

Не продолжайте нажимать все кнопки, сбросьте Arduino и нажмите только sw2. Работает ли тогда sw2?, @ocrdu

@ocrdu, нет, не работает. Работает только первый оператор if., @Habib Anwari

Как вы узнаете, нажали ли вы sw2 только после сброса? Прокомментируйте задержки и циклы while. Значит, все кнопки работают?, @ocrdu

@ocrdu, 1- Источник питания отключен. 2 - теперь источник питания включен. 3- ни один из переключателей не подключен. 3- переключатель номер один удерживается нажатым. 4- Воспроизводится MP3. 5- выпущен sw1. 6- нажата кнопка sw2. 6. ничего не происходит. 7- sw1 нажат и отпущен, чтобы увидеть, нуждается ли он в сбросе. 8- sw2 нажат, отпущен, удерживается> ничего не происходит. 10- если код sw2 перемещен выше оператора sw1 "if", то sw2 работает., @Habib Anwari


1 ответ


Лучший ответ:

2

После нажатия sw1работает первый if. После отпускания sw1 (это кнопка) строка while (digitalRead(sw1) == HIGH); заставит код просто сидеть там вечно, не продолжая работу с остальной частью кода, пока вы снова не нажмете sw1, что будет перехвачено первым if, если вы не отпустите 'sw1' бесчеловечно быстро.

Итак, как только вы нажмете и отпустите sw1, остальная часть кода со следующими двумя ifs никогда не будет запущена.

,

ваше последнее утверждение выглядит правильным, но почему-то оно не может решить проблему. Если я удерживал sw1 нажатой и нажимал sw2, то sw2 начинал работать. Теперь только sw2 функции sw1 не работают. Переключение блокируется на sw2. но когда я все сбрасываю, оно возвращается к sw1., @Habib Anwari

Циклы while блокируют выполнение. Возможно, это сработает так, как вы задумали, если вы удалите их и немного сократите задержки., @ocrdu

Я использую проигрыватель DFmini. Это хорошо работает, если нажать и отпустить кнопку. Но в моем случае кнопку нужно будет удерживать нажатой. проблема с удерживанием кнопки нажатой заключается в том, что MP3 воспроизводится снова и снова. Я хочу, чтобы он воспроизводился только один раз, если выход высокий и кнопка или удерживается нажатой в течение длительного времени. Если я уберу "пока", то он будет воспроизводиться снова и снова. не останавливается., @Habib Anwari

Если вы используете блокировку задержки, ни одна кнопка не будет реагировать в течение времени задержки и повторится только по истечении времени задержки. Или же отключите кнопки (вы можете посмотреть это) и используйте длительное время отключения, в основном отключая кнопку и человека., @ocrdu