Ардуино - запись звука

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Ардуино - запись звука

Сообщение Ivanoff-iv »

roman.com, похоже, что функция записи сама определяет конец буфера флешки, остается только сделать размер буфера таким, чтоб их в буфер флешки укладывалось целое число (видимо с нецелым гдето пересекается по времени оцифровка и запись и получаются артефакты)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

Может уже участники дискуссии потеряли нить ,я напомнью

Сейчас код пишет звук с канал А1 (ADMUX=0X61) и в этой части претензий нет - все в порядки
Нужно что бы одновременно с другого канала А0 оцифровывалось напряжение. И как я понимаю высокая степень дискретизации для А0 не важна. Десять значений за секунду, приведенных к среднему. Потом я вывожу это на экран
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Ардуино - запись звука

Сообщение Ivanoff-iv »

вот какраз с частотой звука было бы проще...
ускорил бы таймер, запускающий оцифровку в 2 раза и после каждо оцифровки делал бы ADMUX^=0x01;
так он бы чередовал каналы формируя стереофайл, а что там во втором канале, уже не так важно...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

Ivanoff-iv, почему нельзя второй таймер сделать? пускай бы каждый таймер занимался своим делом
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Ардуино - запись звука

Сообщение Ivanoff-iv »

можно и второй, но:
1) зачем плодить сущности? (зачем второй таймер, где справится и один)
2) эти таймера придётся синхронизировать, чтобы они не сработали разом или в недопустимой близости друг от друга (АЦП то один и А-Ц преобразование и переключение со входа на вход занимают некоторое время)

Добавлено after 2 minutes 44 seconds:
хотя, если используется не прямой доступ к регистрам, а функция АналогРеад(), то пункт 2 снижает актуальность, т.к. необходимые задержки там уже присутствуют (вне зависимости от того, нужны или нет)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ардуино - запись звука

Сообщение Dimon456 »

roman.com писал(а):ты пишешь по 64 байта ? в сектор по 512 байт ? а остальные 448 байт ? или ты их оставляешь пустыми ?
Что ты пристал?
Тебе надо записать 1 байт, за чем тебе весь сектор в 512 байт писать?
Тебе надо дописать к этому 1 байту еще 1 байт, какие твои действия будут?
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Ардуино - запись звука

Сообщение Ivanoff-iv »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4245346#p4245346"]Тебе надо дописать к этому 1 байту еще 1 байт, какие твои действия будут?[/uquote]Не путай "Твои" действия и действия МК... вполне возможно он заставляет перелопачивать все 512 байт буфера флешки.... но происходит всё это втайне от тебя... т.ч. тут неочевидно....
(собственно, за это я и недолюбливаю ардуину...)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Ардуино - запись звука

Сообщение Martian »

я рискну продолжить утверждать, что нужно исключить эти всякие монопольные задержки и идти путём обработки прерывания АЦП. Таким образом можно получить максимальную частоту выборки данных от скольки угодно каналов, более проще позволит оперировать скоростью преобразования, работать над улучшением качества звука и т. д. Таймером обеспечить лишь синхронизацию данных для wav.
Путь с ожиданием готовности АЦП увеличивает время бессмысленных ожиданий. Это решение, конечно же, может обеспечить желаемое (собственно, уже обеспечило) но не оптимально, и как знать, может быть, на конечном этапе эта неоптимальность помешает.

Добавлено after 54 seconds:
У меня нет атмеги8, но я ща на чем-нибудь слабеньком попробую сделать тоже самое.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

вот этот код работает и звук пишет и напряжение оцифровывает

Код: Выделить всё

ISR(TIMER2_COMPA_vect) {
  // циффруем напряжени с A0
 ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 0 (left adjust)
 sbi(ADCSRA, ADSC); // start ADC sample
  while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
  rsValue=(ADCL|ADCH<<8);
  // тут наверно пауза надо бы.
 // Цифруем звук с A1
ADMUX = 0x61; // set ADC to read pin A1, ADLAR to 1 (left adjust)
  sbi(ADCSRA, ADSC); // start ADC sample
  while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
  recByteCount++; // increment sample counter
  bufByteCount++;
  if (bufByteCount == 64 && bufWrite == 0) {
    bufByteCount = 0;
    bufWrite = 1;
  } else if (bufByteCount == 64 & bufWrite == 1) {
    bufByteCount = 0;
    bufWrite = 0;
  }

  if (bufWrite == 0) {
    buf00[bufByteCount] = ADCH;
  }
  if (bufWrite == 1) {
    buf01[bufByteCount] = ADCH;
  }
качество звука сильно ухудшилось, как сделать что бы оцифровка звука была в облегченном режиме?

Добавлено after 1 minute 6 seconds:
мне необязательно цифровать напряжение с той же частотой (22кгц) что и звук.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Ардуино - запись звука

Сообщение Dimon456 »

Ivanoff-iv писал(а):Не путай "Твои" действия и действия МК...
Да что не у кого протеуса нету?
Загоните этот код да посмотрите что он пишет. Я смогу этот код проверить только через три с половиной месяца.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Ардуино - запись звука

Сообщение Martian »

olegue, увеличьте таймер (частоту) в 2 раза, как советовали выше

Добавлено after 3 minutes 11 seconds:
Dimon456, у меня нет протеуса :dont_know:
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

roman.com писал(а):ты пишешь по 64 байта ? в сектор по 512 байт ? а остальные 448 байт ? или ты их оставляешь пустыми ?

64 байта данных... 11111111111111111....
и 448 байта нулей... 0000000000000000000000000000000000000000000...
так что ли ? ))

Услышьте меня! Мы ведь уже это обсудили. Есть такая библиотека sdfat. Она занимается этим вопросом , - укладывает данные в 512 байт

Добавлено after 39 seconds:
Martian, понял. Спасибо.

Добавлено after 4 minutes 7 seconds:
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4245306#p4245306"]вот какраз с частотой звука было бы проще...
ускорил бы таймер, запускающий оцифровку в 2 раза и после каждо оцифровки делал бы ADMUX^=0x01;
так он бы чередовал каналы формируя стереофайл, а что там во втором канале, уже не так важно...[/uquote]


так мне и заголовок тогда надо менять, указать что это стереофайл?
ADMUX^=0x01; - что это?


Так может мне завести 2ой таймер для А0 и не портить то ,что и так работает хорошо?
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Ардуино - запись звука

Сообщение Martian »

ADMUX^=0x01; - это тоже переключение каналов. Инвертирование младшего бита.
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Ардуино - запись звука

Сообщение roman.com »

olegue писал(а):Услышьте меня! Мы ведь уже это обсудили. Есть такая библиотека sdfat. Она занимается этим вопросом , - укладывает данные в 512 байт
я тебя прекрасно слышу)) с первого дня))

вопрос только в том что в ОРИГИНАЛЕ кода для Ардуино было два буфера по 512 байт.
и была библиотека sdfat, которая брала эти 512 байт и укладывала ровно 512 на флешку))

и всё было хорошо и понятно... пока ты не начал крутить свои буфера)) сначала сделал по 128 байт... потом сделал по 64 байт...
библиотека знает sdfat что размер буфера уменьшился ? или библиотеки пофигу какой буфер ? ))
"сколько указали отправлять на запись - столько я и буду отправлять на запись... хоть по одному байту !"
- ответила библиотека ))

в итоге:
мы указали библиотеки писать по 64 байта...
умная библиотека знает что сектор флешки 512 байт...
поэтому "умная" библиотека дополняет твои 64 байта своими ещё своими 448 байтами нулей... чтоб получилось ровно 512 байт.
и в таком виде твоя "умная библиотека записывает на флешку...

В сетевых технологиях... в Интернет... это называется padding: 00000000000000000000
или по другому это называется "выравнивание"
т.е. дополнения нулями до нужной длины пакета... для передачи пакета по Интернет.

в ПК этим занимается библиотека Socket...
olegue писал(а):качество звука сильно ухудшилось, как сделать что бы оцифровка звука была в облегченном режиме?
потому что ты не правильно настраиваешь ACD...

что такое ADMUX = 0x40; ? ADLAR - Выравнивание результата <<<

или так ADMUX = 0x60; ? ADLAR - Выравнивание результата >>>

ну допустим)) ADMUX = 0x40;

// циффруем напряжени с A0
ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 0 (left adjust)
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
rsValue=(ADCL|ADCH<<8); // результат преобразования записываем в переменную rsValue

// странная запись... ADCL|ADCH<<8... а не лучше так rsValue=ADCW; ? ... ))

// тут наверно пауза надо бы...

// не нужно тут никаких пауз...
// ADC закончил преобразование и готов к следующему преобразованию... без всяких пауз))

// переходим к следующему преобразованию...

// Цифруем звук с A1
ADMUX = 0x61; // set ADC to read pin A1, ADLAR to 1 (left adjust)
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready

что с качеством звука ?
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

Martian писал(а):что с качеством звука ?
звук все еще разборчивый, качество совсем плохое. Мой голос как будто я дед и мне 120 лет.

Добавлено after 38 seconds:
но счас я моложе
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Ардуино - запись звука

Сообщение roman.com »

а без этого кучка кода ...

// циффруем напряжени с A0
ADMUX = 0x40; // set ADC to read pin A0, ADLAR to 0 (left adjust)
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
rsValue=(ADCL|ADCH<<8); // результат преобразования записываем в переменную rsValue

всё нормально ?
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

roman.com, да

Добавлено after 42 seconds:
искажения вносятся именно этим куском.

Добавлено after 5 minutes 33 seconds:
причем искажения , как мне кажется влияют и на оцифровку сигнала с А0(напряжение), так как ранее при снятии сигнала через analogRead(A0) я получал стабильные данные(звук вообще не шел), а теперь они прыгают и не совсем адекватны.

Добавлено after 1 minute 41 second:
Я был на обеде, у меня было очень мало времени что бы повозиться и все как следует выяснить. Вечером наверстаю

Добавлено after 25 seconds:
Главное что бы идеи были.
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Ардуино - запись звука

Сообщение roman.com »

то что прыгают и не совсем адекватны... то ладно)) можно подкрутить))

ну всё ясно... ADC не успевает цифровать... случилось то о чём я писал выше...

твой таймер фигарит с частотой прерывания 22222,22222222222 Hz
соответственно время одного прерывания = 0,000045 секунд.
CTC.jpg
(16.81 КБ) 28 скачиваний
а твой ADC не поспевает за таймером...
ADC_250000Hz .jpg
(97.71 КБ) 27 скачиваний
значит...
или уменьшай частоту таймера...
или повышай частоту ADC...
тайминг_ADC_8000.jpg
(105.6 КБ) 27 скачиваний
:roll:
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Ардуино - запись звука

Сообщение olegue »

[uquote="roman.com",url="/forum/viewtopic.php?p=4245412#p4245412"]или уменьшай частоту таймера...
или повышай частоту ADC...
тайминг_ADC_8000.jpg
:roll:[/uquote]

ок, теперь я уже немного в теме и тогда объясните следущее

Здесь я настраиваю частоту выборки, каждый 1/22000= 45мкс будет начинатся преобразование ADC (если я прав- вопросов нет!)

Код: Выделить всё

void Setup_timer2() {

  TCCR2B = _BV(CS21);  // Timer2 Clock Prescaler to : 8
  TCCR2A = _BV(WGM21); // Interupt frequency  = 16MHz / (8 x 90 + 1) = 22191Hz
  OCR2A = 90; // Compare Match register set to 90

Далее

void Setup_ADC_0() {

Код: Выделить всё

ADMUX = 0x60; // set ADC to read pin A5, ADLAR to 1 (left adjust)
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);

а здесь что происходит, что это за частота? Куда ее пришить?
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
Добавлено after 1 minute 46 seconds:
как эта частота впишется в общую картину работы процессора. Иначе говоря, это столько времени будет затрачено на преобразование?

Добавлено after 1 minute 18 seconds:
т.е само преобразвание займет 1/2 000 000 = 0.5мкс?

Добавлено after 13 minutes 12 seconds:
что если я увеличу время преобзования для А0 (напряжене) до 125кгц (делитель 128) - до 8мкс, сняв лишную нагрузку с процессоа, а время преобразования АЦП для звука оставлю тем же. -0.5мкс.

Хотя я вот все равно не понимаю, если таймер лопатит с частотой 22кгц, то какая разница каким будет время преобразования и как это повлияет на результ оцифровки звука???
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Ардуино - запись звука

Сообщение roman.com »

выше писал... откуда частота 2 мгц для ADC...
[uquote="roman.com",url="/forum/viewtopic.php?p=4242524#p4242524"]// настройки ADC
// тут мы устанавливаем режим работы ADC

void Setup_ADC() {

ADMUX = 0x61; // set ADC to read pin A5, ADLAR to 1 (left adjust)
cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
}

или можно записать так (что одно и то же):

ADMUX = 0b01100001;

//ADMUX
//1... .... REFS1 - опорное напряжение - 0
//.1.. .... REFS0 - опорное напряжение - 1 - AVCC
//..1. .... ADLAR - Выравнивание результата
//...1 .... -
//.... 1... MUX3 - номер канала
//.... .1.. MUX2 - номер канала
//.... ..1. MUX1 - номер канала
//.... ...1 MUX0 - номер канала - ADC0...ADC7 (0000=ADC0)


//.1.. .... REFS0 - опорное напряжение - 1 - AVCC
// т.е. мы все измерения ADC проводим относительно напряжения питания Ардуино = 5 V.

//..1. .... ADLAR - Выравнивание результата
//ADLAR=1
// Выравнивание результата в левую сторону < (8-бит):
// ADCH // 1111 1111 - читать вторым (или первым, тогда последии 2 бит теряем)
// ADCL // 0000 0011 - читать первым

Это не совсем нормально))

я использую режим по умолчанию...

//ADLAR=0
// Выравнивание результата в правую сторону > (10-бит):
// ADCH // 0000 0011 - читать вторым
// ADCL // 1111 1111 - читать первым

Хотя ADLAR не принципиально... работать будет и так и так)) но я лучше буду использовать стандартные настройки ADLAR=0))

// MUX3...MUX0 - номер канала:
// 0000 - ADC0
// 0001 - ADC1
// .................
// 0111 - ADC7

Ардуина использует канал ADC номер 1. Что соответствует пину номер 24...
мега8.jpg
мега328.jpg
далее устанавливаем частоту преобразования ADC для Ардуины...

пишем регистр ADCSRA...

//ADCSRA
//1... .... ADEN - 1- вкл ADC. (0-ADC не потребляет мощности)
//.1.. .... ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
//..1. .... ADFR - 1- режим Непрерывного Преобразования.
//...1 .... ADIF - 1- флаг завершения преобразования
-сброс программно.
-для прерывания очищается аппаратно.
//.... 1... ADIE - 1- Разрешение прерывания
//.... .1.. ADPS2 - предделитель
//.... ..1. ADPS1 - предделитель
//.... ...1 ADPS0 - предделитель

для Ардуино написано так :

cbi(ADCSRA, ADPS2); // set prescaler to 8 / ADC clock = 2MHz
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);

по человечески это будет так:

cbi(ADCSRA, ADPS2); // cbi - сбросить бит в регистре ADCSRA
sbi(ADCSRA, ADPS1); // sbi - установить бит в регистре ADCSRA
sbi(ADCSRA, ADPS0); // sbi - установить бит в регистре ADCSRA

или можно записать так (что одно и то же):

ADCSRA = 0b00000011;

предделитель ADC:
ADPS2 -ADPS1 -ADPS0
----------
// 000: 1 МГц/2=500.000 Hz
// 001: 1 МГц/2=500.000 Hz
// 010: 1 МГц/4=250.000 Hz
// 011: 1 МГц/8=125.000 Hz
// 100: 1 МГц/16=62.500 Hz
// 101: 1 МГц/32=31.250 Hz
// 110: 1 МГц/64=15.625 Hz
// 111: 1 МГц/128=7.812,5 Hz
----------

предделитель ADC = 8
тактовая частота Ардуино 16 мгц.
значит... частота преобразования ADC в Ардуино = 16 мгц / 8 = 2 мгц.[/uquote]
если бы писал бы всё по человечески... то не было бы вопросов... откуда частота преобразования ADC в Ардуино = 16 мгц / 8 = 2 мгц.
Ответить

Вернуться в «AVR»