slava68: (Default)
[personal profile] slava68
Всё хорошо в этой железяке, только вот иногда встречаются задачки, которые не имеют простого решения.

Нужно оцифровать сигнал с микрофона. На первый взгляд - гавновопрос !
Пишем val=analogRead(1);
Только вот, даже если процессор ничего больше не делает, скорость выполнения этой команды через стандартную библиотеку составляет каких-то 8кГц.

По теореме Котельникова "частота дискретизации должна минимум в два раза превышать частоту обрабатываемого сигнала", т.е. мы можем оцифровать максимум до 4кГц. Этого мало даже для речевого сигнала :-(
Если нам нужно сделать БПФ (быстрое преобразование Фурье) и получить спектр звукового сигнала, то необходимо минимум 44кГц частоты дискретизации.

Нарыл в интернете подобную проблемку. Умные люди придумали такую штуку:

#define FASTADC 1 // defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void setup() {
long int start ;
long int i ;

#if FASTADC // set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif

Serial.begin(9600) ;
Serial.print("ADCTEST: ") ;
start = millis() ;
for (i = 0 ; i < 61500 ; i++) analogRead(1) ;
Serial.print(millis() - start) ;
Serial.println(" msec (61500 calls)") ;
}
void loop() {
}
В результате получаем увеличения быстродействия примерно в 8 раз.

60кГц - это более чем достаточно, можно будет ещё и математикой заниматься в промежутках между чтением АЦП. Вот ссылочка на статейку про ускорение ввода-вывода на микроконтроллерах AVR: http://habrahabr.ru/post/141442/

только вот пока не могу разобраться, как это работает :-)))

Date: 2014-10-15 08:43 pm (UTC)
From: [identity profile] nepeanois.livejournal.com
стр.244 - как работает ADC.
если лень - стр.256 - зачем нужен ADSC и 257 - prescaler (делитель систем клока).
если и это лень - https://code.google.com/p/arduino/source/browse/trunk/hardware/arduino/cores/arduino/wiring_analog.c :
64. while (bit_is_set(ADCSRA, ADSC)); // чем быстрее клокаем ADC, тем быстрее нам отдают результат

Date: 2014-10-15 09:04 pm (UTC)
From: [identity profile] nepeanois.livejournal.com
слишкоммногобукф. однако в порядке флейма должен заметить, что для analIsing проверочное слово - analYsis. ;)

так это лаба по электронике или по c++?

Date: 2014-10-15 10:20 pm (UTC)
From: [identity profile] slava68.livejournal.com
"Цифровая обработка сигналов "

:-)))

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

Другая дисциплина у меня - "Схемотехническое проектирование ЭС" , там тоже пытаюсь те же лабораторки придумать, только задачи другие.

Есть у меня ещё "Конструирование ЭС на базе БИС" их тоже постепенно подвожу к тому, чтобы мне было полегче заниматься с ними всеми.

А "Информационные технологии" и "Информатика" у вечерников - там С++

Date: 2014-10-15 11:21 pm (UTC)
From: [identity profile] nepeanois.livejournal.com
ахвонашто! тогда предлагаю добавить в код настройку частоты дискретизации (вот те три битика делителя выставлять по-разному) и смотреть ухудшение/улучшение качества оцифровки, а еще можно - восстановленние сигнала из ранее записанного (плеер).

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

про c++ спросил из-за названия копипасты

Date: 2014-10-16 06:34 am (UTC)
From: [identity profile] slava68.livejournal.com
"а еще можно - восстановленние сигнала из ранее записанного (плеер)."

Да, это будет обязательно. И работу по прерываниям тоже планирую.
Работа большая получается, будем по частям делать.
From: [identity profile] slava68.livejournal.com
Вот, что я пропустил :-)))

стр.247 , получается, что пострадает качество преобразования.

By default, the successive approximation circuitry requires an input clock frequency between
50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the
input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.
The ADC module contains a prescaler, which generates an acceptable ADC clock frequency
from any CPU frequency above 100kHz. The prescaling is set by the ADPS bits in ADCSRA.
The prescaler starts counting from the moment the ADC is switched on by setting the ADEN bit
in ADCSRA. The prescaler keeps running for as long as the ADEN bit is set, and is continuously
reset when ADEN is low.
When initiating a single ended conversion by setting the ADSC bit in ADCSRA, the conversion
starts at the following rising edge of the ADC clock cycle.
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched
on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
When the bandgap reference voltage is used as input to the ADC, it will take a certain time for
the voltage to stabilize. If not stabilized, the first value read after the first conversion may be
wrong.
Edited Date: 2014-10-15 11:13 pm (UTC)
From: [identity profile] nepeanois.livejournal.com
да-да, есть и такая засада. только там они неспроста на 16 делят в вашем варианте, наверное это как раз тот предел, после которого отваливаются младшие биты

Profile

slava68: (Default)
slava68

February 2026

S M T W T F S
1234567
891011121314
15161718192021
22232425262728

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 14th, 2026 04:09 am
Powered by Dreamwidth Studios