DFPlayer зацикливает мелодию при звонке на дисковый GSM телефон. В чем дело? Ошибка в скетче?

Здравствуйте. Есть скетч на котором работает дисковый телефон ссср (стационарный раньше).связка-ардуино про мини-GSM 800L- DFplayer. в скетче все хорошо, кроме одного бага, при звонке с мобильного устройства на этот дисковый телефон мелодия звонка через 7-8 секунд прерывается резко и играет снова сначала(будто включена функция зацикливания, длящаяся 7-8 секунд. пробовал несколько модулей, несколько разных SD накопителей-история таже.Есть подозрение , что создатель скетча намудрил с функциями мелодии mp3(1)-в скетче.Подскажите в чем может быть проблема, а то третью неделю ломаю голову, причем на разным мелодиях входящего звонка такая же история.Вот скетч

#include <DFPlayer_Mini_Mp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(5, 6); // RX, TX

#define PIN_SW_COUNTER 2 //нормально замкнутый контакт
#define PIN_SW_REVERSE 3 //нормално разомкнутый
#define PIN_SW_HANGUP  11 //снятие трубки
#define PIN_SW_RING 8 //RING
#define DELAY_DEBOUNCE 20 //антидребезг

uint8_t n_digits;
uint8_t len = 11; //длина номера - 7 или 11
uint8_t counter;
uint8_t telnumb[11];
uint8_t status_tel;
boolean pevhangup; //прошлое состояние трубки. трубка опущена - контакт замкнут, на входе - ноль.
unsigned long prevtime;
String cpas;

void setup()
{
  pinMode(PIN_SW_COUNTER, INPUT_PULLUP);
  pinMode(PIN_SW_REVERSE, INPUT_PULLUP);
  pinMode(PIN_SW_HANGUP, INPUT_PULLUP);
  pinMode(PIN_SW_RING, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  mp3_set_serial(Serial);
  Serial.println("START");
  mySerial.begin(19200);  //Скорость порта для связи Arduino с GSM модулем

  delay(2000);
  mySerial.print("ATE0\r"); delay(200);
  mySerial.print("AT+CSQ\r"); delay(200);
  mySerial.print("AT+CBC\r"); delay(200);
  mp3_set_volume(20);
}

void loop()
{
  if (!digitalRead(PIN_SW_RING) && (!digitalRead(PIN_SW_HANGUP))) {
    if (millis() > prevtime + 7000) {
      mp3_play(1);
      prevtime = millis();
    }
  }
  
if (mySerial.available()) waitmode();

  if (digitalRead(PIN_SW_HANGUP) && !pevhangup)//если подняли трубку
  {
    delay(DELAY_DEBOUNCE); pevhangup = 1;
cpas=CPAS();
    if  (cpas.indexOf("+CPAS: 0") >= 0) {
      dialing();
    }
    if ((cpas.indexOf("+CPAS: 3") >= 0)||(cpas.indexOf("RING") >= 0)) {
      mp3_stop (); delay(20);
      mySerial.print("ATA\r");
      Serial.println();
      Serial.println("ATA-otvet");
    }
  }//end if сняли трубку

  if (!digitalRead(PIN_SW_HANGUP) && pevhangup)//если положили трубку
  {
    cpas=CPAS();
    if (cpas.indexOf("+CPAS: 4") >= 0) {
      mySerial.print("ATH0\r");
      mp3_play(9);//завершение разговора
    }
    delay(DELAY_DEBOUNCE);
    pevhangup = 0;
  }//end если положили трубку
} //end loop

void dialing() {
  Serial.println();  Serial.println("Dialing");
  mp3_play(8);//набирайте номер
  n_digits = 0;//порядковый номер набираемой цифры
  while (digitalRead(PIN_SW_REVERSE))// ждём пока на входе reverse всё ещё единица
  {
    if (!digitalRead(PIN_SW_HANGUP) && pevhangup)//если положили трубку
    {
      delay(DELAY_DEBOUNCE);  //end если положили трубку
      pevhangup = 0;
      n_digits = 0;
      Serial.println();
      Serial.println("Stop dialing");
      mp3_play(20);
      return;
    }
  }
  Serial.println("open");
  delay(DELAY_DEBOUNCE);

  while (n_digits < len) //пока номер набираемой цифры меньше их количества(11-я цифра имеет номер10)
  {



    if (digitalRead(PIN_SW_COUNTER))//если на вывод счётчика пришла единица
    {
      counter++; digitalWrite(13, HIGH);
      delay(DELAY_DEBOUNCE);
      while (digitalRead(PIN_SW_COUNTER)); //ждём пока на входе счетчика всё ещё единица
      delay(DELAY_DEBOUNCE); digitalWrite(13, LOW);
    }

    if (digitalRead(PIN_SW_REVERSE))//если на вывод реверса пришел адин
    { //при завершени набора одной цифры
      if (counter > 0) {//если набрана какая-нибудь цифра
        if (!(counter == 10)) {
          telnumb[n_digits] = counter; //запись в массив "telnumb" очередной(n_digits) цифры(counter) номера
        }
        else {
          telnumb[n_digits] = 0; //10 импульсов - это ноль
        }
        counter = 0; //сброс счётчика импульсов

        if (n_digits == 0) {//при наборе первой цифры
          if (telnumb[0] == 8) {//если это восьмёрка - 11 цифр
            len = 11;
            Serial.println(" 11 digits ");
          } else {
            len = 7;
            Serial.println(" 7 digits ");
          }
        }

        Serial.print(n_digits); Serial.print(" = "); Serial.println(telnumb[n_digits]);

        n_digits++; //увеличиваем на единицу номер набираемой цифры
      } else {
        Serial.println(" error ");  //если при наборе цифры не поступило импульсов
        getaccum();
      }

      delay(DELAY_DEBOUNCE);
      if (n_digits < len)while (digitalRead(PIN_SW_REVERSE))//ждём пока на входе реверса всё ещё единица
        {
          if (!digitalRead(PIN_SW_HANGUP) && pevhangup)//если положили трубку
          {
            delay(DELAY_DEBOUNCE);  //end если положили трубку
            pevhangup = 0;
            n_digits = 0;
            Serial.println();
            Serial.println("Stop dialing");
            mp3_play(20);
            return;
          }
        };
      delay(DELAY_DEBOUNCE);
    }

  } //end while (n_digits <len)
  call();
} //end void dialing()

void call()//набор номера на ПЫ
{
  Serial.println(); Serial.println("Call");
  if (len == 11) {
    mySerial.print("ATD+7"); Serial.print("ATD+7");
    for (uint8_t i = 1; i < len; i++) {
      mySerial.print(telnumb[i]);
      Serial.print(telnumb[i]);
    }
    mySerial.print(";\r"); Serial.print(";\r");
    delay(700);
  }

  if (len == 7) {
    mySerial.print("ATD+7812"); Serial.print("ATD+7812");
    for (uint8_t i = 0; i < 7; i++) {
      mySerial.print(telnumb[i]);
      Serial.print(telnumb[i]);
    }
    mySerial.print(";\r"); Serial.print(";");
    delay(700);
  }
}

String CPAS() //определение статуса (0,3 или 4)
{
  Serial.print("Send: AT+CPAS"); delay(200);
  mySerial.print("AT+CPAS\r"); delay(200);
  String stroka;
  while (stroka.indexOf("+CPAS:") < 0) {
    stroka = "";
    while (mySerial.available())
    {
      char c  = mySerial.read();
      stroka  +=  c; delay(10);
    }

    Serial.println(); Serial.print("Received: >"); Serial.print(stroka); Serial.println('<');
    return stroka;
  }

}

void waitmode() {
  int ch = 0;
  String val = "";
  if (mySerial.available()) {          //есть данные от GSM модуля
    delay(200);                        //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
    while (mySerial.available()) {      //сохраняем входную строку в переменную val
      ch = mySerial.read();
      val += char(ch);
      delay(10);
    }
    Serial.println(val);                    // дублируем сообщение в терминал
    if (val.indexOf("NO CARRIER") > -1) {
      mp3_play(9);
      val = "";
    }
  }
}

void getaccum() {

  Serial.print("Send: AT+CBC"); delay(200);
  mySerial.print("AT+CBC\r"); delay(200);
  // запрос отправили
  String strok;
  while (strok.indexOf("+CBC:") < 0) {//набираем массив пока в строке не окажется +CBC:
    strok = "";
    while (mySerial.available())
    {
      char c  = mySerial.read();
      strok  +=  c; delay(10);
    }
     Serial.print(strok); delay(200);
    // имеем готовую строку. теперь расшифровать //+CBC: 0,100,4278
    if (strok.indexOf("+CBC: 0,100") > -1) {
      mp3_play(19);
    }
    else {
      if (strok.indexOf("+CBC: 0,1") > -1) {
        mp3_play(10);
      }
      if (strok.indexOf("+CBC: 0,2") > -1) {
        mp3_play(11);
      }
      if (strok.indexOf("+CBC: 0,3") > -1) {
        mp3_play(12);
      }
      if (strok.indexOf("+CBC: 0,4") > -1) {
        mp3_play(13);
      }
      if (strok.indexOf("+CBC: 0,5") > -1) {
        mp3_play(14);
      }
      if (strok.indexOf("+CBC: 0,6") > -1) {
        mp3_play(15);
      }
      if (strok.indexOf("+CBC: 0,7") > -1) {
        mp3_play(16);
      }
      if (strok.indexOf("+CBC: 0,8") > -1) {
        mp3_play(17);
      }
      if (strok.indexOf("+CBC: 0,9") > -1) {
        mp3_play(18);
      }
    }
  }
}

также попутный вопрос , как прописать код, чтобы мой дисковый телефон понимал не только 11тизначные номера мобильных телефонов, а также трехзначные типа 112, 102, 103 и тд.? и если кто вкурсе, как при наборе номера диском выключать при этом длинный гудок в виде моей мп3 мелодии ( mp3_play(8) в скетче),то есть выполнить условие, если идет набор номера , то мп3 мелодия умолкает9 выключается).заранее благодарю

Только с мобильного?
Так может опсос через 7-8 секунд отбой дает и заново начинает посылать вызов?

SIM800 во время входящего звонка после поднятия трубки продолжает слать в UART команду RING каждые несколько секунд.

Вероятнее всего программа не понимает что уже снята трубка.

Так и есть

Нет.вы не поняли…в моем проекте ( дисковый телефон на Ардуино) стоит сим карта в gsm 800L и я звоню на него с другого номера , гудок идёт секунд 30…а на самом дисковом аппарате играет мелодия входящего звонка ,но в один момент ( через 7-8 секунд ) резко прерывается и проигрывается снова…то есть это не естественно …должно быть иначе…мелодия должна играть пока не закончится и не начнет играть снова…не пойму в чем прикол

Вы уверены? Я попробую конечно изменить время,но это функция насколько я понимаю означает лишь что проверяется условие опущена ли трубка на телефонном аппарате ,если опущена более 7 секунд ,то телефон воспринимает входящий звонок…или я не прав ?

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

ОК
Подумайте, что происходит дальше - трубка все еще опущена, телефон звонит, проходит семь секунд… и тайм аут истекает, прерывая мелодию и запуская ее заново.

Похоже на ту проблему, о которой вы задали вопрос? - по-моему да

Поставьте тайм аут равным длительности МП3 файла 1 - посмотрите, исчезнет ли проблема.

1 лайк

Раньше из телефонов модемы делали (и я про диал-ап), теперь наоборот… ))

вы были правы, так и сделал -таймаут по времени мелодии.жить стало легче.Жизнь заиграла новыми красками…Благодарю)).теперь осталась модернизация в виде понимания как изменить скетч, чтобы при наборе диском номера мелодия моя в виде гудка прекращала играть.еще раз благодарю

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

Терпение и труд - всё перетрут)) :+1:

1 лайк