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

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

Вт май 31, 2022 11:51:15

тяжко ли переписать этот код скажем, на СИ, отказавшись совсем от Ардуино.

не тяжко ))
:tea:
может быть использование среды ардуино здесь неоправдано.

на вкус и цвет... ))
Или может кто-то видел готовый проект на СИ для avr?

:dont_know:
лучше написать самому...

а зачем нам флешка ? а давайте писать на ПК ! )) щас вот как раз делаю связь с ПК...
:roll:

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

Вт май 31, 2022 12:19:13

давайте сразу без МК писать на ПК, у нас что, звуковухи нет ? )))

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

Вт май 31, 2022 12:40:08

Morroc писал(а):давайте сразу без МК писать на ПК, у нас что, звуковухи нет ? )))


не, у меня попытка соскочить с ПК

Код:
void loop(){

label:

Если (Кнопка==LOW) {НачатьЗапись();}  // Кнопка нажата - начата запись

Иначе Если (Кнопка==HIGH)  // Кнопка отпущена (попытка остановить запись)
   {
    if (millis() - timing > 2000)  //считаем 2 секунды с момента прекращения записи
      {
        timing = millis();
        Если (Кнопка==LOW) {GOTO label;  // Если в течении 2сек кнопка нажалась уходим в начало loop
      }
     // Есили Кнопка по прежнему отпущена
     ОстановитьЗапись();
   }
   СбросДанныхНаКарту();
}


вот такой код. Посмотрите. Goto -не камифльфо, но может тут прокатит?

Добавлено after 4 minutes 26 seconds:
мне кажется с millis() я перемудрил

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

Вт май 31, 2022 12:48:20

тут есть millis - это хорошо, в остальном пока не очень )

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

Вт май 31, 2022 12:57:24

не вижу в логике ошибок. Подскажие че не так. Перенес label , поставли перед СбросНаКарту()
Код:
void loop(){



Если (Кнопка==LOW) {НачатьЗапись();}  // Кнопка нажата - начата запись

Иначе Если (Кнопка==HIGH)  // Кнопка отпущена (попытка остановить запись)
   {
    if (millis() - timing > 2000)  //прошло 2 секунды с момента прекращения записи
      {
        timing = millis();
        Если (Кнопка==LOW) {GOTO label;  // Если запись возобновили перейдем по метке
      }
     // Есили запись не возобнолена, оставновим
     ОстановитьЗапись();
   }
   label:         //Поставлю метку сюда. Так логичее что-ли???
   СбросДанныхНаКарту();   
}

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

Вт май 31, 2022 13:22:03

не вижу в логике ошибок. Подскажие че не так.


>Если (Кнопка==LOW) {НачатьЗапись();} // Кнопка нажата - начата запись
а в следующий итерации loop через миллисекунду снова НачатьЗапись(); ? кнопку не успеют отпустить

>Иначе Если (Кнопка==HIGH) // Кнопка отпущена (попытка остановить запись)
> {
> if (millis() - timing > 2000) //прошло 2 секунды с момента прекращения записи
в общем случае мы не знаем что у нас в timing в этот момент, может быть что угодно

>{
>timing = millis();
это нужно сделать как только требуется начать отсчет времени, а не в условии if (millis() - timing > 2000)

>Если (Кнопка==LOW) {GOTO label; // Если запись возобновили перейдем по метке
это лишнее, если LOW мы сюда скорее всего не попадем вообще
>}

>ОстановитьЗапись();
это должно быть внутри условия if (millis() - timing > 2000), а не внутри Кнопка = High

>СбросДанныхНаКарту();
это должно выполнятся всегда, а не по условиям

А что бы определить что нужно сделать стоп я измеряю паузу (пытаюсь измерить) . Если пауза менее 2.5сек,то запись не прекращается. Вот такая задумка. Ну это к тому что я полагаю,что запись за флэшку идет уже после Стопа.

судя по коду вы делаете что то вроде жирной защиты от дребезга. типа если отпустили кнопку, но успели её нажать снова за 2 сек - запись не прекращаем, но если проблема в записи после стопа, то она тут никак не решается, после стопа можно тут же стартовать. так что не совсем понятно что именно вам нужно

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

Вт май 31, 2022 14:44:38

Morroc, не согласен частично с тем как вы раскритиковали мой "код", но я вижу что тут дело в том , что мы руководствуемся разной логикой. Я еще раз проверю как работает сразу после стопа, а потом уже буду чтото мудрить. Потому что если кнопку нажимаешь рукой это одно , но у меня кнопку нажимает релюха и "держит" ее пока идет сигнал.

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

Вт май 31, 2022 15:02:42

Я еще раз проверю как работает сразу после стопа, а потом уже буду чтото мудрить.


вот так работает стоп, все что после работает уже после

void StopRec() { // stop recording process, update WAV header, close file

cbi (TIMSK2, OCIE2A); // disable timer interrupt
writeOutHeader();
digitalWrite(ledStart, LOW); // turn off recording LED
digitalWrite(ledStop, HIGH); // light stop LED
recPressed = 0;

}

void writeOutHeader() { // update WAV header with final filesize/datasize

rec.seekSet(4);
byte1 = recByteSaved & 0xff;
byte2 = (recByteSaved >> 8) & 0xff;
byte3 = (recByteSaved >> 16) & 0xff;
byte4 = (recByteSaved >> 24) & 0xff;
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
rec.seekSet(40);
rec.write(byte1); rec.write(byte2); rec.write(byte3); rec.write(byte4);
rec.close();

}


Потому что если кнопку нажимаешь рукой это одно , но у меня кнопку нажимает релюха и "держит" ее пока идет сигнал.

Не вижу разницы )

Morroc, не согласен частично с тем как вы раскритиковали мой "код", но я вижу что тут дело в том , что мы руководствуемся разной логикой.

Напишите еще раз как надо. Из того как могу себе представить работу девайса и проблему "недозаписи" вижу несоответствие кода этому я.

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

Вт май 31, 2022 15:45:59

Итак, говорят 2-3 собеседника. Сначала говорит один, релюха нажата, запись идет. Первый собеседник прекращает разговор , релюха размыкается, и тут же спустя 0.5-1сек начинает говорить 2-й. Проблема началась когда 1 собеседник сказал, типа я перед тем как начал второй, еще там кое -что говорил и это не попало в протокол и соответственно в аудиофайл. В итоге результаты игры отменили. И я подумал, если между собеседниками пауза таки есть , то почему бы ее программно сгладить что ее как бы нет ведь выступления идут один за другим без остановки. А когда остановка произошла, то это фактически конец раунда и можно сделать стоп и уже не беспокоится что ввиду низкой скорости записи данных на карту не все будет записано.

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

Добавлено after 4 minutes 54 seconds:
можно было писать в один файл, но длинна раунда разная и потом придется это редактировать. Ну , короче хочется сделать более менее оптимально.

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

Вт май 31, 2022 15:49:26

Если речь о коде с первой страницы темы (~9 сообщение), то после отпускания кнопки цикл

for (int i = 0; i <= 250; i++) { /*ждем секунду*/
if (digitalRead(btnStart) == LOW){paused=1;break;} /*есил была зафиксирована пауза выходим из ожидания (из цикла фо) */
delay(10);
}

блокирует полностью работу мк на 2.5 сек, в это время ничего не записывается ни в буфер ни на флэшку, далее по коду закрытие файла и рестарт

если у вас релюшка, то можно было как две кнопки сделать и использовать с изначальным кодом, в нормальном положении стоп, в замкнутом запись - не пробовали ?

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


в общем просто задержка стопа записи чтобы при коротких паузах продолжалась запись, а при >2 сек уже стоп ?

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

Вт май 31, 2022 16:09:28

olegue писал(а):если у вас релюшка, то можно было как две кнопки сделать и использовать с изначальным кодом, в нормальном положении стоп, в замкнутом запись - не пробовали ?


не понял мысль, а что мне это решает в плане организации задержки в 2 сек. Так , кстати , тоже можно . Я просто заморочился немного насчет одной кнопки

Morroc писал(а):в общем просто задержка стопа записи чтобы при коротких паузах продолжалась запись, а при >2 сек уже стоп ?


Точно так!

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

Вт май 31, 2022 16:51:48

Morroc писал(а):давайте сразу без МК писать на ПК, у нас что, звуковухи нет ? )))

яне предлагал отказаться от МК... я предложил только отказаться от флешки)) т.е. вместо флешки использовать ПК.
Вот и всё))
:tea:

Добавлено after 6 minutes 35 seconds:
я уже делал звук на ATmega8... записывал с помощью АЦП... а воспроизводил с помощью быстрой ШИМ на таймере...
есть осциллограммы даже... как это вё работает))

а вот кусок кода для ATmega8 для работы с флешкой... всё на Си.))
microSD.c
(12.24 KiB) Скачиваний: 51

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

делать на Ардуино... не хочу.
Ардуино тупая))
:tea:

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

Вт май 31, 2022 16:52:39

Точно так!


что то наподобие


unsigned long timer1;
int timer1on = 0;

void loop() { // THIS RUNS LOTS!

if (digitalRead(btnStart) == LOW && recPressed == 0) {
/* Записываем в RecordNumber, значение из ячейки №0 EEPROM, и прибавляем 1. */
RecordNumber = EEPROM.read(0) + 1;
/* Записываем в ячейку №0 EEPROM, увеличенное значение RecordNumber. */
EEPROM.write(0, RecordNumber);
/* Для конвертации из byte в char / из RecordNumber в NameRecord */
String str; //declaring string.
str = String(RecordNumber); //converting integer into a string.
str.toCharArray(NameRecord, 4); //passing the value of the string to the character array.
StartRec(); // launch StartRec method
timer1on = 0;
}
else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 0) {
timer1 = millis();
timer1on = 1;
}
else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 1 && (millis() - timer1) > 2000) {
StopRec();
/*
После окончания записи, в памяти контроллера остаются данные. <- какая то странная дичь написана
И за этого следующая запись бывает качеством хуже.
Поэтому (Делаем программную перезагрузку).
*/
((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;
}

}

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

Вт май 31, 2022 17:01:56

Код:
else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 0) {
timer1 = millis();
timer1on = 1;
}
else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 1 && (millis() - timer1) > 2000) {
StopRec();


да, уж. Действительно, все довольно просто!
увидели что запрошена остановка - запустили таймер
увидели что запрошена остановка и таймер отщелкал 2 сек - запустили остановку

КРУТО!

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

Вт май 31, 2022 17:18:33

угу, так конечный автомат работает - на состояниях/событиях, основной цикл loop свободно крутится без задержек пока что нибудь новое не произойдет, условия можно друг в друга и не вкладывать

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

Вт май 31, 2022 18:08:12

roman.com, Вам также огромное уважение. Буду разбираться с Вашим кодом. Это для меня хороший старт.

Добавлено after 8 minutes 51 second:
roman.com, код посмотрел, но пока , как баран на новые ворота, прокомментируйте, ну или, как им пользоваться, можно примеры?

Добавлено after 21 minute 29 seconds:
ну я так понял , что там тока инициализация карты. Адс, таймеры, сэмплирование, это все еще предстоит написать.

Добавлено after 18 minutes 4 seconds:
хотелось бы еще конечно и часы точного времени пристроить.

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

Вт май 31, 2022 18:46:34

фм приемник еще и экранчик )

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

Вт май 31, 2022 18:53:19

прокомментируйте....

:shock: :))
это кусок кода для работы с флешкой: чтение/запись... подсчёт контрольных сумм...
а всякие там Адс, таймеры, сэмплирование, это все еще предстоит написать...

как этот кусок кода работает ? очень просто))

введение))
для работы с флешками все используют библиотеки... типа #include <SD.h>
в этой библиотеке (#include <SD.h>) уже есть встроенная инициализация... управление... и т.д.

https://radioprog.ru/post/334

Но ! Настоящие программисты не используют библиотек ! )) Настоящие программисты пишут всё сами... "вручную" ))

Открываем даташит флешки и читаем...
Всё управление флешкой происходит через регистры. Как и всеми другими устройствами (радио модулями... LCD экранами... и т.д.).
Регистры можно читать/писать...
Есть разные регистры... регистры статуса... регистры управления (они же регистры команд)... и т.д.
:))

Код простой - тупо читаем/пишем регистры флешки... с помощью любого МК... Например ATmega8.
:roll:

Пример:
1.
после включения питания первым делом надо проинициализировать флешку.
по умолчанию флешка работает по интерфейсу SD.
а нам надо чтобы флешка работала по интерфейсу SPI.
режим_SPI.jpg
(42.16 KiB) Скачиваний: 41

а так же перед началом работы с флешкой надо настроить дополнительные параметры работы флешки... всякие там напряжения питания... и т.д. (см. даташит).

для этого подключаем флешку к ATmega8 и отправляем по SPI следующие несколько команд (прописываем регистры управления флешки)...


///////////////////////////////////////////////////////////////// инициализация microSD:
///////////////////////////////// Преамбула - 80 синхроимпульсов.
for (x=0; x<10; x++) { tx3=0xFF; SPI3(); }; // "11111111"

PORTB.0=0; // SS microSD
/////////////////////////////////////////////////////////////////
//сброс microSD и перевод в режим SPI:
tx3=0x40; SPI3(); // 01xx xxxx + Номер команды - CMD0
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x95; SPI3(); // CRC7
// ответ R1: 0000 0001 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0001

//состояния интерфейса microSD (напряжение хоста и любой шаблон):
tx3=0x48; SPI3(); // 01xx xxxx + Номер команды - CMD8
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x01; SPI3(); // 0000 0001 -напряжение хоста 2.7 – 3.6 V
tx3=0xAA; SPI3(); // 1010 1010 -1010 1010 -проверочный шаблон
tx3=0x87; SPI3(); // CRC7
// ответ R7: 0000 0001; 0000 0000; 0000 0000; 0000 0001; 1010 1010
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); // STATUS R1 0000 0001
tx3=0xFF; SPI3(); // 0000 0000
tx3=0xFF; SPI3(); // 0000 0000
tx3=0xFF; SPI3(); // 0000 0001 -напряжение хоста 2.7 – 3.6 V
tx3=0xFF; SPI3(); x1 = rx3; // 1010 1010 -проверочный шаблон
/////////////////////////////////////////////////////////////////

while ( (x1 != 0x00) && (tm_microSD != 255) ) { // MOSI 0xFF > MOSI 0x00 // -цикл 2...21
//////////////////////////////// ждём ответ R1: 0000 0000 STATUS:
//старт microSD: // microSD версия v.2 и выше.
tx3=0x77; SPI3(); // 01xx xxxx + Номер команды - CMD55
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // CRC7
// ответ R1: 0000 0001 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0001

//
tx3=0x69; SPI3(); // 01xx xxxx + Номер команды - CMD41
tx3=0x40; SPI3(); // 0100 0000 - хост поддерживает карту памяти высокой емкости SD
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // CRC7
// ответ R1: 0000 0000 - инциализация microSD завершена.
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0000
/////////////////////////////////////////////////////////////////////
tm_microSD++; // таймаут microSD.
};
//////////////
if (tm_microSD == 255) { // таймаут microSD:
error_microSD_EEPROM |= 0b00000001; // 0000 0001 - error init microSD
};
tm_microSD = 0; // сброс таймаут tm_microSD.
///////////////////////////////////////////
PORTB.0=1; // SS microSD
//////////////////////////////////////////////////////////////////////////////////
// microSD - ток = 7 mA.
//////////////////////////////////////////////////////////////////////////////////////////////////////////


после этого флешка переключает интерфейс с SD на SPI... и переходит в рабочий режим.

теперь можно писать/читать данные на флешку.
:tea:

для записи на флешку используем функцию TX_microSD(x); // где unsigned long x - это адрес сектора флешки
для чтения с флешки используем функцию RX_microSD(x); // где unsigned long x - это адрес сектора флешки

чтение/запись я сделал через буфер... так удобней))

пример ? пожалуйста))

например нам надо записать данные на флешку...

1.
записываем данные сначала в буфер bufer_microSD[512]...
2.
затем вызываем функцию TX_microSD(x); // указываем адрес для записи (сектор для записи - x).
*Примечание.
Флешка разбита на сектора. Один сектор это 512 байт. Сектор надо читать/писать целиком. Поэтому буфер так же имеет размер 512 байт.

После этого все данные из буфера будут записаны на флешку))
:tea:

Или например надо прочитать данные на флешки...

1.
вызываем функцию RX_microSD(x); // указываем адрес для чтения (сектор для чтения - x).
*Примечание.
Флешка разбита на сектора. Один сектор это 512 байт. Сектор надо читать/писать целиком. Поэтому буфер так же имеет размер 512 байт.
2.
все считанные данные из флешки будут помещены в буфер bufer_microSD[512]...

*Примечание))
потребляемый ток:
-во время записи до 7 mA (microSD - ток = 7 mA).
-во время чтения ~0 mA (microSD - ток = 0 mA).
-во время простоя ~0 mA (microSD - ток = 0 mA).

вот так вот работает обычная флешка))
это кратко))
:tea:

Добавлено after 3 minutes 13 seconds:
фм приемник еще и экранчик )

никаких ФМ ! ))
WEB-радио рулит ! ))
WebRadio_schematic.GIF
(134.89 KiB) Скачиваний: 36

:tea:

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

Вт май 31, 2022 19:10:07

roman.com, Отличный мануал получился. А как влияет на это все тип файловой системы в которую отформатирована флэшка?

Добавлено after 3 minutes 30 seconds:
а, ну да, мы же читаем данные а не файлы...

Добавлено after 1 minute:
а как от данных перейти к файлам - это тоже кусок работы?

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

Вт май 31, 2022 19:20:38

удалил,ушел изучать даташит
Последний раз редактировалось Novice user Вт май 31, 2022 19:43:56, всего редактировалось 1 раз.
Ответить