Звуковые библиотеки UNremote и PCM мешают

У меня есть простой скетч, который посылает ИК-коды, воспроизводит звук и переключает светодиод, когда вы нажимаете кнопку, и переключает другой светодиод, когда он получает этот код. Идея заключается в том, что у меня есть два Arduino с этим же скетчем, и когда вы нажимаете кнопку на одном, светодиод переключается, а также другой светодиод на другом Arduino. Эта программа работает по назначению, когда звук не включен.

Вот скетч:


#include <IRremote.h> // Для ИК-передачи и приема
#include <PCM.h> // Для аудиовыхода 

IRsend irsend; // Настройка ИК-передатчика
const int receiver = 8; // Инициализация pin 13 как recevier pin.
IRrecv irrecv(receiver); // Создать новый экземпляр
decode_results results;

// Declare arrays to hold sound notes to play
const unsigned char gunShot[] PROGMEM = {}; // В этом массиве есть огромный список чисел, но я удалил их, чтобы облегчить чтение кода

const unsigned char gunClick[] PROGMEM = {}; // В этом массиве есть огромный список чисел, но я удалил их, чтобы облегчить чтение кода


// declare consants
const int button = 13;
const int greenLight = 7;
const int yellowLight = 2;
const int timeBetweenTransmittion = 800; //  Не менее 800 миллисекунд между двумя передачами
// Динамик закреплен на контакте 11

// объявить переменные
bool toggleGreen = true; // Булевы переменные для переключения огней
bool toggleYellow = true;
long int previousTransmittion = 0; // Длинное целое для хранения метки времени в миллисекундах предыдущей передачи


void setup() 
{
  pinMode(button, INPUT_PULLUP); // Настройка кнопки с внутренним резистором pullup
  Serial.begin(9600);
  irrecv.enableIRIn(); // Включить приемник
  Serial.println("start");
}

void loop() {
  if (not digitalRead(button) && millis() > previousTransmittion + timeBetweenTransmittion) // Если кнопка нажата и прошло достаточно времени с момента последней передачи
  { 
    Serial.println("send!");

    // Different orders of these lines of code were tried:
    
    //startPlayback(gunShot, sizeof(gunShot)); //  Play shot перед отправкой кода и включением приемника (команда play 1 для справки)
    //delay(250);
    
    irsend.sendNEC(1367857, 32); // Отправить код

    //startPlayback(gunShot, sizeof(gunShot)); // Воспроизведение кадра между отправкой кода и включением приемника (команда воспроизведения 2 для справки)
    //delay(250);
    
    irrecv.enableIRIn(); // Отправка ик-сигнала останавливает приемник, поэтому запустите его снова
    
    startPlayback(gunShot, sizeof(gunShot)); // Воспроизведение выстрела после отправки кода и включения приемника (команда воспроизведения 3 для справки)
    delay(250);


    // Toggle the yellow light
    digitalWrite(yellowLight, toggleYellow);
    toggleYellow = not toggleYellow;

    previousTransmittion = millis(); // Установить рекорд последней передачи в currnt time 
  }


  
  if (irrecv.decode(&results)) // Если мы получили ИК-сигнал
  { 
    Serial.println (String(results.value, HEX)); // Display HEX results 
    if (String(results.value, DEC) == "1367857") // If the code is the right one
    {
      Serial.println("correct code");
      
      // toggle the green light
      digitalWrite(greenLight, toggleGreen);
      toggleGreen = not toggleGreen;
    }
    irrecv.resume(); // Подготовка приемника к следующему коду
 }
}

// Конец скетча

Как вы можете видеть, я попытался поместить звуковую линию воспроизведения до, между и после ИК-линий передачи кода. Задержки есть, так что я могу видеть, начинает ли звук воспроизводиться и останавливается или он просто никогда не воспроизводится. Вот что я нашел из всех комбинаций:

  • Во всех комбинациях (команды воспроизведения 1, 2 и 3) ИК-приемник работал по назначению, если он использовался ДО нажатия кнопки.

  • Ни одна из комбинаций не останавливает цикл, как если бы я поставил <Serial.println("loop");> в начале процедуры loop() он продолжает печатать "loop", независимо от того, что я делаю.<Serial.println("loop");>

  • В командах воспроизведения 1 и 2 звук воспроизводится, когда я нажимаю кнопку, но останавливается после задержки в 250 мс. После того как кнопка была нажата один раз, она ничего не делает, когда я нажимаю ее снова (не печатает "отправить!" и не переключает свет). Приемник получает еще один код после нажатия кнопки, но всегда печатает код "2a", независимо от того, какую кнопку на пульте дистанционного управления телевизора я нажимаю (пульт дистанционного управления телевизора обычно печатает 6-символьный шестнадцатеричный код). После того как он печатает "2а", он больше не получает никаких кодов.

  • Команда Play 3 воспроизводит полный звук и отправляет правильный код, и позволяет мне делать это столько раз, сколько я хочу (кнопка все еще работает после нажатия ее несколько раз). Однако приемник по-прежнему не работает после первого нажатия кнопки. Он не получает "2a" в первый раз после нажатия кнопки в отличие от первых 2.

Я использую библиотеки UNremote от shirriff, z3t0 и ArminJo (ВЕРСИЯ 2.6.1) и PCM Дэвида Меллиса, Майкла Смита (ВЕРСИЯ 1.0.0) (http://highlowtech.org/?p=1963). Я не знаю, есть ли простой способ обойти эту проблему или эти библиотеки просто не могут использоваться вместе.

У меня есть динамик на выводе 11.

Если вам нужно что-нибудь прояснить, пожалуйста, спросите. Любая помощь будет оценена по достоинству, заранее спасибо.

, 👍2


2 ответа


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

1

Библиотека PCM использует таймер 1 и таймер 2. Библиотека UNremote использует таймер 1. Так что им обоим нужен таймер 1. Итак, есть конфликт. Поэтому, к сожалению, вы не можете использовать обе библиотеки одновременно.

,

Хорошо, спасибо. Знаете ли вы какие-либо другие библиотеки, которые я мог бы использовать вместе, которые позволили бы мне использовать ИК и звук, которые не конфликтуют?, @Patrick

Проще всего было бы перенести воспроизведение звука на другой чип, например dfplayer mini (который оснащен картой micro SD)., @chrisl

Хорошо, спасибо. Я бегло взглянул, и это выглядит как хорошее решение., @Patrick


1

Это работает для меня, если я ставлю задержку после startPlayback, за которой следует irrecv.enableIRIn();

startPlayback(sample, sizeof(sample));
delay(1000); // задержка необходима до тех пор, пока воспроизводится
irrecv.enableIRIn(); //  включить ввод с ИК-приемника после использования библиотеки PCM startPlayback
,