Обсуждаем контроллеры компании Atmel.
Ответить

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

Ср июн 01, 2022 01:32:12

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

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

Ср июн 01, 2022 06:34:39

2. когда буфер ATmega8 размером 512 байт заполнится, мы передаём 512 байт в буфер флешки SRAM на 512 байт

а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно

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

Ср июн 01, 2022 07:19:42

SRAM занято всего 85%

Вот компилятор и предупреждает, что ее мало осталось.

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

Ср июн 01, 2022 07:49:34

Код:
  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

а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно
делал плейер на меге8 (за основу взял плеер на тини2313 с гетчипа - главный недостаток того - недопустимость фрагментации т.к. чтение было побайтным, буфера не было и искать следующий блок было некогда) сделал буфер на 512, но затыки были, пришлось сделать 2 функции чтения, первая инициировала чтение и считывала первые 128 байт, вторая считывала остаток, вызывались они поочереди, при воспроизведении соответственно 128го и 0го байтов буфера. (цифры точно не помню - давно это было... помню, что буфер был разделен на неравные части)

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

Ср июн 01, 2022 09:01:39

мне не нравиться эта "программная перезагрузка". Не срывает ли она следующий за ней сброс данных на карту?

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

Morroc уже отмечат, что это какая-то дичь. Может и правда эта перезагрузка не нужна

И перезагрузка дичь и указанная причина тоже какая то дичь, но не исключаю, что какой то глюк она устраняет :))

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

Ср июн 01, 2022 10:29:59

Еще очень нужная вещь это увеличиение количества файлов , сейчас файлы нумеруются от 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

Morroc писал(а):а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно

а давайте посчитаем ! )) а лучше измерим))

когда я что-то делаю... я первым делом всё проверяю в Протеусе...

-когда я пишу на Си я считаю тайминги с точностью до 1 микросекунды))
тайминги.jpg
(150.85 KiB) Скачиваний: 39

-когда я пишу на Ассемблере я считаю тайминги с точностью до 1-го машинного такта процессора))
Ethernet-Atmega8-тр.jpg
(200.93 KiB) Скачиваний: 34


и с Ардуино я делаю тоже самое))
ILI9341-ардуино.jpg
(145.77 KiB) Скачиваний: 42

ааа... !!! я чуть не попал в секту свидетелей Ардуино))
:o

поэтому мы взяли код для TFT экрана из Ардуино..
ILI9341-ардуино-переделанный.jpg
(132.9 KiB) Скачиваний: 33

и переписывали код Ардуино на нормальный и понятный всем человеческий язык СИ ))
а затем уже нормальный переделанный код на понятном всем человеческом языке СИ мы залили в AVR...
ILI9341-ATmega128.jpg
(105.28 KiB) Скачиваний: 33

всё работает))
:tea:

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

Ср июн 01, 2022 13:21:43

а куда смотреть то ? где время ?

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

Ср июн 01, 2022 13:35:20

olegue писал(а):так пойдет?
да, тем более, что теперь можно записывать туда сразу сформированное имя, а не только int (если это понадобится)

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

Ср июн 01, 2022 14:43:10

roman.com писал(а):
Morroc писал(а):а мы это успеем между отсчетами ADC ? это надо практически проверять, все остальное вполне возможно

а давайте посчитаем ! )) а лучше измерим))

:)
берём код ADC...
ATmega8-ADC.c
(2.76 KiB) Скачиваний: 43

закидываем в Протеус и смотрим))
ADC.jpg
(97.71 KiB) Скачиваний: 38

одно преобразование ADC занимает 57 микросекунд... при условии // 8 МГц/32=250.000 Hz
и это с фильтром шума ADC ))
:tea:
а какая у нас частота wav потока ?
допустим 8000 семплов / секунду... это при минимальном качество звука))
значит мы должны запускать преобразование ADC каждые 1/8000 = 0,000125 секунд.
проверяем))
тайминг_ADC_0.jpg
(105.6 KiB) Скачиваний: 30

67 микросекунд - время преобразования ADC
58 микросекунд - свободное процессорное время))

оптимизируем))
отключим режим стабилизации ADC...
отключим фильтр шума ADC...
для записи wav они нам не нужны))
тайминг_ADC_1.jpg
(95.87 KiB) Скачиваний: 33

57 микросекунд - время преобразования ADC
68 микросекунд - свободное процессорное время))

ещё оптимизируем))
будем брать не 10 бит преобразования ADC... а будем брать младшие 8 бит преобразования ADC... чтоб был ровно один байт ))
ADC_55_us.jpg
(100.34 KiB) Скачиваний: 34

55 микросекунд - время преобразования ADC
70 микросекунд - свободное процессорное время))

Итого:
мы получили 70 микросекунд - свободное процессорное время))

Но пока мы так и не ответили на простой вопрос:
успеем ли мы за 70 микросекунд из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?

На самом деле 70 микросекунд - это вагон времени !!! ))
:))

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

Ср июн 01, 2022 15:14:16

olegue писал(а):так пойдет?
да, тем более, что теперь можно записывать туда сразу сформированное имя, а не только int (если это понадобится)

Код:
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

olegue писал(а): if (RecordNumber == 32767)RecordNumber = 0;
32767 не очень красиво, наверняка в ардуино есть константа типа INT_MAX, и тогда запись if (RecordNumber == INT_MAX) RecordNumber = 0; более универсальна - вдруг завтра int станет 4-разрядным... Но это так, мелочь и несущественно.

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

Ср июн 01, 2022 15:52:38

olegue писал(а):я смотрю тут Роман атмегу8 параллельно заряжает...

угу))
:)
далее...
а сколько времени занимает запись данных из ADC в буфер ?
ADC_bufer.jpg
(92.71 KiB) Скачиваний: 32

~1 микросекунда )) зависит от настройки... int... chart... и т.д.

а сколько времени занимает запись буфера 512 байт ATmega8 ?
считаем:
запускаем преобразование ADC каждые 1/8000 = 0,000125 секунд * 512 байт = 0,064 секунд.
проверяем...
ADC_bufer_512.jpg
(95.53 KiB) Скачиваний: 33

всё сходится))

Итого:
55 микросекунд - время преобразования ADC.
1 микросекунда - время записи ADC в буфер 512 байт ATmega8.
69 микросекунд - свободное процессорное время))
:tea:

значит мы должны записывать сектора на флешку каждые 0,064 секунды.
Или по другому - скорость записи флешки - 15,625 секторов в секунду))

И осталось ответить на последний вопрос:
успеем ли мы за 69 микросекунд из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?
:tea:
На самом деле 69 микросекунд - это вагон времени !!! ))

Добавлено after 19 minutes 16 seconds:
далее..
подключаем флешку к ATmega8 по SPI...

Отступление ))
В представленном коде...
microSD.c
(12.24 KiB) Скачиваний: 38

мы подключили флешку к 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;
}
:tea:
Скорость работы апаратного SPI = 8 МГц/4 = 2 МГц -режим мастер
С учётом накладных расходов... можно рассчитывать на ~ 1 Мбит/с.
:tea:

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

Ср июн 01, 2022 16:09:03

ну... можно же кварц пошустрей поставить, или сэмплрейт снизить... (на случай отсутствия аппаратного SPI)

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

Ср июн 01, 2022 16:44:46

olegue писал(а): if (RecordNumber == 32767)RecordNumber = 0;
32767 не очень красиво, наверняка в ардуино есть константа типа INT_MAX, и тогда запись if (RecordNumber == INT_MAX) RecordNumber = 0; более универсальна - вдруг завтра int станет 4-разрядным... Но это так, мелочь и несущественно.


а что если вместо INT объявить unsignet INT - это же беззнаковое целое , до 65 000. При этом можно ж до этой цифры файлы гнать?

Добавлено after 1 minute 17 seconds:
roman.com, в Атмеге8 есть аппаратный SPI?

Добавлено after 26 minutes 48 seconds:
а куда смотреть то ? где время ?


Подключаю часы по 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

в Атмеге8 есть аппаратный SPI?

Да.
1.png
(12.44 KiB) Скачиваний: 33

2.png
(67.24 KiB) Скачиваний: 34

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

Ср июн 01, 2022 17:45:51

далее...
ну... можно же кварц пошустрей поставить, или сэмплрейт снизить... (на случай отсутствия аппаратного SPI)

1. кварц мы пока ставить не будем.
2. семплерт снижать уже некуда)) и так уже минимальное качество звука - 8000 семплов/с.

далее...

Скорость работы апаратного SPI = 8 МГц/4 = 2 МГц -режим мастер
С учётом накладных расходов... можно рассчитывать на ~ 1 Мбит/с.

сколько по времени передать из буфера ATmega8 размером 512 байт передать 512 байт в буфер флешки SRAM на 512 байт ?
считаем...
~ 1 Мбит/с / 8 = 125000 байт/c.
1 байт будем передавать... 0,000008 с.
проверяем...
SPI_1.jpg
(96.71 KiB) Скачиваний: 34

всё сходится))
:tea:
а нам надо передать 512 байт...
0,000008 с * 512 = 0,004096.
проверяем...
SPI_0.jpg
(94.14 KiB) Скачиваний: 37

всё сходится))
:tea:

а сколько у нас свободного процессорного времени ? 0,000069 c....
Не сходится !
:))
а я предупреждал... ))
:tea:

1. за 0,000069 c.... мы можем передать только 8 байт... а это 512/8 = 64 раза меньше чем нужно ))
а что делать ?
:dont_know:

2. самое простое - это переключить SPI в режим удвоенной скорости )) x2 )) так мы уже делали в прошлом проекте...
за 0,000069 c.... SPI будет передавать по 16 байт... всё равно мало))

3. переключить тактовый генератор с 8 МГц на 16 МГц (как в Ардуино). так мы уже делали в прошлом проекте...
за 0,000069 c.... SPI будет передавать по 32 байт... всё равно мало))
максимальная рабочая тактовая частота ATmega8 до 25 МГц... всё равно мало)) так мы уже делали в прошлом проекте...
как ни крути... поднимать частоту бессмысленно))

4. нужно изменить алгоритм работы... Если за один раз передать не получается, то будем передавать частями)) точно!))
так мы уже делали в прошлом проекте...
:tea:

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

Ср июн 01, 2022 18:31:55

если данные АЦП писать сразу на флешку,когда сектор заполнится переходим в след сектор-получится?

каждый байт что ли ? кроме того, что это изнасилование флэшки (она побайтно не умеет и будет переписывать сектор), так еще и долго

понаберут восьмых мег на 20р дешевле, потом мозг ломают себе и окружающим :))

Читайте первый пост данной темы-автор темы хочет переделать на атмега8 а не я

Добавлено after 4 minutes 46 seconds:
4. вот именно это я и имел ввиду,но думал писать побайтно
И причем тут "(она побайтно не умеет и будет переписывать сектор)",я и пишу что пишем сектор,просто самы байты пишем не со скоростью несколько миллионов в секунду,а после каждого преобразования АЦП,то есть если АЦП работает на частоте 8 кГц то и передаем байты с такой же скоростью,дошли до конца сектора-переключились на следующий и дальше пишем

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

Ср июн 01, 2022 18:55:39

4. мы можем передавать буфер частями... по 1... 2... 3... 4... 5... 6... 7... 8... байт
тогда нам нужно 512 / 8 = 64 транзакции))

5. мы вообще можем не использовать буфер ATmega8... а измерять ADC и сразу передавать по SPI...
ADC_SPI.jpg
(93.89 KiB) Скачиваний: 33

Итого:
55 микросекунд - время преобразования ADC.
8 микросекунд - время передачи по SPI.
62 микросекунд - свободное процессорное время))
так совсем хорошо))
:tea:
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// 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[b]; 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.

надо выкинуть отсюда всё лишнее ))
Последний раз редактировалось roman.com Ср июн 01, 2022 18:58:06, всего редактировалось 1 раз.
Ответить