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

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

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

Сообщение olegue »

да
задумка была не загружать МК вторым преобразованием
Реклама
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

olegue писал(а):задумка была не загружать МК вторым преобразованием
ну и не запускай каждое прерывание второй преобразование...
запускай 1 раз из 1000 )) остальное время потрать на другое...

лучше закинь всё протеус и посмотри как всё работает...
ILI9341-ардуино.jpg
(145.77 КБ) 43 скачивания
сколько времени занимает одно преобразование ADC мы выяснили))

сколько времени занимает обработка данных и запись в буфер ADC мы выяснили выше))
ADC_bufer.jpg
(92.71 КБ) 41 скачивание
сколько времени занимает запись буфера на флешку в моём случае... мы выяснили выше))
ADC_SPI_поток.jpg
(108.16 КБ) 49 скачиваний
почему надо два буфера а не один... тоже выяснили выше))
SPI_0.jpg
(94.14 КБ) 42 скачивания
и т.д.

осталось всё собрать в единую картину))

как работают мои схемы... по времени... я знаю.
тайминги.jpg
(150.85 КБ) 52 скачивания
как работает твои библиотеки... по времени... я НЕ знаю.
:tea:
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

roman.com писал(а):и отдать такты фильтру...
Если усреднение не справится, то фильтр тем более.
У тебя АЦП работает на запредельных частотах, фильтр подрежет динамический диапазон сигнала, сверху и снизу. Можешь зарезать по самое самое и чисто середину оставить. В путь.
Martian писал(а):Однако, мне не верится, что этот мк не способен справиться.
Ну по чему не способен, 500кГц это еще не 1МГц, в тестах 1МГц выжимали на два канала.

Осталось мой код на реальном устройстве проверить. Но и поиграться с оптимизацией кода, в основном в прерывании.

roman.com, ты бы хоть синхронизировал таймер с АЦП, а то, while (bit_is_set(ADCSRA, ADSC)), ждешь седьмого пришествия.
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

Dimon456 писал(а):Если усреднение не справится, то фильтр тем более.
фильтр справится.

обязательно всё синхронизируем когда выкинем ардуину и будем писать по нормальному))
среду разработки ардуины я удалил... я этим больше не пользуюсь.
у меня есть всё... кроме ардуины))
Реклама
Эиком - электронные компоненты и радиодетали
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

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

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

Сообщение olegue »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4246226#p4246226"]Осталось мой код на реальном устройстве проверить. Но и поиграться с оптимизацией кода, в основном в прерывании.

roman.com, ты бы хоть синхронизировал таймер с АЦП, а то, while (bit_is_set(ADCSRA, ADSC)), ждешь седьмого пришествия.[/uquote]

вАш код:
Спойлер

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

volatile uint8_t sum_adc;
volatile bool n0=0, n1=0;
byte buf00[256]; // buffer array 1
byte buf01[256]; // buffer array 2

// ADC interrupt service routine
ISR(ADC_vect)
{
static uint8_t count = 0;
static uint8_t temp=0;
static uint32_t temp_adc=0;
static uint16_t count_buf = 0;

  if(ADMUX & (1<<MUX0)){
    temp = ADCH;   
    if(count_buf < 256) {
    buf00[count_buf] = temp;
    } else buf01[count_buf - 256] = temp;

    if(count_buf == 255) {
      n0=0; n1=1;
    }
     
    if(++count_buf > 511) {
      count_buf=0; n0=1; n1=0;
    }
    ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0
  }else{
    temp_adc += ADCH;

  if (++count > ((127)))  {
    count = 0;
    sum_adc = temp_adc>>7;
    temp_adc=0;
  }

    ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
  }

}


void loop() {
   if (n0==0 && n1 == 1) {
      rec.write(buf00, 256);  // save buf01 to card
      n0=0; n1=0;
    }
    if (n0==1 && n1 == 0) {
      rec.write(buf01, 256);  // save buf02 to card
      n0=0; n1=0;
    }
}

void StartRec() { // begin recording process

  digitalWrite(ledStart, HIGH);
  digitalWrite(ledStop, LOW);
  recByteCount = 0;
  recByteSaved = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  ADCSRA |= (1<<ADEN);
}

void StopRec() { // stop recording process, update WAV header, close file
  ADCSRA &= ~(1<<ADEN);
  writeOutHeader();
  digitalWrite(ledStart, LOW); // turn off recording LED
  digitalWrite(ledStop, HIGH); // light stop LED
  recPressed = 0;
}

void Setup_ADC() {
// ADC initialization
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);  // 500kHz
sampleRate = 19600; bytesPerSec = 19600;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // 250kHz
//sampleRate = 9800; bytesPerSec = 9800;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // 125kHz
//sampleRate = 4900; bytesPerSec = 4900;

ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}

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

Добавлено after 13 minutes 3 seconds:
ошибки:
Спойлер
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void __vector_21()':
DIMON456_AUDIORECORDER:27:13: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0
^~~~~~~~~~~~~
DIMON456_AUDIORECORDER:37:13: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
^~~~~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void loop()':
DIMON456_AUDIORECORDER:45:7: error: 'rec' was not declared in this scope
rec.write(buf00, 256); // save buf01 to card
^~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:45:7: note: suggested alternative: 'getc'
rec.write(buf00, 256); // save buf01 to card
^~~
getc
DIMON456_AUDIORECORDER:49:7: error: 'rec' was not declared in this scope
rec.write(buf01, 256); // save buf02 to card
^~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:49:7: note: suggested alternative: 'getc'
rec.write(buf01, 256); // save buf02 to card
^~~
getc
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void StartRec()':
DIMON456_AUDIORECORDER:56:16: error: 'ledStart' was not declared in this scope
digitalWrite(ledStart, HIGH);
^~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:56:16: note: suggested alternative: 'va_start'
digitalWrite(ledStart, HIGH);
^~~~~~~~
va_start
DIMON456_AUDIORECORDER:57:16: error: 'ledStop' was not declared in this scope
digitalWrite(ledStop, LOW);
^~~~~~~
DIMON456_AUDIORECORDER:58:3: error: 'recByteCount' was not declared in this scope
recByteCount = 0;
^~~~~~~~~~~~
DIMON456_AUDIORECORDER:59:3: error: 'recByteSaved' was not declared in this scope
recByteSaved = 0;
^~~~~~~~~~~~
DIMON456_AUDIORECORDER:60:3: error: 'recPressed' was not declared in this scope
recPressed = 1; // recording button has been pressed
^~~~~~~~~~
DIMON456_AUDIORECORDER:61:3: error: 'stopPressed' was not declared in this scope
stopPressed = 0;
^~~~~~~~~~~
DIMON456_AUDIORECORDER:62:3: error: 'writeWavHeader' was not declared in this scope
writeWavHeader();
^~~~~~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void StopRec()':
DIMON456_AUDIORECORDER:68:3: error: 'writeOutHeader' was not declared in this scope
writeOutHeader();
^~~~~~~~~~~~~~
DIMON456_AUDIORECORDER:69:16: error: 'ledStart' was not declared in this scope
digitalWrite(ledStart, LOW); // turn off recording LED
^~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino:69:16: note: suggested alternative: 'va_start'
digitalWrite(ledStart, LOW); // turn off recording LED
^~~~~~~~
va_start
DIMON456_AUDIORECORDER:70:16: error: 'ledStop' was not declared in this scope
digitalWrite(ledStop, HIGH); // light stop LED
^~~~~~~
DIMON456_AUDIORECORDER:71:3: error: 'recPressed' was not declared in this scope
recPressed = 0;
^~~~~~~~~~
C:\Users\lula\Documents\Arduino\DIMON456_AUDIORECORDER\DIMON456_AUDIORECORDER.ino: In function 'void Setup_ADC()':
DIMON456_AUDIORECORDER:77:20: error: 'ADC_VREF_TYPE' was not declared in this scope
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
^~~~~~~~~~~~~
DIMON456_AUDIORECORDER:79:1: error: 'sampleRate' was not declared in this scope
sampleRate = 19600; bytesPerSec = 19600;
^~~~~~~~~~
DIMON456_AUDIORECORDER:79:21: error: 'bytesPerSec' was not declared in this scope
sampleRate = 19600; bytesPerSec = 19600;
^~~~~~~~~~~
exit status 1
'ADC_VREF_TYPE' was not declared in this scope
Добавлено after 3 minutes 1 second:
Тут если на то пошло, надо определить какие процедуры заменить в моем коде и какие переменные исключить/добавить.
Реклама
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

[uquote="olegue",url="/forum/viewtopic.php?p=4246306#p4246306"]я бы его проверил,но так как он мне не совсем понятен[/uquote]
тут даже мне не понятен... а ардуине и подавно))
:))
начиная на ещё стадии инициализации ADC...

void Setup_ADC() {
// ADC initialization
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0); // 500kHz
sampleRate = 19600; bytesPerSec = 19600;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // 250kHz
//sampleRate = 9800; bytesPerSec = 9800;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // 125kHz
//sampleRate = 4900; bytesPerSec = 4900;

ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}

во первых есть стандартные настройки sampleRate = 8000,11025,16000,22050,44100
нафига делать не стандартные... не ясно)) наверное чтобы невозможно было послушать на обычном плеере))
:tea:
во вторых зачем вот это
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
почему не записать просто
ADCSRA=0x6D;
:tea:
в третьих... нафига писать регистры которые и так сброшены в 0
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
в четвёртых... этот код будет работать только на ардуине c AVR типа ATmega328
а если я захочу этот код запустить на ардуине c AVR типа ATmega8 то нифига работать не будет)) потому что в ардуине c AVR типа ATmega8 нет регистров DIDR0 и ADCSRB... ))
:tea:
в пятых... это для AVR типа ATmega328
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
а для ATmega8 надо писать так
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
а почему тогда прост оне записать так
ADCSRA=0x6D;
и для AVR типа ATmega328 и для AVR типа ATmega8
:tea:
в шестых...
давайте проверим это в простом компиляторе AVR...
ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
компилятор ответил - ОШИБКА !
ошибка_компилятор_AVR.jpg
(83.32 КБ) 50 скачиваний
мой компилятор не знает что такое ADEN, ADSC, ADFR, ADIF, ADIE, ADPS2, ADPS1, ADPS0... и т.д.))

а теперь давайте запишем по нормальному))
ADCSRA=0x6D;
компилятор_OK.jpg
(110.09 КБ) 38 скачиваний
компилятор ответил - OK
:tea:
вывод:
надо писать так
ADCSRA=0x6D;
или так
ADCSRA=0b01101101;
тогда будет всё работать хорошо)) и любая ардуина (на ATmega328 и на ATmega8) и любой компилятор ))
оно и понятно... эта простая логическая операция записи значения 0x6D в регистр ADCSRA понятна всем))
:tea:
в седьмых...
в восьмых...
:))
блин... мы ещё даже не начали разбирать код... а у нас уже куча ошибок повыскакивало...
что же будет дальше... страшно представить))
:)
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

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

Сообщение olegue »

Немного вьехал в эту тему и понял, что вот МК один а люди понимают его по разному.

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

Но кроме этого, я еще одну фишку хочу добавить в этот проект.

У меня есть 4х битный сигнал, я хочу подать его на свободные пины Ардуины(ну считай Атмеги) и преобразовать его в десятичное число
4х битный сигнал - 4 пина будут взяты с hc595 c пинов 15,1,2,3. Дело осложняется еще и тем, что 595 запитана от 3.3 в, а Ардуина запитана от 5в.
Я полагаю , что уровнь "еденица" с 595 идет высокий. Какая помощь мне нужна?
1. Настройка пинов
2. Формула преобразования в bcd to decimal

Буду весьма признателен за участие всех кто мне здеьс помогает.

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

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

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

если источник имеет меньшее напряжение, а приемник большее - входы приемника ставь в z состояние и соединяй напрямую (если страшно - добавь в разрыв резисторы 300-500 Ом).

бсд 4 бита соответствует хексу - преобразовывать ничего не надо.
бсд 8 бит в хекс: у=х&0х0f+(x>>4)*10;
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

4х битный сигнал напряжением 3.3 от hc595 подключаются НАПРЯМУЮ к Атмеги (ну считай Ардуины).
для этого никакие резисторы не нужны))

Настройка пинов - пины Атмеги (ну считай Ардуины) должны настроены на вход.

Формула преобразования в bcd to decimal ?

у=х&0х0f+(x>>4)*10;

боюсь что эта формула работать не будет))
хотя тут всё зависит от компилятора... что он первым будет делать... х&0х0f или (x>>4)*10
))
но жаде если компилятор всё сделает правильно... то все равно работаь не будет ))
Последний раз редактировалось roman.com Чт июн 16, 2022 17:07:24, всего редактировалось 1 раз.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

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

Сообщение olegue »

Ivanoff-iv, пины ардуино по умалчанию настроены на вход. Получается это и будет z-состояние?

Потому что если
если я едлаю pinmode(6,HIGH) ИЛИ PINMODE(6,LOW), то я просто выходит пина по умолчанию на строенный на входа притягиваю к плюсу или к земле.

Если так идием дальше, нужно теперь считаь значение пинов


valA= DigitalRead(6);
valB=DigitalRead(7);
valC=DigitalRead(8);
valD=DigitalRead(9);


а дальше что делать?

Добавлено after 5 minutes 29 seconds:
а , ну да, удобнее же взять пины одноо регистра

например PD0,pd1,pd2,pd3 и подать на них, а как из "взять"? Эти биты?

Добавлено after 2 minutes 10 seconds:
Надо глянуть чтение регистров Атмеги...
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

[uquote="olegue",url="/forum/viewtopic.php?p=4246405#p4246405"]если я едлаю pinmode(6,HIGH) ИЛИ PINMODE(6,LOW), то я просто выходит пина по умолчанию на строенный на входа притягиваю к плюсу или к земле.[/uquote]
это слишком сложный вопрос... для простых смертных))
[uquote="olegue",url="/forum/viewtopic.php?p=4246405#p4246405"]а как из "взять"? Эти биты?[/uquote]
простые смертные делают так

x = PINC; // в переменной х содержатся значения пинов 0,1,2,3,4,5,6,7 потр С

а можно и по отдельности ))

x0 = PINC.0; // в переменной х0 содержится значения пина 0 потр С
x1 = PINC.1; // в переменной х1 содержится значения пина 1 потр С
x2 = PINC.2; // в переменной х2 содержится значения пина 2 потр С
x3 = PINC.3; // в переменной х3 содержится значения пина 3 потр С
x4 = PINC.4; // в переменной х4 содержится значения пина 4 потр С
x5 = PINC.5; // в переменной х5 содержится значения пина 5 потр С
x6 = PINC.6; // в переменной х6 содержится значения пина 6 потр С
x7 = PINC.7; // в переменной х7 содержится значения пина 7 потр С

а можно и по другому))
[uquote="olegue",url="/forum/viewtopic.php?p=4246405#p4246405"]а дальше что делать?[/uquote]
преобразования HEX в DEC... ? я пересчитываю через счётчик... ))
Последний раз редактировалось roman.com Чт июн 16, 2022 18:03:15, всего редактировалось 2 раза.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

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

Сообщение olegue »

нагуглив вот это
https://www.geeksforgeeks.org/program-t ... al-number/
Спойлер

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

// C++ code to convert BCD to its
// decimal number(base 10).
 
// Including Header Files
#include <bits/stdc++.h>
using namespace std;
 
// Function to convert BCD to Decimal
int bcdToDecimal(string s)
{
    int len = s.length(),
        check = 0, check0 = 0;
    int num = 0, sum = 0,
        mul = 1, rev = 0;
 
    // Iterating through the bits backwards
    for (int i = len - 1; i >= 0; i--) {
 
        // Forming the equivalent
        // digit(0 to 9)
        // from the group of 4.
        sum += (s[i] - '0') * mul;
        mul *= 2;
        check++;
 
        // Reinitialize all variables
        // and compute the number.
        if (check == 4 || i == 0) {
            if (sum == 0 && check0 == 0) {
                num = 1;
                check0 = 1;
            }
            else {
                // update the answer
                num = num * 10 + sum;
            }
 
            check = 0;
            sum = 0;
            mul = 1;
        }
    }
 
    // Reverse the number formed.
    while (num > 0) {
        rev = rev * 10 + (num % 10);
        num /= 10;
    }
 
    if (check0 == 1)
        return rev - 1;
 
    return rev;
}
 
// Driver Code
int main()
{
    string s = "100000101000";
 
    // Function Call
    cout << bcdToDecimal(s);
 
    return 0;
}
но тут в строку надо преобразовать 4 бита

А мне бы надо функцию с 4мя параметрами

Добавлено after 6 minutes 43 seconds:
уже чуть ближе
https://math.stackexchange.com/question ... mal-number

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

x = [0 0 0 1];
n = length(x);
y = 0;
for i = 1:n
    if x(i)
        y = y + 2^(n-i);
    end
end
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

[uquote="olegue",url="/forum/viewtopic.php?p=4246430#p4246430"]нагуглив вот это[/uquote]
щас подумаем... ))

а что у нас со звуком ? когда будем подключать AVR (читай Ардуина) к Интернету ?))

для интереса посмотрел как работает наш самодельный диктофон на ПК...
sampleRate = 8000
sampleSizeInBits = 8
8000.jpg
(246.09 КБ) 38 скачиваний
видим непрерывный поток... по сети Интернет... в реальном времени ))
50 Гц - это помехи от микрофона... плохо экранирован... и без заземления))
слышим сигнал помехи от микрофона частотой 50 герц в динамике...

olegue ты тоже можешь себе сделать такой типа "монитор"... будешь смотреть как твои байты записываются на флешку... в реальном времени ))

всё работает)) но без шифрования))
:tea:
включаем кнопочку "зашифровать" поток...
8000_AES.jpg
(255.88 КБ) 49 скачиваний
видим непрерывный поток... по сети Интернет... в реальном времени... в зашифрованном виде ))
тот же самый сигнал частотой 50 герц в динамике слышен как просто громкий шум... просто белый шум))

замечательно)) теперь никто нас не подслушает))
8)

теперь надо подключить к сети Интернет... ATmega8 или ATmega328...

тут есть одна проблема... ATmega8 или ATmega328... шифруют слишком медленно...
ATmega8_AES.jpg
(146.06 КБ) 42 скачивания
Ардуина 16 мгц будет шифровать поток со скоростью ~2000 байт в секунду...
а нам надо шифровать поток со скоростью ~8000 байт в секунду...
:roll:
этот вариант нам не подходит...

можно попробовать поменять протокол шифрования... например вместо AES128 использовать старый ГОСТ 28147-89...
GOST_vs_AES.jpg
(94.7 КБ) 42 скачивания
неее... этот вариант нам тоже не подходит... старый ГОСТ 28147-89 работает ещё медленней...

для шифрования потока нужен более мощный процессор... типа ESP32 )) с частотой процессора 160/240 мгц )) тогда будет нормально.
точно))
сделаем радио диктофон по Wi-Fi на ESP32 )) с записью на ПК...
или радио микрофон по Wi-Fi на ESP32 ))
:)
короче... будем петь в караоке ))
:music:
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

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

Сообщение olegue »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4246397#p4246397"]бсд 4 бита соответствует хексу - преобразовывать ничего не надо.[/uquote]

но для этого нужно получить именно это 4 бита из регистра в котором 8 бит. Как это сделать?
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

[uquote="olegue",url="/forum/viewtopic.php?p=4246441#p4246441"][uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4246397#p4246397"]бсд 4 бита соответствует хексу - преобразовывать ничего не надо.[/uquote]

но для этого нужно получить именно это 4 бита из регистра в котором 8 бит. Как это сделать?[/uquote]
эти ?

valA= DigitalRead(6);
valB=DigitalRead(7);
valC=DigitalRead(8);
valD=DigitalRead(9);

что это ? в регистре всего 8 бит... 0,1,2,3,4,5,6,7
откуда взялось эти 8 и 9 ?
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

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

Сообщение olegue »

по сути ,е сли без заморочек и сдвиговых финтов то вот это

Изображение

Добавлено after 2 minutes 52 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=4246447#p4246447"]valA= DigitalRead(6);
valB=DigitalRead(7);
valC=DigitalRead(8);
valD=DigitalRead(9);

что это ? в регистре всего 8 бит... 0,1,2,3,4,5,6,7
откуда взялось эти 8 и 9 ?[/uquote]


это пины в которх лежат эти биты
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

olegue писал(а):ошибки:
Вот полностью код
Спойлер

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

// Arduino Audio Recorder


#include <SdFat.h> // https://yadi.sk/d/zqi8-L5xruhFq
#include <EEPROM.h>

#include <RTClib.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

SdFat sd;
SdFile rec;
RTC_DS1307 rtc;

#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (1<<ADLAR))

volatile uint8_t sum_adc;

volatile bool n0=0, n1=0;

const int chipSelect = 4; /* Поменял на 10-pln */
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;
unsigned long sampleRate = 22050;
unsigned long bytesPerSec = 22050;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
const int btnStart = 6;
const int btnStop = 5;
const int ledStart = 2;
const int ledStop = 3;
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[256]; // buffer array 1
byte buf01[256]; // buffer array 2
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;

unsigned long timer1;
int timer1on = 0;
//----------
//char NameRecord[4]; /* Имя нового - записываемого файла на SD-карту. */
int RecordNumber; /* Номер записи - храним в EEPROM. в диапазоне 0..255. */
char filename[12];

void setup() { // THIS RUNS ONCE
  rtc.begin();
//EEPROM.put(0, 20000);
  Setup_timer2();
  Setup_ADC();

  pinMode(10, OUTPUT);
  pinMode(ledStart, OUTPUT);
  pinMode(ledStop, OUTPUT);
  pinMode(btnStop, INPUT_PULLUP);
  pinMode(btnStart, INPUT_PULLUP);

  if (sd.begin(chipSelect, SPI_FULL_SPEED)) { // initialise card on SPI to 8MHz SPI bus speed
    for (int dloop = 0; dloop < 4; dloop++) {
      digitalWrite(ledStart, !digitalRead(ledStart));
      delay(100);
    }
  } else { // if error, flash LED twice per second, until reset
    while (1) {
      digitalWrite(ledStart, !digitalRead(ledStart));
      delay(500);
    }
  }

}

void loop() { // THIS RUNS LOTS!

 if (digitalRead(btnStart) == LOW && recPressed == 0) {
    /* Записываем в RecordNumber, значение из ячейки №0 EEPROM, и прибавляем 1. */
    /*RecordNumber = EEPROM.read(0) + 1;*/
     if (RecordNumber == 32767)RecordNumber = 0;
/*RecordNumber==RecordNumber+1;*/
       EEPROM.get(0,RecordNumber) ;
       /* Записываем в ячейку №0 EEPROM, увеличенное значение RecordNumber. */
    /*EEPROM.write(0, RecordNumber);*/
    EEPROM.put(0, RecordNumber+1);
   String str;  //declaring string.
    //
   str = String(RecordNumber); //converting integer into a string.
   while (str.length() < 6)
    {
    str = "0" + str;
      }
   str.concat(".wav");
   str.toCharArray(filename, sizeof(filename));
    /*str.toCharArray(NameRecord, 4); //passing the value of the string to the character array.*/
    /*SdFile::dateTimeCallback(dateTime);*/
    StartRec(); // launch StartRec method
    timer1on = 0;
  }
  else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 0)
    {
      timer1 = millis();
      timer1on = 1;
    }
    else if (digitalRead(btnStart) == LOW && recPressed == 1 && timer1on == 1) {
    timer1on = 0;
    }
   
  else if (digitalRead(btnStart) == HIGH && recPressed == 1 && timer1on == 1 && (millis() - timer1) > 2000)
  {
    StopRec(); // launch StopRec method
   
    /*         Поэтому (Делаем программную перезагрузку). */
    ((void (*)())0x0000)(); /* Делаем программную перезагрузку - Arduino */
  }
 
  //if (recByteCount % 512 == 256 && recPressed == 1) {
  //  rec.write(buf00, 256);  // save buf01 to card
  //  recByteSaved += 256;
  //}
  //if (recByteCount % 512 == 0 && recPressed == 1) {
  //  rec.write(buf01, 256);  // save buf02 to card
  //  recByteSaved += 256;
  //}

   if (n0==0 && n1 == 1) {
      rec.write(buf00, 256);  // save buf01 to card
      recByteSaved += 256;
      n0=0; n1=0;
    }
    if (n0==1 && n1 == 0) {
      rec.write(buf01, 256);  // save buf02 to card
      recByteSaved += 256;
      n0=0; n1=0;
    }
}

void StartRec() { // begin recording process

  digitalWrite(ledStart, HIGH);
  digitalWrite(ledStop, LOW);
  recByteCount = 0;
  recByteSaved = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  //sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio

  ADCSRA |= (1<<ADEN);
}

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;

    //cbi (TIMSK2, OCIE2A); // disable timer interrupt
  ADCSRA &= ~(1<<ADEN);
  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();

}

void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = rtc.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

void writeWavHeader() { // write out original WAV header to file

  recByteSaved = 0;
  // rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);
  /*rec.open(NameRecord, O_CREAT | O_TRUNC | O_RDWR); /* Имя нового - записываемого файла на SD-карту. */
  //DateTime now = rtc.now();
   SdFile::dateTimeCallback(dateTime);
   rec.open(filename, O_CREAT | O_TRUNC | O_RDWR); /* Имя нового - записываемого файла на SD-карту. */
   //rec.timestamp(T_CREATE, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
  rec.write("RIFF");
  byte1 = fileSize & 0xff;
  byte2 = (fileSize >> 8) & 0xff;
  byte3 = (fileSize >> 16) & 0xff;
  byte4 = (fileSize >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.write("WAVE");
  rec.write("fmt ");
  byte1 = waveChunk & 0xff;
  byte2 = (waveChunk >> 8) & 0xff;
  byte3 = (waveChunk >> 16) & 0xff;
  byte4 = (waveChunk >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = waveType & 0xff;
  byte2 = (waveType >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = numChannels & 0xff;
  byte2 = (numChannels >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = sampleRate & 0xff;
  byte2 = (sampleRate >> 8) & 0xff;
  byte3 = (sampleRate >> 16) & 0xff;
  byte4 = (sampleRate >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = bytesPerSec & 0xff;
  byte2 = (bytesPerSec >> 8) & 0xff;
  byte3 = (bytesPerSec >> 16) & 0xff;
  byte4 = (bytesPerSec >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = blockAlign & 0xff;
  byte2 = (blockAlign >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = bitsPerSample & 0xff;
  byte2 = (bitsPerSample >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  rec.write("data");
  byte1 = dataSize & 0xff;
  byte2 = (dataSize >> 8) & 0xff;
  byte3 = (dataSize >> 16) & 0xff;
  byte4 = (dataSize >> 24) & 0xff;
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);

}

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() {

//  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);

// ADC initialization
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= (1<<MUX0) | ADC_VREF_TYPE;

ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);  // 500kHz
//sampleRate = 20000; bytesPerSec = 20000;
sampleRate = 19600; bytesPerSec = 19600;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // 250kHz
//sampleRate = 9800; bytesPerSec = 9800;
//sampleRate = 19230; bytesPerSec = 19230;
//ADCSRA=(0<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // 125kHz
//sampleRate = 4807; bytesPerSec = 4807;

ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
}

// ADC interrupt service routine
ISR(ADC_vect) 
{
static uint8_t count = 0;
static uint8_t temp=0;
static uint32_t temp_adc=0;
static uint16_t count_buf = 0;

  if(ADMUX & (1<<MUX0)){
    temp = ADCH;
    ADMUX = ADC_VREF_TYPE | (0<<MUX0);//set ch 0     
    if(count_buf < 256) {
    buf00[count_buf] = temp; 
    } else buf01[count_buf - 256] = temp;

    if(count_buf == 255) { 
      n0=0; n1=1; 
    }
      
    if(++count_buf > 511) { 
      count_buf=0; n0=1; n1=0; 
    }
  }else{
    temp_adc += ADCH;
    ADMUX = ADC_VREF_TYPE | (1<<MUX0);//set ch 1
    if (++count > ((127)))  { 
    count = 0;
    sum_adc = temp_adc>>7; 
    temp_adc=0;
  }
  }


}

ISR(TIMER2_COMPA_vect) {

  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 == 256 && bufWrite == 0) {
    bufByteCount = 0;
    bufWrite = 1;
  } else if (bufByteCount == 256 & bufWrite == 1) {
    bufByteCount = 0;
    bufWrite = 0;
  }

  if (bufWrite == 0) {
    buf00[bufByteCount] = ADCH;
  }
  if (bufWrite == 1) {
    buf01[bufByteCount] = ADCH;
  }

}
В ардуино иде собирается без проблем.
Последний раз редактировалось Dimon456 Чт июн 16, 2022 19:13:12, всего редактировалось 1 раз.
roman.com
Друг Кота
Сообщения: 9174
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

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

[uquote="olegue",url="/forum/viewtopic.php?p=4246448#p4246448"]это пины в которх лежат эти биты[/uquote]
берём переменную х и записываем в неё данные из пинов 0,1,2,3 потр С

if (PINC.0 == 1) {x |= 0b00000001;};
if (PINC.0 == 0) {x &= 0b11111110;};
if (PINC.1 == 1) {x |= 0b00000010;};
if (PINC.1 == 0) {x &= 0b11111101;};
if (PINC.2 == 1) {x |= 0b00000100;};
if (PINC.2 == 0) {x &= 0b11111011;};
if (PINC.3 == 1) {x |= 0b00001000;};
if (PINC.3 == 0) {x &= 0b11110111;};

в переменной х содержатся значения пинов 0,1,2,3 потр С

Добавлено after 20 minutes 42 seconds:
Dimon456 писал(а):Вот полностью код
на этой ардуине работать не будет
ардуино.jpg
(69.17 КБ) 42 скачивания
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

roman.com писал(а):на этой ардуине работать не будет
если в 1 килобайт твой код укладывается, тогда давай, выкладывай.
Надо еще места на плюшки там оставить, на загрузчик и т.п.
roman.com писал(а):берём переменную х и записываем в неё данные из пинов 0,1,2,3 потр С
Спойлерif (PINC.0 == 1) {x |= 0b00000001;};
if (PINC.0 == 0) {x &= 0b11111110;};
if (PINC.1 == 1) {x |= 0b00000010;};
if (PINC.1 == 0) {x &= 0b11111101;};
if (PINC.2 == 1) {x |= 0b00000100;};
if (PINC.2 == 0) {x &= 0b11111011;};
if (PINC.3 == 1) {x |= 0b00001000;};
if (PINC.3 == 0) {x &= 0b11110111;};

в переменной х содержатся значения пинов 0,1,2,3 потр С
:facepalm: :kill:

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

	x = ((PINC&(1<<0))?(1<<0):0) 		\
			| ((PINC&(1<<1))?(1<<1):0) 	\
			| ((PINC&(1<<2))?(1<<2):0) 	\
			| ((PINC&(1<<3))?(1<<3):0);
Ответить

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