Удалить блокирующую функцию delay() toneMelody?

Я хотел бы изменить delay() на неблокирующую функцию в коде ниже. Я реализовал его (часть урока от arduino.cc) в моем коде, но delay() блокирует остальную часть моего кода. Может ли кто-нибудь помочь мне изменить это?

void speelMelodie(int melodie){

if(melodie == 1){

      for (int thisNote = 0; thisNote < 8; thisNote++) {

      int noteDuration = 1000 / noteDurations1[thisNote];
      tone(speaker, melody1[thisNote], noteDuration);

      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes); // <-- this one has to be changed

      noTone(speaker);
      }
  }

else if (melodie == 2) {
      // the same part as previous part (for loop)
  }


else if (melodie == 3) {
      // the same part as previous part (for loop)
  }
}

, 👍2

Обсуждение

Посмотрите на пример программы Arduino, BlinkWithoutDelay (File | Examples | Digital | BlinkWithoutDelay). Он использует millis() для определения длительности периодов "включения" и "выключения" светодиода - именно то, что вы хотите сделать с тоном., @JRobert

Вы изучали примеры и учебные пособия о millis()? Вы их поняли? Что именно мешает вам изменить свой код на `millis ()'?, @chrisl

Да, есть, но я не знаю, как реализовать это в своем коде. У меня есть 5 разных мелодий, как и вышеприведенные фрагменты., @Joost

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

@Fahad , у меня есть много другого кода, я вызываю эту функцию. но из-за задержки в этой функции я не могу делать с остальными входами вне этой функции., @Joost


1 ответ


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

1

Определите глобальные параметры для настройки()

unsigned long timeStamp = 0; 
bool pauseOn = false;

и используйте его

void speelMelodie(int melodie) {

  if (melodie == 1) {

    for (int thisNote = 0; thisNote < 8; thisNote++) {

      int noteDuration = 1000 / noteDurations1[thisNote];
      if (millis() - timeStamp < noteDuration && pauseOn == false) {
         tone(speaker, melody1[thisNote], noteDuration);
      } else { // сбросьте значение и измените значение паузы на true
        pauseOn = true;
        timeStamp = millis();
      }
      int pauseBetweenNotes = noteDuration * 1.30;

      //delay(pauseBetweenNotes); // <-- это было изменено
      if (millis() - timeStamp < pauseBetweenNotes && pauseOn == true) {
          noTone(speaker);
      } else {
         pauseOn = false;
         timeStamp = millis();
      }
    }
  }
}

Нам нужна переменная состояния pauseOn, чтобы различать два состояния воспроизведения ноты или тишины. Код компилируется, но вы должны выполнить настройку в своей программе.
последний совет, в котором используется функция delay() , кроме

  • для отладки или
  • в настройке для инициализации оборудования

имеют очень низкое качество
-> Это похоже на то, как слепой человек говорит о цветовой композиции.

,

Спасибо за это, но сейчас я получаю только две записки., @Joost

Опубликуйте свой код полностью, отредактировав свой вопрос-трудно найти ошибки во фрагментах, возможно, не связанных с реальной проблемой, @Codebreaker007

Это часть функции, которую я вызываю в другом месте, поэтому она должна быть в этой части. Весь код очень большой., @Joost

Тогда вам придется найти его самостоятельно. Теперь функция не блокируется, и, поскольку мы не знаем кода rest, она может быть вызвана где угодно (проверьте наличие других задержек() и избавьтесь от них), поэтому, по крайней мере, предоставьте полную функцию, если вам нужна дополнительная помощь (и необходимые библиотеки - только часть include и глобальные переменные, используемые в функции), @Codebreaker007

Хорошо. Сначала я попробую это сделать сам. В противном случае, когда я застряну, я попрошу вас о помощи., @Joost

В нем все еще была задержка (), так что это действительно было ошибкой. остальная часть функции является повторением данной части. Я отредактировал свой код выше., @Joost

Теперь у меня есть постоянный сигнал "стоп-старт", @Joost

Сначала вы должны применить мои изменения в одном и том же wy ко всем трем частям. Затем убедитесь, что ваш цикл не вызывает постоянно speelMelodie с новыми параметрами. Вы можете сделать это с помощью второго bool changeMelodie = true/false; таким образом, цикл по-прежнему входит в функцию без каждого изменения параметров. Скопируйте эту часть вызывающего абонента(цикл) с некоторыми строками до и после и примерной структурой, что еще происходит в цикле, @Codebreaker007

Может быть, вы могли бы привести мне пример? Для меня это все еще не совсем ясно., @Joost

Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/106182/discussion-between-joost-and-codebreaker007)., @Joost