Как ускорить Due ADC

Я делаю проект, в котором использую Arduino для измерения разницы во времени поступления сигналов на четыре пьезоэлектрических датчика. Пьезодатчики приклеены к плате, и мы хотим локализовать источник ударов по плате, исходя из TDOA вибрации на пьезоэлементах.

Изначально мы использовали прерывания для поднятия флагов после обнаружения сигналов (по сути, мы установили пороговое значение для пьезонапряжения, чтобы сказать, что мы «обнаружили» сигнал), но это кажется особенно чувствительным к шумам. когда вокруг слышен громкий шум (музыка, голоса в микрофонах и т. д.).

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

На данный момент моя цель — сделать производительность этого подхода сопоставимой с тем, в котором мы используем прерывания. На данный момент новый подход очень чувствителен к разнице в ответвлениях, что обеспечивает высокий уровень POE.

Насколько я понимаю, основное различие между этими двумя подходами заключается в том, что подход с прерыванием имеет разницу в микросекундах между отсчетами, в результате чего разница нажатий составляет примерно от 10 до 30 микросекунд. Однако при аналоговом подходе разница между каждой выборкой для каждого канала составляет 20 микросекунд, в результате чего разница в подсчете также составляет 20 секунд. Даже если разница в подсчете составит 20 нас.

Можно ли как-нибудь ускорить это время? Я знаю, что АЦП нужно время для преобразования и передачи данных в соответствующие регистры, но я просто пытаюсь найти способы сделать это быстрее. Я прочитал в таблице данных микроконтроллера Due, что он имеет 14 каналов АЦП плюс датчик температуры на 15-м. Может быть, это можно сделать, уменьшив количество каналов? Я не знаю как.

Есть ли способ ускорить преобразование АЦП Arduino Due?

, 👍1


4 ответа


2

Да, есть возможность настроить ADC на более быструю работу, так как он может обрабатывать 1Msps. Для четырех каналов ADC это означает 250ksps каждый (с разницей во времени между выборками 1us). Это невозможно с помощью оболочек Arduino, так как они слишком медленные и также ждут окончания преобразования. Вам нужно настроить его непосредственно в регистрах микроконтроллера, поэтому начните с спецификации SAM3X8.

Короче говоря: режим свободного хода, последовательные показания типа: 0 1 2 3, с прерыванием на 4-м образце, обработчиком прерываний и некоторой обработкой.

,

Спасибо @KIIV! Еще один вопрос, в режиме свободного выполнения, будут ли проблемы при чтении выходных регистров? Я имею в виду, поскольку АЦП свободно преобразует, а я все еще читаю канал 1 (я полагаю, что чтение через SPI или I2C медленнее, чем фактическое преобразование), но у АЦП есть новый набор данных, будут ли какие-либо коллизии данных или что-то еще?, @noobiejp

@noobiejp Вот почему я упомянул последовательные показания. Вы можете настроить его на прохождение входов АЦП в любом порядке. И показания сохраняются в соответствующих регистрах данных., @KIIV


0

разница между каждым образцом для каждого канала,

Это слишком медленно для любого микроконтроллера, выпущенного с 1980-х годов.

Посмотрите на техническое описание и сравните его с вашим кодом, чтобы увидеть, где вы можете увеличить скорость. Обычно для АЦП есть предделитель тактовой частоты, который вы можете изменить.

В общем, самым быстрым будет непрерывный АЦП в ДМА. Если нужно добавить несколько каналов, включите сканирование.

,

0

//Настройка АЦП PMC->PMC_WPMR &= ~(PMC_WPMR_WPEN); //Отключить режим защиты от записи PMC->PMC_PCER1 |= PMC_PCER1_PID37; //Включить периферийную тактовую частоту АЦП

PIOA->PIO_PDR |= PIO_PDR_P16; //Отключить контроллер PIO

ADC->ADC_WPMR &= ~(ADC_WPMR_WPEN); //Отключить режим защиты от записи ADC->ADC_CHER |= ADC_CHER_CH7; //Включить вывод A0 АЦП->ADC_MR = 0; //ADC->ADC_MR = ADC_MR_PRESCAL(2); //Частота АЦП установлена на 16 МГц ADC->ADC_MR = ADC_MR_PRESCAL(4); //Частота АЦП установлена на 8 МГц АЦП->АЦП_МР |= АЦП_МР_ТРЕКТИМ(3); АЦП->ADC_MR |= ADC_MR_STARTUP_SUT8; АЦП->ADC_EMR = 0;

//считывание выходного сигнала АЦП ADC->ADC_CR |= ADC_CR_START; //Программный триггер uint32_t adc_read = ADC->ADC_CDR[7];

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

,

0

Вы можете перевести АЦП в режим свободной работы, чтобы получать результаты так же быстро, как они могут быть прочитаны.

Для этого используйте adc_configure_trigger. р>

adc_configure_trigger(ADC, ADC_TRIG_SW, ADC_MR_FREERUN_ON);

Чтобы включить автономную работу на АЦП или настроить по мере необходимости. Больше нет необходимости устанавливать регистры.

Раньше с этой функцией была ошибка, если она вызывалась более одного раза, но теперь она исправлена. https://github.com/arduino/Arduino/issues/1819

,