10-битный АЦП Arduino не точен?

adc voltage-divider

Я считываю напряжение с помощью делителя напряжения:

схема

| Arduino подключен как к USB, так и к адаптеру 9 В.

float r1 = 100000;
float r2 = 9980;
float adc, voltage, analog;
void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  pinMode(A0, INPUT);
}

void loop() {
  for (int i = 0; i < 256; ++i) {
    analog += analogRead(A0);
  }
  analog = analog / 256;
  adc = analog * 1.228 / 1023;
  voltage = adc / (r2 / (r1 + r2));
  Serial.print(analogRead(A0));
  Serial.print(", ");
  Serial.print(analog);
  Serial.print(", ");
  Serial.print(adc);
  Serial.print(", ");
  Serial.print(voltage);
  Serial.println(" ");
  delay(100);
}

Вот результат теста на точность:

Input | Arduino | Difference
 1V      0.89V     -110mV
 2V      1.90V     -100mV
 3V      2.92V     -80mV
 4V      3.93V     -70mV
 5V      4.95V     -50mV
 6V      5.97V     -30mV
 7V      6.98V     -20mV
 8V      8.00      0
 9V      9.01      +10mV
 10V     10.02     +20mV
 11V     11.04     +40mV
 12V     12.06     +60mV

Входное напряжение измерено цифровым мультиметром и соответствует напряжению, например, 1 000 В.

Я не тестировал напряжения выше 12 В, но кажется, что разница будет увеличиваться на 20 мВ с каждым повышением на 1 В, это означает, что при 50 В показания напряжения будут отличаться на ~ 1 В!

Даже с 10-битным разрешением Arduino у меня должна была быть стабильная точность с некоторым процентом разницы (правильно?), но, как вы можете видеть, результат показывает, что показания совсем не стабильны!

Почему разность напряжений уменьшается/увеличивается при изменении напряжения на входе?

, 👍1


2 ответа


Лучший ответ:

3

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

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

voltage = 0.9848815 * voltage + 0.125354;

Или вы могли бы вместо этого вычислить коррекцию на уровне АЦП и заменить

adc = analog * 1.228 / 1023;

от

adc = (analog + offset) / scale;

где смещение и масштаб вычисляются на основе калибровки.


Правка: вот как я извлек калибровочные коэффициенты из данные.

Сначала я сохранил данные в текстовый файл Calibration.tsv и очистил его. чтобы удалить единицы и добавить маркер комментария (#) перед столбцом ярлыки:

#Input | Arduino | Difference
 1      0.89     -110e-3
 2      1.90     -100e-3
...

Затем я просмотрел данные с помощью gnuplot. Так как я хочу знать, как исправить показания, я нарисовал сумму, которую я должен добавить (минус столбец 3) по сравнению с показаниями Arduino (столбец 2):

plot 'calibration.tsv' using 2:(-$3)

На данный момент кажется, что это линейно с тем, что выглядит в основном шум квантования. Я моделирую это как линию уравнения a*x+b, и сравнить строку с данными:

a = -1e-2
b = 0.12
plot 'calibration.tsv' using 2:(-$3), a*x+b

Линия сильно отличается от данных, но в первую очередь это разумно. приближение. Теперь я прошу gnuplot выполнить подбор по методу наименьших квадратов, затем взгляните еще раз:

fit a*x+b 'calibration.tsv' using 2:(-$3) via a, b
replot

Теперь подгонка выглядит неплохо. После завершения подгонки gnuplot отображается:

Final set of parameters            Asymptotic Standard Error
=======================            ==========================
a               = -0.0151185       +/- 0.0002953    (1.953%)
b               = 0.125354         +/- 0.002173     (1.734%)

так что теперь я знаю, что могу исправить данные с помощью:

voltage += -0.0151185 * volatage + 0.125354;

что эквивалентно тому, что я написал выше.

,

Как рассчитать смещение и масштаб?, @ElectronSurf

@newbie, поместите данные в Excel/Calc, нарисуйте диаграмму с ожидаемыми значениями и функцией, а затем измените значения смещения и масштаба для функции, пока линии на диаграмме не совпадут., @Juraj

@Juraj Нравится [Это](https://1drv.ms/x/s!AgDusyVPFjOrglWeWee06WbLD3lx)?, @ElectronSurf

Код «напряжение = 0,9848815 * напряжение + 0,125354» почти откалибровал показания с устойчивой разницей ~ -60 мВ (хотя он не может измерять ниже 130 мВ), откуда вы взяли эти значения? не могли бы вы объяснить больше с включенной математикой?, @ElectronSurf

@newbie: я старожил, которому нравятся текстовые программы, а не Excel, Calc и тому подобное, поэтому я использовал gnuplot. Смотрите расширенный ответ., @Edgar Bonet

@EdgarBonet Ты гений, теперь мне нужно сесть и изучить твой ответ. Спасибо., @ElectronSurf

@newbie, столбец B должен иметь функцию в ячейках. и функция должна использовать две другие ячейки с коэффициентами, которые вы хотите настроить, @Juraj

@Juraj Я никогда раньше не пользовался Excel и понятия не имею, как сделать то, что ты хочешь, чтобы я сделал ..., @ElectronSurf

@newbie, пример https://github.com/jandrassy/Regulator/tree/master/util/Calc, @Juraj


2

Да, вы правы в том, что АЦП Arduino не является точным. Если вы прочитали техническое описание (ATMega328P, раздел 28.9, Характеристики АЦП ) можно увидеть множество характеристик "ошибки" и "нелинейности".

Все это приводит к неточностям в ваших показаниях. Например, «ошибка смещения» на вашем VREF может достигать ± 4,4 мВ, а «ошибка усиления» такая же. Нелинейность может достигать 2 мВ и т. д.

АЦП Arduino не предназначен для обеспечения точности. Это должно быть простым и дешевым в реализации. (Это "АЦП последовательного приближения" - ключевое слово здесь - приближение...) Если вам нужна более высокая точность, то есть более подходящие микросхемы АЦП, обеспечивающие такую точность.

,

Я ожидал, что ошибка 100 мВ будет устойчивой, как 1,100 В, 2,100 В ... Потрачено столько времени на калибровку этого ...! помимо использования внешнего АЦП, вы думаете, что это хорошая идея переключиться на микроконтроллер PIC с 12-битным АЦП. я спрашиваю это, потому что PIC дешевле., @ElectronSurf

Я бы всегда советовал использовать PIC, а не ATMega, но тогда я фанат PIC, однако увеличение разрешения не означает повышение точности. Это все еще SAR с неотъемлемыми неточностями, которые он вам дает. Поскольку неточность выглядит довольно линейной, вы можете использовать калибровку и расчеты, чтобы устранить ее. У вас есть прямая линия, формула которой (если вы помните школьные уроки математики) y = mx + c, @Majenko

Относительно «АЦП последовательного приближения»: любое измерение всегда является приближением. Ключевое слово здесь «последовательный»: это означает, что АЦП работает путем итеративного уточнения аппроксимации., @Edgar Bonet

@EdgarBonet А поскольку замеренное напряжение хранится в крошечном конденсаторе, и невозможно прочитать напряжение, не потребляя *некоторый* ток, каждое последующее сравнение будет влиять на напряжение на этом конденсаторе, делая его менее точным с каждым битом, который аппроксимируется. Таким образом, это последовательно ухудшающееся приближение. Это последовательное приближение, которое может быть только приблизительным., @Majenko