Выполнение действия 1 раз внутри лупа (нужна помощь)

danikanik
Offline
Зарегистрирован: 25.02.2020

Добрый день! 

очень нужна помощь по одной задаче. Есть проект, состоящий из: фоторезистор, пищалка и модуль воспроизведения mp3 файлов + динамик.

1. if фоторезистор больше 1, то через небольшую паузу пищим пищалкой. тут все предельно понятно и получается.
2. if фоторезистор меньше 1, то запускаем необходимый файл на модуле. Это реализуется с помощью собственно библиотеки модуля, все просто, команда play(#файла). Это команда запускает файл и он играет, пока не закончится.
проблема в том, что файл должным образом не воспроизводится, потому что, как я понимаю, он постоянно тригируется каждые миллисекунды опроса фоторезистора. т.е. находится в постоянном лупе. что для пищалки это гуд, то тут совсем не применимо. мне нужно чтобы при значениях меньше 1 файл запустился только один раз, сколько бы времени фоторезистор не был бы значениях меньше 1. при больше 1 приходит команда стоп воспроизведение и начало пищаний. когда снова фоторезистор меньше 1, файл вновь должен запустится с самого начала...

#include "GyverTimer.h"
#include "DFRobotDFPlayerMini.h"
#include "Arduino.h"
#include "SoftwareSerial.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

int photocellPin = 0;
int photocellReading;


GTimer Timer1(MS, 1000);
GTimer Timer3(MS);


const int buzzer = 6;
const int c = 1047;
const int e = 1397;
void beep(int ton, int time)
{
  tone(buzzer, ton, time);
  delay(time + 20);
}


void setup() {

  mySoftwareSerial.begin(9600);
  Serial.begin(9600);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(10);

}

void loop() {

  photocellReading = analogRead(photocellPin);
  if (Timer1.isReady()) Serial.println(photocellReading);

  if (photocellReading < 1) {
    myDFPlayer.stop();
  }


  if (photocellReading > 1) {
    myDFPlayer.play(3);
  }

  if (photocellReading < 1) {
    Timer3.setTimeout(3000);
  }

  if (Timer3.isReady()) {

    do {
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);


      noTone(buzzer);
      delay(1200);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);
      beep(c, 20);
      beep(e, 20);


      noTone(buzzer);
      delay(5000);
    } while (analogRead(photocellPin) < 1);
  }
}

Буду очень благодарен за помощь с решением этой задачи!

SLKH
Offline
Зарегистрирован: 17.08.2015

danikanik пишет:

Добрый день! 

очень нужна помощь по одной задаче. Есть проект,

А что автор проекта по этому поводу говорит?

danikanik
Offline
Зарегистрирован: 25.02.2020

он, т.е. я, не знает как решить эту задачу :)

 

danikanik
Offline
Зарегистрирован: 25.02.2020

и сразу могу сказать, что в примерах из библиотеки к модулю это решается с помощью 

play

delay(сколько длится файл)

 

но этот метод мне не подходит, потому что из-за него стопорится считывание значений фоторезистора и соотвественно реакция не прерывание .

 

 

b707
Offline
Зарегистрирован: 26.05.2017

danikanik - подсказка, запускайте файл не просто когда "фоторезистор < 1", а когда на этом шаге фоторезистор < 1, а на прошлом шаге он был > 1

b707
Offline
Зарегистрирован: 26.05.2017

хотя посмотрел код - вряд ли это вам поможет, у вас такая каша в скетче.

Зачем вы пользуетесь одновременно таймерами, делеями и циклом while? - чтобы всех запутать. в первую очередь себя?

danikanik
Offline
Зарегистрирован: 25.02.2020

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

b707
Offline
Зарегистрирован: 26.05.2017

danikanik пишет:

буду благодарен за предложения по реализации нужной задачи.

я выше дал подсказку в сообщении #4

Только цикл do..while в строке 69 необходимо выкинуть, он абсолютно несовместим с таймерами и нормальным опросом фоторезистора

danikanik
Offline
Зарегистрирован: 25.02.2020

спасибо! доберусь до дома попробую.

а на что do...while менять? на просто while (photocellreading > 1) ?

 

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Ставьте флаг при сработке фоторезистора и воспроизводите, далее, пока он в состоянии сработки и флаг стоит дальнейшие действия игнорируете. Когда фоторезистор "отпускает" - опускаете флаг. В принципе все.

SLKH
Offline
Зарегистрирован: 17.08.2015

danikanik пишет:

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

Во-первых, свернуть beep'ы в циклы for.

Во-вторых, переписать всё в стиле блинк без делей, что ли.

потом разбираться с плеером.