Перестаёт работать AnalogRead

Kulibin_

✩✩✩✩✩✩✩
13 Мар 2023
12
0
Здравствуйте! Собираю устройство для записи и воспроизведения звука, устройство состоит из микрофона (A0), динамика (D9), карты памяти, подключённой через SPI, и аналоговой клавиатуры (A7). Столкнулся с такой проблемой - после окончания записи перестаёт работать AnalogRead, начинает показывать одно и то же значение, как я понял, последнее зафиксированное. После окончания воспроизведения такого нет, всё работает. Что может быть причиной этого?

C++:
#include <TMRpcm.h>
#include <SD.h>
#include <SPI.h>
#include <EEPROM.h>
#include <GyverButton.h>

TMRpcm audio;
char filePrefixname[50] = "rec";
char exten[10] = ".wav";

const int mic_pin = A0;
const int sample_rate = 16000;

int song_number = 0;
boolean debounce1 = true;
boolean debounce2 = true;
boolean play_pause;
bool isPlaying = false;

int analog;

GButton ButtRead;
GButton ButtPlay;
GButton ButtUp;
GButton ButtDown;

#define SD_CSPin 4

void setup() {
  // put your setup code here, to run once:
  //initializes the serial connection between the Arduino and any connected serial device(e.g. computer, phone, raspberry pi...)
  Serial.begin(9600);
  //Sets up the pins
  pinMode(mic_pin, INPUT);
  audio.speakerPin = 9;
  Serial.println("loading... SD card");
  audio.CSPin = SD_CSPin;
  if (!SD.begin(SD_CSPin)) {
    Serial.println("An Error has occurred while mounting SD");
  }
  while (!SD.begin(SD_CSPin)) {
    Serial.print(".");
    delay(500);
  }
  audio.setVolume(5); // установка уровня громкости (от 0 до 7)
  audio.quality(1);
  ButtRead.setType(LOW_PULL);
  ButtPlay.setType(LOW_PULL);
  ButtUp.setType(LOW_PULL);
  ButtDown.setType(LOW_PULL);
}

void wait_min(int mins, int minw, int maxw) {
  int count = 0;
  int secs = mins * 60;
  while (1) {
    Serial.print('.');
    delay(1000);
    count++;
  analogRead(7);
    if ((count == secs) || (analogRead(7) < maxw && analogRead(7) > minw)) {
      count = 0;
      break;
    }
  }
  Serial.println();
  return ;
}

void writing() {
  Serial.println("####################################################################################");
  char fileSlNum[20] = "";
  itoa(file_number, fileSlNum, 10);
  char file_name[50] = "";
  strcat(file_name, filePrefixname);
  strcat(file_name, fileSlNum);
  strcat(file_name, exten);
  Serial.print("New File Name: ");
  Serial.println(file_name);
  audio.startRecording(file_name, sample_rate, mic_pin);
  Serial.println("startRecording");
  wait_min(2, 400, 450);
  audio.stopRecording(file_name);
  Serial.println("stopRecording");
  file_number++;
  Serial.println("####################################################################################");
}

void playing() {
  audio.play("0.WAV", 1);
  wait_min(2, 200, 250);
}

void loop() {
  int analog = analogRead(A7);
  Serial.println(analogRead(A7));
  ButtRead.tick(analog < 250 && analog > 200);
  ButtPlay.tick(analog < 450 && analog > 400);
  ButtUp.tick(analog < 680 && analog > 630);
  ButtDown.tick(analog > 1000);

  if (ButtRead.isClick()) {
    Serial.println("Writing");
    writing();
  }

  if (ButtPlay.isClick()) {
    Serial.println("Playing");
    playing();
  }

  if (ButtUp.isClick()) {

  }

  if (ButtDown.isClick()) {

  }
}
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@Kulibin_,
попробуйте для проверки снизить частоту чтения.
Например, добавьте строчку
delay(100);
после или перед функцией чтения.

И два раза подряд читать одно и то же значение - это неправильно.
int analog = analogRead(A7);
Serial.println(analogRead(A7))
 

Kulibin_

✩✩✩✩✩✩✩
13 Мар 2023
12
0
@Сотнег, не помогло.

А считывать два раза это да, я знаю, просто решил убедиться, что не работает именно analogRead , а не значение analog по какой-то причине застревает на одном и том же значении
 

Kulibin_

✩✩✩✩✩✩✩
13 Мар 2023
12
0
Наткнулся в интернете на человека, описывающего такую проблему, связанную как раз с библиотекой TMRpcm

Я обнаружил, что при записи звука изменяются регистры ADMUX, ADCSRA и ADCSRB, что не позволяет аналоговым выводам считывать напряжения. Мне удалось обойти эту проблему, вернув регистры к тому состоянию, в котором они были изначально

Но никак не могу найти - как именно можно привести эти регистры к изначальному состоянию?
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
501
149
@Kulibin_,
При записи, нельзя использовать в wait_min вызов analogRead
Возможно, если хватает ног, то стоит использовать обычные кнопки, а не аналоговые.

В актуальной версии TMRpcm.h значения ADMUX, ADCSRA и ADCSRB сохраняются и восстанавливаются.
Но может у вас старая версия, может значения портятся из за переполнения памяти, так что проверить их значения будет не лишним. (Выводом в Serial)

При печати статичного текста используйте Serial.println(F()), иначе вы попусту тратите RAM

Serial.println(F("####################################################################################"));
 

Kulibin_

✩✩✩✩✩✩✩
13 Мар 2023
12
0
Памяти должно оставаться достаточно, 600 байт, а библиотеку тоже обновил.

Тогда скорее всего да, перепаяю на обычные кнопки.

Про статичный текст учту, спасибо)
 

Nitrogenium

✩✩✩✩✩✩✩
25 Ноя 2022
33
3
@Kulibin_,

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