Ви не увійшли.
Вот да, на это я и намекал - 250Khz это как бы на 1/3 больше рекомендованного диапазона. При правильной настройке там и 19kSPS получить можно. Работать будет - по докам косвенно указано, что до 1Mhz АЦП разгонять можно. Только надеяться на 10bit даже при 250Mhz я бы уже не стал, хотя прямого указания на сколько падает точность при повышении частоты я в свое время ни где не нашел.
Тест недействителен. Сравнивали разовую вычитку из АЦП с простым проходом по циклу, да еще выкинули из времени delay(500). Вопрос: что этим примером хотел показать автор?
Если бы он сравнивал предыдущий код самостоятельной настройки получения данных из АЦП и функцию analogRead() - такой "разительной" разницы не наблюдалось бы.
Я не поддерживаю ардуино, оно действительно тормознутое, но не поддерживаю за уши притянутые тесты.
Тест недействителен. Сравнивали разовую вычитку из АЦП с простым проходом по циклу, да еще выкинули из времени delay(500). Вопрос: что этим примером хотел показать автор?
Если бы он сравнивал предыдущий код самостоятельной настройки получения данных из АЦП и функцию analogRead() - такой "разительной" разницы не наблюдалось бы.
Я не поддерживаю ардуино, оно действительно тормознутое, но не поддерживаю за уши притянутые тесты.
Можете провести правильное сравнение и выложить тут результаты ...
Неактивний
Андрей М. пише:Тест недействителен. Сравнивали разовую вычитку из АЦП с простым проходом по циклу, да еще выкинули из времени delay(500). Вопрос: что этим примером хотел показать автор?
Если бы он сравнивал предыдущий код самостоятельной настройки получения данных из АЦП и функцию analogRead() - такой "разительной" разницы не наблюдалось бы.
Я не поддерживаю ардуино, оно действительно тормознутое, но не поддерживаю за уши притянутые тесты.Можете провести правильное сравнение и выложить тут результаты ...
Вы автор поста, поэтому за правдоподобность Вам и отвечать. Кстати, ранее, на ошибку тестов указал Vlad17
Думаю, что все понятно без объяснений…
Понятно, что пример жульнический.
При правильном сравнении время единичного измерения практически не отличается. Выигрыш от регистров можно получить, если измерять несколько раз с одного и того же пина - тогда не нужно его каждый раз настраивать.
Ну или ещё один выигрыш - если не ждать завершения измерения тупо в while, как у тебя, а в это время делать другие дела. Но это может ухудшить качество измерения. Производитель советует наоборот, отправлять контроллер на это время в сон.
Неактивний
renoshnik пише:Думаю, что все понятно без объяснений…
Понятно, что пример жульнический.
При правильном сравнении время единичного измерения практически не отличается. Выигрыш от регистров можно получить, если измерять несколько раз с одного и того же пина - тогда не нужно его каждый раз настраивать.
Ну или ещё один выигрыш - если не ждать завершения измерения тупо в while, как у тебя, а в это время делать другие дела. Но это может ухудшить качество измерения. Производитель советует наоборот, отправлять контроллер на это время в сон.
я все прочитал и решил проверить, вооружившись документацией на ATMega. Время на преобразование я смотрел осциллографом. Для этого устанавливал и сбрасывал единицу на ноге D13.
вот скетч:
void SetupADC()
{
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0);//разрешаем АЦП, прескалер АЦП ставим 16 (по даташиту на Atmega)
}
inline unsigned int ReadADC(byte Chan)
{
const byte ADMUXMask = (0 << ADLAR) | (0 << REFS1) | (1 << REFS0); // опорное напряжение ARef=AVcc
const byte ADSCMask = 1 << ADSC;
ADMUX = ADMUXMask | (Chan & B0111);
ADMUX = ADMUX;// задержка на переключение мультиплексора
ADMUX = ADMUX;// задержка на переключение мультиплексора
ADCSRA |= 1 << ADSC;// Запускаем АЦП
while (ADCSRA & ADSCMask) {}; // ждем конца преобразования
return (ADCL | (ADCH << 8)); // возвращаем результат
}
void setup() {
Serial.begin(115200);
pinMode(13,OUTPUT);
SetupADC();
}
void loop()
{
PORTB |= 1<<5; // устанавливаем единицу на D13 ( на ноге D13 устанавливаем щуп осциллографа)
int ADC0 = ReadADC(0);
PORTB &= 0x11011111; // устанавливаем D13 в 0
Serial.println(ADC0); // выводим в монитор порта результат
delay(100);//может быть любой, не имеет значения
}
При прескалере АЦП=8 длительность преобразования у меня получилась около 8.5 мкс.
При прескалере АЦП=16 длительность преобразования у меня получилась около 16 мкс.
Длительность контролировал осциллографом.
При меньших значениях прескалера, АЦП практически не работает( резко падает разрешение). А начиная с 8 мкс на преобразование, АЦП работает очень хорошо, шум порядка +-1 квант ( то есть реально получать 10 разрядов и 50000..100000 преобразований в секунду). Что кстати подтвердили микропроцессорщики с нашего КБ.
При прескалере АЦП=
Дальше можно не читать.
Производитель микроконтроллера даёт вполне конкретные рекомендации по установке делителя. И там вариантов практически нет. Другие установки - это партизанщина и гаражное любительство.
Неактивний
ДОбрый день. Подскажите пожалуйста толковый скетч. Есть Ардуино Мега. Нужно измерять звуковые сигналы до 20 кГц. Частота дискретизации должна быть 100кГц, лучше если 200кГц. Разрядность желательно 10-12, если не получится, можно и 8.
И что дальше делать с данными? Производительности процессора может не хватить.
to Kaka и Green : По поводу радиолюбительства даже странно слышать, как я понял, тут типа профессионалы на Arduino профессиональные проекты собирают.
Kaka, может все таки сначала почитать что пишет производитель. цитирую из стр 249 даташита на ATmega48A/PA/88A/PA/168A/PA/328/P :
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.
Тут вроде все понятно на чистом английском написано...
Тут вроде все понятно на чистом английском написано...
Таки да. Всё понятно. Если нужно меньшее разрешение, то можно и подразогнать.
Вот я и сказал, что пример ТС - жульнический. Он взял функцию с максимальным разрешением, сравнил её со своей, у которой погрешность вдвое выше, и радостно заявил о своей победе в быстродействии. Это не жульничество? А что?
Остання редакція Kaka (2019-04-06 11:03:44)
Неактивний
Лично у меня на Arduino получилось с очень приемлемым шумом преобразование порядка 60000 Гц . Я уже пожалел, что вообще что то написал. У Юлии на Arduino навряд ли поработать со звуком получится, я бы на ее месте в сторону Teensy посмотрел.
На мой взгляд- радиолюбитель это не ругательство. Я по профессии инженер-электронщик. Просто Arduino раньше не трогал. Студенты рядом ходили, у них были проблемы с измерениями на Arduino. Вот пришлось самому взять осциллограф и посмотреть.
Остання редакція Юрий И (2019-04-06 11:04:22)
Неактивний
Vlad17 пише:прямого указания на сколько падает точность при повышении частоты я в свое время ни где не нашел.
А в даташите смотрел?
Раздел 29.8, стр. 310. При 200кГц - 2 lsb, при 1МГц - 4.5 lsb
Ага,спасибо, теперь и я туда посмотрел . Как то в спешке туда не раньше дошел. Тут явно рассматривается суммарная погрешность преобразования.
Вообще то вряд ли можно рассматривать встроенные АЦП, как серьезные средства измерения.
Неактивний
... Вообще то вряд ли можно рассматривать встроенные АЦП, как серьезные средства измерения.
А что вы считаете серъёзными, эталонные измерительные приборы? Микроконтроллеры не для этого.
Юрий И пише:... Вообще то вряд ли можно рассматривать встроенные АЦП, как серьезные средства измерения.
А что вы считаете серъёзными, эталонные измерительные приборы? Микроконтроллеры не для этого.
Я имел ввиду внешние микросхемы АЦП. Вот прямо сейчас подключаю к Ардуине AD7680 Получается , как прототип вполне сойдет.
Остання редакція Юрий И (2019-04-06 11:44:14)
Неактивний
Юрий И. пише:Тут вроде все понятно на чистом английском написано...
Таки да. Всё понятно. Если нужно меньшее разрешение, то можно и подразогнать.
Вот я и сказал, что пример ТС - жульнический. Он взял функцию с максимальным разрешением, сравнил её со своей, у которой погрешность вдвое выше, и радостно заявил о своей победе в быстродействии. Это не жульничество? А что?
жульничество это если бы я скрыл код и выдавал полученный результат как достижение...
тут коды приведены, поэтому это просто не корректный эксперимент...
вы заметили несоответствия, озвучили их тут и любой пользователь сам может оценить и принять решение...
Неактивний
Юрий, спасибо, очень интересная статья.
______________________________________________________________
По поводу комментаторов, недовольных сравнительными тестами.
Для вас есть несколько поправок.
Использование контроллера, тем более на платформе ардуино - очень специфическая тема.
Все зависит от задачи и результата. А решения бывают диаметрально противоположными. Речь в статье идет не о замене этой конкретной функции, а об альтернативе получения менее точного результата более быстрым методом.
К примеру - мне нужно понимать по току на шунте, остановился ли ротор DC мотора . При торможении ротора ток возрастает в несколько раз. Напряжение на шунте изменяется от примерно 0,6V до примерно 1.4V. Мне нужно только знать, началось ли торможение (уровень ПРИМЕРНО выше 1V) или нет.
Отреагировать нужно максимально быстро. А моторов несколько)
Как получить результат? Опросить несколько портов analogReead() и отреагировать ПРИМЕРНО через 100 мкс, в течении которых МК простаивает в ожидании завершения работы ADC, или сделать то же самое, но за 10 мкс? При этом точность измерения мне нужна +/- лапоть, а штатная analogReead() убивает время, которого нет и так.
А как решить задачу, где требуется непрерывный опрос всех 6 аналоговых входов и вывод результата в виде ШИМ на 6 цифровых выходов, при этом параллельно делать опрос нескольких цифровых входов и в зависимости от их состояний крутить несколько циклов? Использовать ISR(ADC_vect) и ручную настройку регистров ADC или же вы через жо.. сорри - через analogReead() и digitalWrite() справитесь? Без жульничества?
Получится у вас? Вы же не дураки как и авторы штатной analogReead()? Покажите мне на примере.
Поэтому, прежде чем кидать в кого-то мокрыми тапками, сделайте что то полезное сами - статью напишите более правильную на ваш взгляд или предложите другой вариант в виде своей библиотеки.
... Отреагировать нужно максимально быстро. А моторов несколько)
Как получить результат? Опросить несколько портов analogReead() и отреагировать ПРИМЕРНО через 100 мкс, в течении которых МК простаивает в ожидании завершения работы ADC, или сделать то же самое, но за 10 мкс? При этом точность измерения мне нужна +/- лапоть, а штатная analogReead() убивает время, которого нет и так.
А как решить задачу, где требуется непрерывный опрос всех 6 аналоговых входов и вывод результата в виде ШИМ на 6 цифровых выходов, при этом параллельно делать опрос нескольких цифровых входов и в зависимости от их состояний крутить несколько циклов? Использовать ISR(ADC_vect) и ручную настройку регистров ADC или же вы через жо.. сорри - через analogReead() и digitalWrite() справитесь? Без жульничества?
Именно так, как вы выразились, через жо.. Подобные задачи реального времени требуют разработки адаптированных под них HAL-ов. А для AVR и универсального нет, за ненадобностью. А ядро Ардуино прекрасный инструмент для прототипирования компонентов программ. Так что нужно разобраться с какой стороны жо...
...Получится у вас? Вы же не дураки как и авторы штатной analogReead()? Покажите мне на примере.
Поэтому, прежде чем кидать в кого-то мокрыми тапками, сделайте что то полезное сами - статью напишите более правильную на ваш взгляд или предложите другой вариант в виде своей библиотеки.
Вы оплатите?
Вы оплатите?
Поразительная жадность. Конечно же нет) Если вы заметили, это форум, а не базар. Причем вполне себе любительский форум.
На котором вы реагируете менее, чем за несколько часов.
Для моих целей на атмеге328 эта задача решается простой функцией, выполняемой за 4 мкс с любым прескалером-
(мне нужно было только для двух входов - А0 и А1)
Накидал за минуту, прочитав эту статью.
//+++++++++++++++++++++++++++++++++++++++++++++
byte Current_Measure(bool A_PIN)
{
ADCSRA = 0; ADCSRB = 0; ADCSRA=B11100111;
if (!A_PIN)ADMUX=B01100000; // вход A0
else ADMUX=B01100001; // вход A1
byte VoltLVL = ADCH;
return VoltLVL;
}
//+++++++++++++++++++++++++++++++++++++++++++++
Для моей задачи этого более, чем достаточно, учитывая время выполнения штатной analogRead();
Пользуйтесь на здоровье.
Watchdog пише:Вы оплатите?
Поразительная жадность. Конечно же нет) Если вы заметили, это форум, а не базар. Причем вполне себе любительский форум.
На котором вы реагируете менее, чем за несколько часов.
...
Накидал за минуту, прочитав эту статью.
...
Пользуйтесь на здоровье.
Не нужно меня воспитывать у меня свои родители есть. Так кто из нас жаден? Во всём мире за публикации статей платят. А форум и есть базар! https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D1%83%D0%BC А на базаре нужно быть расторопным. Всем же известно: "Кто хочет тот и платит". Но у вас видимо всё наоборот. А мне ваши скетчи и даром не нужны. Учитель ...