Страница 4 из 36
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 01:32:12
Martian
[uquote="roman.com",url="/forum/viewtopic.php?p=4239636#p4239636"]вот так люди попадают в секту свидетелей ардуино ))[/uquote]смех смехом, но недавно изменил своё отношение к ардуино, и больше не называю одурино-обдурино и т.д. Сам-то пользоваться не буду, нет необходимости, но для кого-то это вполне приемлемо. А фигню слепить можно из любых компонентов, дело не в них.
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 06:34:39
Morroc
[uquote="roman.com",url="/forum/viewtopic.php?p=4239636#p4239636"]2. когда буфер ATmega8 размером 512 байт заполнится, мы передаём 512 байт в буфер флешки SRAM на 512 байт[/uquote]
а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 07:19:42
codenamehawk
[uquote="Novice user",url="/forum/viewtopic.php?p=4238977#p4238977"]SRAM занято всего 85%[/uquote]
Вот компилятор и предупреждает, что ее мало осталось.
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 07:49:34
olegue
Код: Выделить всё
StopRec(); // launch StopRec method
/* Поэтому (Делаем программную перезагрузку). */
((void (*)())0x0000)(); /* Делаем программную перезагрузку - Arduino */
}
if (recByteCount % 1024 == 512 && recPressed == 1) {
rec.write(buf00, 512); // save buf01 to card
recByteSaved += 512;
}
if (recByteCount % 1024 == 0 && recPressed == 1) {
rec.write(buf01, 512); // save buf02 to card
recByteSaved += 512;
мне не нравиться эта "программная перезагрузка". Не срывает ли она следующий за ней сброс данных на карту?
Добавлено after 19 minutes 34 seconds:
в оригинальном коде разработчика (
http://apcmag.com/arduino-projects-digi ... order.htm/) такой строчки нет
ссылка недоступна, web arhiv Тоже не помог. Если кто-то найдет оригинальную страницу, будет интересно посмотреть
Код: Выделить всё
void loop() { // THIS RUNS LOTS!
if (digitalRead(btnStart) == LOW && recPressed == 0) {
StartRec(); // launch StartRec method
}
if (digitalRead(btnStop) == LOW) {
StopRec(); // launch StopRec method
}
if (recByteCount % 1024 == 512 && recPressed == 1) { rec.write(buf00,512); recByteSaved+= 512; } // save buf01 to card
if (recByteCount % 1024 == 0 && recPressed == 1) { rec.write(buf01,512); recByteSaved+= 512; } // save buf02 to card
}
Добавлено after 2 minutes 3 seconds:
Код: Выделить всё
После окончания записи, в памяти контроллера остаются данные.
И за этого следующая запись бывает качеством хуже.
Поэтому (Делаем программную перезагрузку).
*/
((void (*)())0x0000)(); /* Делаем программную перезагрузку - Arduino */
Morroc уже отмечат, что это какая-то дичь. Может и правда эта перезагрузка не нужна
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 08:23:28
Ivanoff-iv
[uquote="Morroc",url="/forum/viewtopic.php?p=4239675#p4239675"]а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно[/uquote] делал плейер на меге8 (за основу взял плеер на тини2313 с гетчипа - главный недостаток того - недопустимость фрагментации т.к. чтение было побайтным, буфера не было и искать следующий блок было некогда) сделал буфер на 512, но затыки были, пришлось сделать 2 функции чтения, первая инициировала чтение и считывала первые 128 байт, вторая считывала остаток, вызывались они поочереди, при воспроизведении соответственно 128го и 0го байтов буфера. (цифры точно не помню - давно это было... помню, что буфер был разделен на неравные части)
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 09:01:39
Morroc
[uquote="olegue",url="/forum/viewtopic.php?p=4239681#p4239681"]мне не нравиться эта "программная перезагрузка". Не срывает ли она следующий за ней сброс данных на карту?[/uquote]
не срывает, просто добавляет паузу перед следующим стартом записи. если залить программатором без загрузчика, то будет незаметно, думаю
[uquote="olegue",url="/forum/viewtopic.php?p=4239681#p4239681"]Morroc уже отмечат, что это какая-то дичь. Может и правда эта перезагрузка не нужна[/uquote]
И перезагрузка дичь и указанная причина тоже какая то дичь, но не исключаю, что какой то глюк она устраняет

Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 10:29:59
olegue
Еще очень нужная вещь это увеличиение количества файлов , сейчас файлы нумеруются от 0 до 255 , т.е используется типа BYTE
хочу перейти к int и увеличить до 32000
счас у меня вот так
Код: Выделить всё
byte RecordNumber; /* Номер записи - храним в EEPROM. в диапазоне 0..255. */
..................
/* Записываем в RecordNumber, значение из ячейки №0 EEPROM, и прибавляем 1. */
RecordNumber = EEPROM.read(0) + 1;
/* Записываем в ячейку №0 EEPROM, увеличенное значение RecordNumber. */
EEPROM.write(0, RecordNumber);
вычитал тут
http://codius.ru/articles/Arduino_EEPRO ... 1%8C%D1%8E
что теперь нужно использовать put и get
Код: Выделить всё
int RecordNumber; /* Номер записи - храним в EEPROM. в диапазоне 0..32767. */
..................
void loo(){
.............
/* Записываем в RecordNumber, значение из ячейки №0 EEPROM, и прибавляем 1. */
EEPROM.get(0,RecordNumber+ 1) ;
/* Записываем в ячейку №0 EEPROM, увеличенное значение RecordNumber. */
EEPROM.put(0, RecordNumber);
так пойдет?
Добавлено after 37 minutes 40 seconds:
часы таки придется пристраивать. Как имея информацию с часов записать файл с правильным временем?
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 13:12:23
roman.com
Morroc писал(а):а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно
а давайте посчитаем ! )) а лучше измерим))
когда я что-то делаю... я первым делом всё проверяю в Протеусе...
-когда я пишу на Си я считаю тайминги с точностью до 1 микросекунды))
-когда я пишу на Ассемблере я считаю тайминги с точностью до 1-го машинного такта процессора))
и с Ардуино я делаю тоже самое))
ааа... !!! я чуть не попал в секту свидетелей Ардуино))
поэтому мы взяли код для TFT экрана из Ардуино..
и переписывали код Ардуино на нормальный и понятный всем человеческий язык СИ ))
а затем уже нормальный переделанный код на понятном всем человеческом языке СИ мы залили в AVR...
всё работает))

Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 13:21:43
Morroc
а куда смотреть то ? где время ?
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 13:35:20
Martian
olegue писал(а):так пойдет?
да, тем более, что теперь можно записывать туда сразу сформированное имя, а не только int (если это понадобится)
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 14:43:10
roman.com
roman.com писал(а):Morroc писал(а):а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно
а давайте посчитаем ! )) а лучше измерим))
берём код ADC...
закидываем в Протеус и смотрим))
одно преобразование ADC занимает 57 микросекунд... при условии // 8 МГц/32=250.000 Hz
и это с фильтром шума ADC ))
а какая у нас частота wav потока ?
допустим 8000 семплов / секунду... это при минимальном качество звука))
значит мы должны запускать преобразование ADC каждые 1/8000 = 0,000125 секунд.
проверяем))
67 микросекунд - время преобразования ADC
58 микросекунд - свободное процессорное время))
оптимизируем))
отключим режим стабилизации ADC...
отключим фильтр шума ADC...
для записи wav они нам не нужны))
57 микросекунд - время преобразования ADC
68 микросекунд - свободное процессорное время))
ещё оптимизируем))
будем брать не 10 бит преобразования ADC... а будем брать младшие 8 бит преобразования ADC... чтоб был ровно один байт ))
55 микросекунд - время преобразования ADC
70 микросекунд - свободное процессорное время))
Итого:
мы получили 70 микросекунд - свободное процессорное время))
Но пока мы так и не ответили на простой вопрос:
успеем ли мы за 70 микросекунд из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?
На самом деле 70 микросекунд - это вагон времени !!! ))

Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 15:14:16
olegue
[uquote="Martian",url="/forum/viewtopic.php?p=4239815#p4239815"]
olegue писал(а):так пойдет?
да, тем более, что теперь можно записывать туда сразу сформированное имя, а не только int (если это понадобится)[/uquote]
Код: Выделить всё
if (digitalRead(btnStart) == LOW && recPressed == 0) {
/* Записываем в RecordNumber, значение из ячейки №0 EEPROM, и прибавляем 1. */
/*RecordNumber = EEPROM.read(0) + 1;*/
if (RecordNumber == 32767)RecordNumber = 0;
EEPROM.get(0,RecordNumber) ;
/* Записываем в ячейку №0 EEPROM, увеличенное значение RecordNumber. */
/*EEPROM.write(0, RecordNumber);*/
EEPROM.put(0, RecordNumber+1);
да, все получилось
roman.com писал(а):берём код ADC...
я смотрю тут Роман атмегу8 параллельно заряжает...
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 15:29:02
Martian
olegue писал(а): if (RecordNumber == 32767)RecordNumber = 0;
32767 не очень красиво, наверняка в ардуино есть константа типа INT_MAX, и тогда запись if (RecordNumber == INT_MAX) RecordNumber = 0; более универсальна - вдруг завтра int станет 4-разрядным... Но это так, мелочь и несущественно.
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 15:52:38
roman.com
olegue писал(а):я смотрю тут Роман атмегу8 параллельно заряжает...
угу))
далее...
а сколько времени занимает запись данных из ADC в буфер ?
~1 микросекунда )) зависит от настройки... int... chart... и т.д.
а сколько времени занимает запись буфера 512 байт ATmega8 ?
считаем:
запускаем преобразование ADC каждые 1/8000 = 0,000125 секунд * 512 байт = 0,064 секунд.
проверяем...
всё сходится))
Итого:
55 микросекунд - время преобразования ADC.
1 микросекунда - время записи ADC в буфер 512 байт ATmega8.
69 микросекунд - свободное процессорное время))
значит мы должны записывать сектора на флешку каждые 0,064 секунды.
Или по другому - скорость записи флешки - 15,625 секторов в секунду))
И осталось ответить на последний вопрос:
успеем ли мы за 69 микросекунд из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?
На самом деле 69 микросекунд - это вагон времени !!! ))
Добавлено after 19 minutes 16 seconds:
далее..
подключаем флешку к ATmega8 по SPI...
Отступление ))
В представленном коде...
мы подключили флешку к ATmega8 по программному SPI...
////////////////////////////////////////// программный SPI3/4МГц/0.000.060 microSD:
void SPI3(void)
{
rx3=0; // сброс RX
mask3=0b10000000;
do {
if (tx3 & mask3) PORTD.7 = 1;// выход MOSI
else PORTD.7 = 0;// выход MOSI
delay_us(2);
PORTD.6=1; // выход SCK
if (PIND.5) rx3 |= mask3; // вход MISO
PORTD.6=0; // выход SCK
mask3=(mask3>>1);
}
while (mask3);
delay_us(2);
PORTD.7 = 0; // сброс MOSI
}
а в каких случаях используется программный SPI ?
например в случае отсутствия апаратного SPI в МК )) мы же пишем универсальный код... для любых МК ))
проблема в том что программный SPI работает медленно... ~ 100 кбит/с... в 69 микросекунд не уложимся))
значит будем подключать флешку по апаратному SPI...
////////////////////////////////// SPI:
void SPI(void)
{
SPDR=tx; while(!(SPSR & (1<<7))); rx=SPDR;
}
Скорость работы апаратного SPI = 8 МГц/4 = 2 МГц -режим мастер
С учётом накладных расходов... можно рассчитывать на ~ 1 Мбит/с.

Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 16:09:03
Ivanoff-iv
ну... можно же кварц пошустрей поставить, или сэмплрейт снизить... (на случай отсутствия аппаратного SPI)
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 16:44:46
olegue
[uquote="Martian",url="/forum/viewtopic.php?p=4239857#p4239857"]
olegue писал(а): if (RecordNumber == 32767)RecordNumber = 0;
32767 не очень красиво, наверняка в ардуино есть константа типа INT_MAX, и тогда запись if (RecordNumber == INT_MAX) RecordNumber = 0; более универсальна - вдруг завтра int станет 4-разрядным... Но это так, мелочь и несущественно.[/uquote]
а что если вместо INT объявить unsignet INT - это же беззнаковое целое , до 65 000. При этом можно ж до этой цифры файлы гнать?
Добавлено after 1 minute 17 seconds:
roman.com, в Атмеге8 есть аппаратный SPI?
Добавлено after 26 minutes 48 seconds:
[uquote="Morroc",url="/forum/viewtopic.php?p=4239803#p4239803"]а куда смотреть то ? где время ?[/uquote]
Подключаю часы по i2c, но на А5 (SCL) висит вход звука. Поэтому буду его перености на А0
Код: Выделить всё
void Setup_ADC() {
ADMUX = 0x65; // 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=0x65 это в двоичной 0b0110 0101 где 0101 и есть А5, а мне надо А0 т.е 0000
получаю 0b0110 0000 , перевожу в хекс - ADMUX=0x60
Годится?
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 17:01:45
VNS
[uquote="olegue",url="/forum/viewtopic.php?p=4239875#p4239875"]в Атмеге8 есть аппаратный SPI?[/uquote]
Да.
- 1.png
- (12.44 КБ) 69 скачиваний
- 2.png
- (67.24 КБ) 67 скачиваний
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 17:45:51
roman.com
далее...
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4239871#p4239871"]ну... можно же кварц пошустрей поставить, или сэмплрейт снизить... (на случай отсутствия аппаратного SPI)[/uquote]
1. кварц мы пока ставить не будем.
2. семплерт снижать уже некуда)) и так уже минимальное качество звука - 8000 семплов/с.
далее...
Скорость работы апаратного SPI = 8 МГц/4 = 2 МГц -режим мастер
С учётом накладных расходов... можно рассчитывать на ~ 1 Мбит/с.
сколько по времени передать из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?
считаем...
~ 1 Мбит/с / 8 = 125000 байт/c.
1 байт будем передавать... 0,000008 с.
проверяем...
всё сходится))
а нам надо передать 512 байт...
0,000008 с * 512 = 0,004096.
проверяем...
всё сходится))
а сколько у нас свободного процессорного времени ? 0,000069 c....
Не сходится !
а я предупреждал... ))
1. за 0,000069 c.... мы можем передать только 8 байт... а это 512/8 = 64 раза меньше чем нужно ))
а что делать ?
2. самое простое - это переключить SPI в режим удвоенной скорости )) x2 )) так мы уже делали в прошлом проекте...
за 0,000069 c.... SPI будет передавать по 16 байт... всё равно мало))
3. переключить тактовый генератор с 8 МГц на 16 МГц (как в Ардуино). так мы уже делали в прошлом проекте...
за 0,000069 c.... SPI будет передавать по 32 байт... всё равно мало))
максимальная рабочая тактовая частота ATmega8 до 25 МГц... всё равно мало)) так мы уже делали в прошлом проекте...
как ни крути... поднимать частоту бессмысленно))
4. нужно изменить алгоритм работы... Если за один раз передать не получается, то будем передавать частями)) точно!))
так мы уже делали в прошлом проекте...

Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 18:31:55
Novice user
[uquote="Morroc",url="/forum/viewtopic.php?p=4239580#p4239580"][uquote="Novice user",url="/forum/viewtopic.php?p=4239571#p4239571"]если данные АЦП писать сразу на флешку,когда сектор заполнится переходим в след сектор-получится?[/uquote]
каждый байт что ли ? кроме того, что это изнасилование флэшки (она побайтно не умеет и будет переписывать сектор), так еще и долго
понаберут восьмых мег на 20р дешевле, потом мозг ломают себе и окружающим

[/uquote]
Читайте первый пост данной темы-
автор темы хочет переделать на атмега8 а не я
Добавлено after 4 minutes 46 seconds:
4. вот именно это я и имел ввиду,но думал писать побайтно
И причем тут "(она побайтно не умеет и будет переписывать сектор)",я и пишу что пишем сектор,просто самы байты пишем не со скоростью несколько миллионов в секунду,а после каждого преобразования АЦП,то есть если АЦП работает на частоте 8 кГц то и передаем байты с такой же скоростью,дошли до конца сектора-переключились на следующий и дальше пишем
Re: Ардуино - запись звука
Добавлено: Ср июн 01, 2022 18:55:39
roman.com
4. мы можем передавать буфер частями... по 1... 2... 3... 4... 5... 6... 7... 8... байт
тогда нам нужно 512 / 8 = 64 транзакции))
5. мы вообще можем не использовать буфер ATmega8... а измерять ADC и сразу передавать по SPI...
Итого:
55 микросекунд - время преобразования ADC.
8 микросекунд - время передачи по SPI.
62 микросекунд - свободное процессорное время))
так совсем хорошо))

//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// TX_microSD:
void TX_microSD(unsigned long x)
{
/////////////////////// crc bufer_microSD[512]:
crc=0xFFFF;
for (b=0;b<510;b=b+2) {
bcrc=bufer_microSD
; bcrc=(bcrc<<8)|bufer_microSD[b+1]; fcrc();
};
bufer_microSD[510]=(crc>>8); // crc
bufer_microSD[511]=crc; // crc
///////////////////////////////////////////////
PORTB.0=0; // SS microSD
/////////////////////// запись Data:
tx3=0x58; SPI3(); // 01xx xxxx + Номер команды - CMD24
tx3=(x>>24); SPI3(); // адрес
tx3=(x>>16); SPI3(); // адрес
tx3=(x>>8); SPI3(); // адрес
tx3=x; SPI3(); // адрес
tx3=0x00; SPI3(); // 0000 0000. CRC - 0
// ответ R1: 0000 0000 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); // STATUS R1 0000 0000
//////////////////////////////////////////////////////////////////////////////// метка:
tx3=0xFE; SPI3(); // 0xFE метка для команды - CMD24
//////////////////////
for (a=0; a<512; a++) {
tx3=ADC; SPI3(); // ADC > microSD
};
////////////////////
tx3=0x00; SPI3(); // CRC - 0
tx3=0x00; SPI3(); // CRC - 0
/////////////////////////////////////////////////////////// ответ - данные приняты 0xE5:
tx3=0xFF; SPI3(); // SPI пустой
/////////////////////////////////////////////////// ждём окончания записи... OUT = 0xFF:
while ( (x1 != 0xFF) && (tm_microSD != 255) ) {
tx3=0xFF; SPI3(); x1=rx3; // MOSI 0x00 > MOSI 0xFF // -цикл 34...53
tm_microSD++;
};
//////////////
if (tm_microSD == 255) { // таймаут microSD:
error_microSD_EEPROM |= 0b00010000; // 0001 0000 - error microSD_TX
};
tm_microSD = 0; // сброс таймаут tm_microSD.
////////////////////////////////////////////////////////////////
PORTB.0=1; // SS microSD
////////////////////////////////////////////////////////////////////////////////////////
// microSD - ток = 0 mA.
надо выкинуть отсюда всё лишнее ))