Mega 2560 не воспроизводит аудиофайл, когда я хочу. Он играет, когда выполняется первое условие, но не другое

Итак, я делаю шкатулку для драгоценностей для своей племянницы, которая будет вращать держатель ожерелья с помощью шагового двигателя, воспроизводить аудиофайл и включать светодиодные фонари. Я использую Arduino MEGA 2560.

Поток такой:

  1. Кольцевая дверь открыта, а кольцевая закрыта: горит светодиод, крутится шаговый двигатель, воспроизводится звук.
  2. Кольцевая дверь закрыта, а кольцевая открыта: горит светодиод и воспроизводится звук, шагового двигателя нет.
  3. Обе двери закрылись: все выключено или выключено после задержки.
  4. Обе двери открыты: горит светодиод, играет музыка, шагового двигателя нет.

Моя проблема заключается в том, что при открытой дверной задвижке звук воспроизводится так, как и должен. Нет проблем, но если я только открою doorLatch2, звук не воспроизводится. Если я открою doorLatch, а затем doorLatch2, будет воспроизводиться звук. Если я откроюсь в обратном порядке, звук не будет воспроизводиться. Я попытался добавить оператор if сам по себе с "или" в разделе loop, чтобы проверить, открыта ли любая дверь, и я не могу поместить его в раздел настройки, потому что он просто постоянно играет с открытыми или закрытыми защелками. В настоящее время я держу его там, где играет музыка с открытой дверной защелкой. Чрезвычайно странная часть для меня заключается в том, что если я помещу tmrpcm.play в первый оператор else, то звук будет воспроизводиться после открытия и закрытия doorLatch2.

Поэтому я бы хотел, чтобы звук воспроизводился и зацикливался до тех пор, пока открыта любая из дверей. ПОЖАЛУЙСТА, ПОМОГИТЕ! ЧТО Я ДЕЛАЮ НЕ ТАК?!?!?!?!?!

Код:

#include <SD.h>
#include <TMRpcm.h>
TMRpcm tmrpcm;

#include <Stepper.h>
const int stepsPerRevolution = 2048;
const int doorLatch=2;   //Ring door
const int doorLatch2=6;  //Necklace door
const int relayPower=13; //Turn relay on

Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  Serial.begin(9600);
  Serial.print("\nInitializing SD card...");

  // set this to your card type and cs pin
  if (!SD.begin(53)) {
    Serial.println("failed!");
    return;
  }
  Serial.println("done.");

  tmrpcm.speakerPin = 46;

  myStepper.setSpeed(5);
  pinMode(doorLatch,INPUT);
  pinMode(doorLatch2,INPUT);
  pinMode(relayPower,OUTPUT);
  digitalWrite(doorLatch,HIGH);
  digitalWrite(doorLatch2,HIGH);

}

void loop() {

  if ((digitalRead(doorLatch)==HIGH)&&(digitalRead(doorLatch2)==HIGH)) {
    //ring door and necklace door is closed
    digitalWrite(relayPower,LOW);

  }
  else {
    //ring door is open, lights on, stepper motor spinning, music playing
    digitalWrite(relayPower,HIGH);

  }

  if ((digitalRead(doorLatch2)==HIGH)&&(digitalRead(doorLatch)==LOW)) {
    //ring door open and necklace door closed

    digitalWrite(relayPower,HIGH);

    myStepper.step(stepsPerRevolution);
    delay(500);
    myStepper.step(-stepsPerRevolution);
    delay(500);

  }
  else {
    tmrpcm.play("music.wav");
  }
}

НОВЫЙ КОД, НОВАЯ ПРОБЛЕМА, но более близкиеОбновленные имена и примечания для более легкого следования*** Новая проблема заключается в том, что если я сначала открою дверь Ожерелья, то ничего не произойдет. Сначала я должен открыть вход. Это все заводит. Затем, когда дверца ожерелья откроется, шаговый двигатель выключится, а свет и музыка продолжат играть. Но я хочу сначала открыть дверь ожерелья и включить музыку при свете. Я не хочу, чтобы имело значение, какая из них откроется первой. Я также понял, что если я смогу заставить оператор or работать в операторе and, то смогу полностью покончить с четвертым оператором if. И открытая кольцевая дверь, и открытая Кольцевая дверь, а также закрытая кольцевая дверь и открытая Кольцевая дверь имеют один и тот же результат. Теперь, если я переключу состояния двери в третьем операторе if, я получу necklaceDoor только воспроизводит звук после закрытия(оригинальная проблема), но если обе двери открыты, а затем ringDoor закрыт, музыка отключится после завершения шагового таймера, а затем начнется снова после закрытия necklaceDoor?!?!?!?

#include <SD.h>
#include <TMRpcm.h>
#include <Stepper.h>
TMRpcm tmrpcm;

const int stepsPerRevolution = 2048;   //Number of pulses per revolution
const int ringDoor=2;                  //Ring door
const int necklaceDoor=7;              //Necklace door
const int relayPower=22;               //Turn relay on

Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  Serial.begin(9600);                         //Start connection with computer
  
  if (!SD.begin(53))                         //Chip pin on card
  {
    Serial.println("failed!");                //SD card did not read
    return;
  }
  
  tmrpcm.speakerPin = 46;                      //Speaker output pin
  myStepper.setSpeed(5);                       //Stepper speed
  pinMode(ringDoor,INPUT);                     //Check state of ring door magnetic switch, NO
  pinMode(necklaceDoor,INPUT);                 //Check state of necklace door magnetic switch, NO
  pinMode(relayPower,OUTPUT);                  //Relay enable for 12V LED
  digitalWrite(ringDoor,HIGH);                 //Make door closed read high on start up
  digitalWrite(necklaceDoor,HIGH);             //Make door closed read high on start up
  digitalWrite(relayPower,LOW);                //Make relay off on start up
}

void loop() {

  if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==HIGH)) 
  {                                                                                 //ring door and necklace door is closed, everything is off
    digitalWrite(relayPower,LOW);
  }
  
  if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH))
  {                                                                                 //ring door is open and necklace door is closed, lights on, stepper motor spinning, music playing
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
    myStepper.step(stepsPerRevolution);
    delay(500);
    myStepper.step(-stepsPerRevolution);
    delay(500);
  }
  
  if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==LOW)) 
  {                                                                                 //ring door closed and necklace door open, lights on, stepper motor off, music playing
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
  }
  
  if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==LOW)) 
  {                                                                                 //ring door and necklace door open, lights on, stepper motor off, music playing
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
  }
}

Пожалуйста, и спасибо всем, кто помогает. Это очень ценится

, 👍1

Обсуждение

пара вещей ... используйте описательные имена переменных ... используйте "ringDoor" вместо "doorLatch", аналогично для другой двери.... нарисуйте диаграмму поведения ... это " любая дверь -> светодиод и звук ... кольцевая дверь -> мотор`, @jsotola


1 ответ


1

Ваш код не соответствует желаемому результату. Вы говорите, что хотите:

Дверная защелка открыта, а дверная защелка 2 закрыта: горит светодиод, шаговое вращение, воспроизводится звук.
Защелка двери закрыта и защелка двери 2: горит светодиод и воспроизводится звук, шагового двигателя нет.
Обе защелки закрыты: Все выключено или выключено после задержки.
Обе защелки открыты: горит светодиод и играет музыка, шагового двигателя нет.

Обратите внимание, что обе защелки открыты, а защелка двери закрыта, Защелка двери 2 открыта в одном и том же состоянии: горит светодиод и воспроизводится звук, шагового двигателя нет.

Ваш кодекс гласит

if doorLatch & doorLatch2 are both closed (high)

    relayPower = low (off)

else 

    relayPower = HIGH (on). // Это во ВСЕХ случаях, кроме обеих защелок, HIGH

Далее, второе утверждение if:

if doorLatch2 == HIGH && doorLatch == LOW
     relayPower = HIGH (on)
     step motor back and forth
else 
     play sound

Таким образом, вы воспроизводите звук, если doorlatch2 низкий или дверная защелка высокая

Вы выключаете реле, если дверная защелка и дверная защелка2 закрыты (высокий)

Вы включаете реле, если дверная защелка низкая или дверная защелка 2 низкая.

void loop() {
   int latchState digitalRead(doorLatch); 
   int latch2state = digitalRead(doorLatch2);
   if (latchState = LOW && latch2Sate == HIGH) {        //0 - 1
      //включите светодиод
      //шаговое вращение
      //воспроизведение аудио
   } else if (latchState = HIGH && latch2Sate == LOW) { //1 - 0
      //Включите светодиод
      //воспроизведение аудио
      //выключите шаговый двигатель
   } else if (latchState = HIGH && latch2Sate == HIGH) {//1 - 1
     //выключите все (после задержки?)
   } else if (latchState = LOW && latch2Sate == LOW {   //0 - 0
     //СВЕТОДИОД включен
     //воспроизведение музыки
     //выключите шаговый двигатель
   } 
}
,

Я попробовал это, и контакт реле все время оставался под напряжением. Я немного переделал и отредактирую оригинальный пост, @Vincent Ledbetter

Я решил ту же проблему для друга давным-давно. Возможно, это тот же самый случай: между степпером и игроком произошел конфликт прерываний. Способ решения проблемы состоит в том, чтобы повторно запускать плеер каждый раз, когда вы хотите играть, чтобы он заново устанавливал прерывание.., @Peter