Ускорение считывания с нескольких аналоговых входов Arduino MEGA

medic
Offline
Зарегистрирован: 06.02.2016

У меня постоянно считываются значения с четырех аналоговых входов Arduino MEGA 2560.

Реализовано в цикле.

analogRead(A1);

analogRead(A2);

analogRead(A3);

analogRead(A4);

Причем точность в интервале 0 - 1023 мне не нужна. Мне нужен интервал 0 - 100.

Получается пустая трата процессорного времени. Сначала получаем высокую точность (0 - 1023), а затем приводим к (0 - 100).

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

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Запостили ссылки на какой-то дилетанский бред .. там измеряется не скорость чтения, а скорость преобразования во float по большей части.

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

Да, если из второй ссылки уберете тип float получится шустрее. Киберлиб - вполне грамотная либа.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

вопрос задал дилетант, а вы его с апломбом тыкаете в даташит - мол, разбирайся сам. Негуманно ;)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

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

Потоковая работа с прерываниями есть у меня в arhat.h, но я его не тестировал на ненадобностью .. так что он там под комментом. Поэтому и отправляю в даташит. В целом, ADC на потоке способен оцифровывать за 13 периодов частоты преобразования, которую рекомендуется не устанавливать выше 250кГц. Вот и вся скорость. Нет там ничего сложного в даташите по ADC .. Атмел постарался, чтобы было все просто.

mag155
Offline
Зарегистрирован: 21.12.2017

Здраствуйте Arhat109-2. Писал вам ранее по библиотеке киберлаб и ее работе с ардуино мега. Не хочет компелировать когда задействую аналоговые входа. Смотрел саму библиотеку там для меги всего 5 аналоговых входов указано думаю проблема в этом. Подскажите как дополнить очень надо ? Пытался описать остальные входы результата ноль. Полностью удалил библиотеку из папки библиотека. Не каких изменений?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вы можете отдельно использовать analogReference() для установки порога функции analogRead(), а также после вызова ручками изменить частоту чтения, подняв её до 1Мгц. Функция analogRead() вроде как теперь больше не устанавливает частоту чтения самостоятельно. Примерно так:

void setup()
{
    // .. блок настройки analogRead():
    analogReference(/* что требуется */);
    ADCSRA |= (/* доустановить делитель на 1Мгц: 1/16 для Мега 2560 */)
    analogRead(); // первое чтение, результат не нужен..
}

Конкретные значения уже не помню, посмотрите в даташите .. делитель, кажется надо ставить 4 для частоты в 1Мгц АЦП. Меньшее значение (быстрее) задавать - бессмысленно. Мультиплексор входов не переключается выше 1Мгц, а если у вас ещё и диф. замеры, то предел - 0.5Мгц. С одного входа можно снимать до 592 килозамера в секунду с разрешением около 6 бит.

Нормально разведенная плата на 1Мгц выдает 9-10бит практически стабильно.

Сама функция analogRead() в 1.8.5 вроде бы не содержит уже ничего особо лишнего. Можете посмотреть на её реализацию в Wiring и слегка ускорить, запуская старт нового замера ПЕРЕД чтением значений предыдущего и тщятельно успевая сделать что требуется до его завершения... Но это надо делать очень аккуратно, иначе "запутаетесь". Именно так и получал свои 592 килозамера с одного входа. :)

В теме http://arduino.ru/forum/proekty/samodelnaya-mega2560-128a-s-pamyatyu-512kb, с поста №8 как раз мои исследования работы АЦП на повышенных частотах.

toc
Offline
Зарегистрирован: 09.02.2013

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

В любом случае, будет полезно: https://www.gammon.com.au/adc

mag155
Offline
Зарегистрирован: 21.12.2017

Мне нужно мерить одновременно 5 входов АЦП может лучше чтоб разгрузить мк использовать внешний АЦП. Типа АDS 1115 . Что скажите ?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ваши 50гц нормально можно мерить и встроенным АЦП, что Вас смущает?

Типовой замер - 15 килозамеров в сек. 1/5 = 3 килозамера или 333мксек. частота 50гц - это 20 000мксек или 60 замеров на период по всем 5-и входам. Или точность замера в районе 6 градусов синуса. Его макс скорость изменения возле нуля, соответственно, макс. ошибка это sin(6) = 9.4% в районе нуля и 3,1% в районе максиумов и миниумов. Средняя ошибка составит 6.25% - это для Вас много? Сколько требуется по задаче?

Далее. 15кзамеров/сек это около 55мксек на замер. Если это делать по прерыванию, то обработчик можно уложить в 10-15мксек. Итого свободного времени на все остальное останется не менее 30мксек на каждом замере. Или 30/55 = 54% времени ЦП. Вполне достаточно для прочих задач из loop() или надо больше? Сколько?

Для частоты замеров в 1мгц (ваш предел) = 78 кзамеров/сек, соответственно повышается точность замера, но и падает доля свободного времени ЦП для "прочих задач".

Тут можно отказаться от непрерывности замеров, если Вам не нужен весь синус 50Гц, а только его "особые точки", например Вас интересует "переход через ноль" или поиск "максиума/миниума". И, кроме этого, ваши 5 датчиков имеют некоторую связность промеж себя, например "фазность": зная время когда от одного найденного сигнала, стоит уточненно искать следующий - можно прерывать непрерывность поиска для других задач.

Но, мне больше кажется, что типовых 15к - Вам вполне хватит. И они вполне нормально пашут в непрерывном режиме по прерыванию, оставляя около 50% на все прочие задачи.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Внешний АЦП .. а что он Вам даст? Да, он справится и точнее и шустрей (за соотв. бабки конечно же), но .. поток его мысли придется принимать и обрабатывать точно также на повышенной скорости, да ещё и 5шт сразу.. SPI, I2C, UART .. какой интерфейс выбрать для 5-и АЦП "срущих" в микроконтроллер одновременно? А микроконтроллер сумеет принять все 5 потоков полноценно?

Мне кажется, что Вам стоит для начала провести оценку погрешности тех или иных требований к результату, а уже на их основе выбирать требуемые ТТХ элементов (скорость АЦП в частности и вообще интсрумент - камень в общем).

mag155
Offline
Зарегистрирован: 21.12.2017

Благодарю за столь развернутый ответ. Задача мерить постоянное (после диодного моста ) напряжение и сравнивать его с напряжением задания, вычитать ошибку если она есть и потом контроллеру эту ошибку убирать уменьшая либо увеличивая напряжение на выходе. Третьим каналом мерить ток (по сути тоже постоянное напряжение) . Напряжение на выходе максимум 450 вольт а на входе всего 4.5 это в что раз меньше .

mag155
Offline
Зарегистрирован: 21.12.2017

То есть примерно если брать ацп. От 0 до 1023 это 4 шага на вольт. Точность нужна плюс минус 3 вольт а на выходе То есть это грубо 10 шагов ацп. В принципе достаточно но есть еще шумы ? Так же параллельно с этим МК. по прерывается по синхроимпульсам из трех фаз ( одна фаза синхроимпульс 50 герц.) Плюс еще кнопки считывать . Вот и получается что МК работает на пределе. Вот и думал разгрузить его от АЦП. Что скажите ?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

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

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

3. Про прерывания и синхроимпулсы от 3-х фаз .. извините, но ничего не понял.

4. Считывать кнопки - это не "работа" для МК. В том смысле что на затратах ЦП это не сказывается, практически никак при его 16Мгц. :)

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

I2C - довольно медленный интерфейс. Заявленная частота преобразования 0.86 ksps тоже не кажется достаточной. Это не более 17 выборок на период для одного канала. А если каналов 5 - вообще получается по 3 выборки. Так что выбор этого чипа вряд ли могу признать удачным.

Сам пользовался MCP3008. Интерфейс SPI, максимальная скорость преобразования 200 ksps. И, честно говоря, никаких противопоказаний против использования внешнего АЦП не вижу. Ну, естественно, кроме лишнего корпуса, пайки и цены сопоставимой с ценой Pro Mini.

Кстати, "типовой замер" АЦП Ардуины - это 112 мкс или чуть менее 9 ksps, а не 15 ksps, как было указано выше. Можно, конечно, измерять и с более высокой скоростью, но тут уж надо знать, - как, с какой целью и какой ценой.

mag155
Offline
Зарегистрирован: 21.12.2017

По синхроимпульса МК раздает импульсы управление тиристорами . Принцип как у диммер. Только тиристоров 6 а фаз три.

mag155
Offline
Зарегистрирован: 21.12.2017

Скорость нужна не то что замера и работы МК. Но как я понимаю чем быстрее скорость замера тем быстрее МК. перейдет к другой операции.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Мне ваш "диммер" ничего не говорит. Если правильно понял, то Вы снимаете напряжение, выпрямленное мостом, сравниваете его с опорным и на основании разбега выдаете упр. импульсы на регулятор мощности. Так? Если да, то ваши тиристоры в общем-то не при чем. Основной цикл работы - проверить разницу и выдать упр. сигналы. Зачем тиристорам АЦП? вы хотите использовать аж 5 каналов АЦП .. один на замер и сравнение с опорным, один на замер тока .. куда ещё три? :)

2. Скорость замера влияет на время кода напрямую, только если замер ожидает конца замера в паузе. Если замер по прерыванию (что в скоростных режимах даже медленней), то на остальной код он влияет весьма опосредовано: только временем запуска и реакции на прерывание (что может быть существенно меньше времени замера).

mag155
Offline
Зарегистрирован: 21.12.2017

Пять Ацп. Один задатчик. Второй меряем напряжение на выходе. Еще два определяем направление и уровень напряжения перед переключением( хотя можно переделать и на цифровые входы ). Ну и ток меряем напряжение с шунта . К стати сегодня замерил скорость АЦП.НА DUE . Вот что получилось 10275 то есть одна микросекунда против 1120136 (112 микросекунд ) у меги.

mag155
Offline
Зарегистрирован: 21.12.2017

Подскажите пожалуйста правильно ли я написал код. if( dimmer < zadat ){ D3_Low.} if(micros() - time > 500) {D4_HIGH}ЗАДАЧА ТАКАЯ ЕСЛИ dimmer больше zadat нужно Выкл пин 3. Потом подождать и включить пин 4. Извиняюсь за текст с телефона пишу .

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Не надо сюда писать с телефона. Неправильно получается.