Не могу заставить свой код воспроизводить музыку

Проблема в том, что если я сначала открою дверь ожерелья, ничего не произойдет. Сначала я должен открыть кольцевую дверь. Это все включает. Затем, когда дверь ожерелья открыта, шаговый двигатель выключится, а свет и музыка продолжат играть. Но я хочу иметь возможность сначала открыть дверь ожерелья и включить музыку со светом. Я не хочу, чтобы имело значение, какой из них открывается первым. Я также понял, что если я смогу заставить оператор or работать внутри оператора and, то смогу полностью избавиться от четвертого оператора if. И RingDoor open, и chainDoor open, а также ringDoor Closed и chainDoor open имеют одинаковый результат. Теперь, если я переключаю состояния двери в третьем операторе if, я получаю, что chainDoor воспроизводит звук только после закрытия (исходная проблема), но если обе двери открыты, а затем RingDoor закрыт, музыка отключится после того, как шаговый таймер завершит работу, а затем начать снова после того, как ожерелье будет закрыто?!?!?!?

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

const int stepsPerRevolution = 2048;   //Количество импульсов на оборот
const int ringDoor=2;                  //Кольцевая дверь
const int necklaceDoor=7;              // Ожерелье дверь
const int relayPower=22;               // Включаем реле

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

void setup() {
  Serial.begin(9600);                         //Начнем соединение с компьютером
  
  if (!SD.begin(53))                         // Чип на карте
  {
    Serial.println("failed!");                // SD-карта не читается
    return;
  }
  
  tmrpcm.speakerPin = 46;                      // Выходной контакт динамика
  myStepper.setSpeed(5);                       //Шаговая скорость
  pinMode(ringDoor,INPUT);                     //Проверить состояние магнитного выключателя кольцевой двери, NO
  pinMode(necklaceDoor,INPUT);                 //Проверьте состояние магнитного выключателя дверцы ожерелья, NO
  pinMode(relayPower,OUTPUT);                  //Включение реле для светодиода 12В
  digitalWrite(ringDoor,HIGH);                 // Сделать дверь закрытой с высоким уровнем чтения при запуске
  digitalWrite(necklaceDoor,HIGH);             // Сделать дверь закрытой с высоким уровнем чтения при запуске
  digitalWrite(relayPower,LOW);                //Выключаем реле при запуске
}

void loop() {

  if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==HIGH)) 
  {                                                                                 //кольцо и ожерелье закрыты, все выключено
    digitalWrite(relayPower,LOW);
  }
  
  if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH))
  {                                                                                 //кольцо-дверь открыта, а дверца-кольцо закрыта, свет горит, шаговый двигатель вращается, играет музыка
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
    myStepper.step(stepsPerRevolution);
    delay(500);
    myStepper.step(-stepsPerRevolution);
    delay(500);
  }
  
  if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH)) 
  {                                                                                 //кольцевая дверь закрыта, а дверца ожерелья открыта, свет включен, шаговый двигатель выключен, играет музыка
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
  }
  
  if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==LOW)) 
  {                                                                                 //дверь с кольцом и дверь с ожерельем открыты, свет включен, шаговый двигатель выключен, играет музыка
    digitalWrite(relayPower,HIGH);
    tmrpcm.play("music.wav");
  }
}

Пожалуйста и спасибо всем, кто помогает. Это очень ценится. Да, я задал исходный вопрос, и ответ, который я получил, не только не работал, но почему-то ни одна защелка больше не работала.

, 👍1

Обсуждение

Код, который вы представили, даже не должен компилироваться. Кое-что из того, что выглядит как код, находится в комментариях, окончания строк явно отсутствуют, а строки простираются далеко по всей странице. Это то, что вы пытались запустить, или оно было искажено, когда вы разместили его? Если это последнее, пожалуйста, опубликуйте код, который вы действительно скомпилировали., @JRobert

Я не знаю, что случилось с вашим кодом, когда вы его скопировали, но, пожалуйста, полностью переформатируйте его и снова вставьте сюда. Это совершенно нечитаемо и определенно не должно компилироваться как есть. После того, как вы вставите его, выделите все это и нажмите кнопку «Пример кода» в редакторе, чтобы редактор обработал его как блок кода (как сейчас)., @Gabriel Staples

Обновлено. Спасибо, я и не знал, что накосячил., @Vincent Ledbetter

Вы намеревались, чтобы два средних оператора if имели точно такое же условие? Или один должен был быть для другой двери?, @Delta_G

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

Я пробовал два оператора if. Я пробовал еще операторы if. Я пробовал практически все, что только можно вообразить. Несмотря ни на что, я не могу включить свет, если только открыта дверь с ожерельем. И мне нужно, чтобы мотор остановился, если дверь ожерелья откроется в любой момент. Спасибо за помощь, но я думаю, что мне придется заплатить кому-то, чтобы посмотреть на это., @Vincent Ledbetter


1 ответ


1

Прежде всего вы должны выяснить, как работают ваши магнитные переключатели. Откроются они или закроются, если прикрепить к ним магнит? Они ведут себя одинаково или один закрывается, а другой открывается, если прикрепить магнит? Ваш код выше написан для активных НИЗКИХ переключателей, т.е. если соответствующая дверь закрыта, переключатель разомкнут, и поэтому логический уровень контакта ВЫСОКИЙ. Уровень НИЗКИЙ, если дверь открыта (активирована; следовательно, активен НИЗКИЙ).

Чтобы ваш код мог работать, переключатели должны быть подключены правильно: с одной стороны подключите их к GND, а с другой стороны к соответствующему контакту Arduino. Если это не так, необходимо изменить код или правильно подключить переключатели. Вы не показали нам свою схему, поэтому я не могу ее проверить.

Вот код, который можно попробовать. Но сначала выясните, активны ли переключатели, которые вы используете, в LOW или HIGH. У меня также нет доступа к IDE на данный момент, поэтому я не могу попробовать код. Воспринимайте это как подсказку, как это сделать.

И один совет от человека, который занимается этим вот уже 30 лет: не комментируйте переменные, если их названия говорят сами за себя:

// такого рода комментарии делают код нечитаемым --V
const int ringDoor=2;                          //Кольцевая дверь

Я знаю, что это обычное поведение в сообществе Arduino, но не пишите комментарии после утверждения. В приведенном выше коде я понял, что комментарии для операторов if есть только тогда, когда я скопировал код в своем ответе. Комментарии полезны только в том случае, если они говорят что-то новое и их можно без проблем прочитать.

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

const int stepsPerRevolution = 2048;
const int ringDoor = 2;             
const int necklaceDoor = 7;         
const int relayPower = 22;

Stepper myStepper = Stepper( stepsPerRevolution, 8, 10, 9, 11 );
    
void setup() 
{
  Serial.begin( 9600 );          
  if ( ! SD.begin( 53 ) )           
  {
    Serial.println( "failed!" ); 
    return;
  }
  
  tmrpcm.speakerPin = 46;      
  myStepper.setSpeed( 5 );       
  pinMode( ringDoor, INPUT );     
  pinMode( necklaceDoor, INPUT ); 
  pinMode( relayPower, OUTPUT );  

  digitalWrite( ringDoor, HIGH ); 
  digitalWrite( necklaceDoor, HIGH );

  digitalWrite( relayPower, LOW );    
}

void loop() {

  // следующий код работает, если оба переключателя активны LOW
  // (т.е. НИЗКИЙ, если дверь открыта)
  // если переключатель «ringDoor-switch» ВЫСОКИЙ, активен изменить
  // digitalRead(ringDoor) == LOW to
  // digitalRead(ringDoor) == HIGH
  // если переключатель "necklaceDoor-switch" ВЫСОКИЙ, активен изменить
  // digitalRead( chainDoor ) == LOW to
  // digitalRead( chainDoor ) == HIGH
  // а также
  // digitalRead( chainDoor ) == ОТ ВЫСОКОГО до
  // digitalRead( chainDoor ) == LOW

  if ( ( digitalRead( ringDoor )     == LOW ) ||
       ( digitalRead( necklaceDoor ) == LOW ) ) 
  {                                                                                        
    // одна из дверей открыта
    digitalWrite( relayPower, HIGH );
    tmrpcm.play( "music.wav" );
    if ( digitalRead( necklaceDoor ) == HIGH )
    {
      // открыта только кольцевая дверь
      myStepper.step( stepsPerRevolution );
      delay( 500 );
      myStepper.step( -stepsPerRevolution );
      delay( 500 );
    }
  }
  else
  {
    digitalWrite( relayPower, LOW );
  }
}
,

Так что ваш код работает почти идеально. Большое спасибо! Приношу извинения за заметки. Форум страницы arduino попросил их, как и мой первый пост здесь. Единственная проблема, с которой я сталкиваюсь сейчас, заключается в том, что если я сначала открою дверь с ожерельем, музыка не будет воспроизводиться, пока я не закрою этот переключатель? Тогда музыка будет играть? Я пытаюсь понять, как добавить изображение моей схемы. Будьте нежны со мной, у меня нет CAD, поэтому я нарисовал его в MultiSim. (Программа, которую я все еще имею из колледжа). Я только что отредактировал исходный пост со схемой., @Vincent Ledbetter

@VincentLedbetter Пожалуйста. Нет причин извиняться. Схема в порядке. Переключатели подключают GND к контактам датчика, поэтому первая часть программы (например, активация подтягивающих резисторов) кажется правильной. Есть одна вещь, которую я не могу проверить, а именно: замкнуты ли выключатели, если двери закрыты, или они открыты? См. комментарий в коде выше. Если вы не можете узнать, внесите изменения HIGH/LOW, которые я предлагаю в комментарии, и узнайте, работает ли это лучше. Также может быть проблема с необходимой мощностью. Возможно, Mega не сможет обеспечить весь необходимый вам ток., @Peter Paul Kiefer

Итак, блок питания 12 В имеет разветвитель. Одна сторона идет к Arduino, и я использую только устройство чтения SD-карт, реле включения и аудиовывод. Затем через реле проходит другая сторона источника питания 12 В. Светодиод подключается до регулятора напряжения, а шаговый двигатель запитывается после регулятора напряжения. Таким образом, мой высокий ток поступает прямо от источника питания, а не через плату., @Vincent Ledbetter

@VincentLedbetter Контакт 3,3 В имеет максимальный ток 50 мА. Какой ток потребляет модуль SD-карты? Контакты ввода-вывода могут выдавать 40 мА. Сколько тянет Зуммер? Напряжение 5 В может обеспечить минимальный возможный ток источника питания и 500 мА (контролируется термопредохранителем). Из этого вы должны вычесть ток, который потребляется от других контактов: 3,3 В, контакты ввода-вывода, подтягивающие устройства на переключателях потребляют ток ... Это была просто идея, если ничто другое не имеет смысла. Другая идея, что переключатели могут вести себя не так, как ожидалось, для меня более важна., @Peter Paul Kiefer