DUE и измерение напряжения

tokima
Offline
Зарегистрирован: 29.08.2015

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

void setup() {
 analogReadResolution(12);
}

void loop() {
  int x=analogRead(A0);// Напряжение
  int k=15
float X = x*3.3/4095.0*k;//Напряжение
   g.printNumF( X, 1, 5, 45, '.', 4); //Напряжение

}

Могу написать условие: до 10В один коэффицент, от 10 до 30В другой, 30 - 50В третий, но на границах все равно не удовлетворительно. Как написать цикл, что бы float k=n (n росло вместе с падением напряжения на входе).

Спасибо.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

tokima пишет:

Здравствуйте, помогите написать цикл. ... Как написать цикл, 

О каком цикле речь и где цикл в Вашем нынешнем коде (в каких строках)?

tokima
Offline
Зарегистрирован: 29.08.2015

Так нет у меня его, цикла, я не догоняю как мне плавно изменять коэффицент "k", что бы он плавно изменялся с ростом напряжения на делителе от 0 до 50В с k=20 до k=15.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

У Вас проблем не в цикле, а в формулировке задачи. Для начала внятно выпишите что и как Вам надо менять. Формулой, или таблицей, или чётким описанием. И только тогда можно думать о программировании с которым проблем не возникнет.

tokima
Offline
Зарегистрирован: 29.08.2015

Ладно, спасибо. Видимо не смог внятно объяснить.. Обошелся условиями else if.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

можно через MAP, но это не очень точно:

Я правильно же понял вы хотите получить 4096 единиц градаций коэффициента K в диапазоне значений от 20 до 15?

k = map (x,0,4095,20,15);

 

tokima
Offline
Зарегистрирован: 29.08.2015

Я не соображу как объяснить.. На входе А0 делитель, напряжение до делителя 0-50В, после делителя соответственно 0-3.3В . То есть 50В - 4095(А0). Вычисляем:

void loop() {
  int x=analogRead(A0);
  float X = x*50/4095.0;
}

Но в реале чем меньше напряжение тем больше погрешность. Например:

На делитель        На экране

50.0                      50.0

40.0                      39.9

30.0                      29.7

20.0                      19.6

10.0                        9.4

5.0                          4.3

1.0                          0.3

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

if(X<0.2){
  X=0.0;
}
else if(X <= 15.0){
  X = (X + 0.7);
}
else if(X > 15.0 && X <= 25.0){
  X = X + 0.5;
}
else if(X > 25.0 && X <= 35.0){
  X = X + 0.3;
}
else if(X > 35.0 && X <= 42.0){
  X = X + 0.2;
}
else if(X > 42.0 && X < 50.0){
  X = X + 0.1;
}

вношу поправку в диапазонах, но при измерении на границах этих диапазонов все равно погрешность небольшая.

ЗЫ Поправил косяк в коде, где границы выпадают из вычислений.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так-то точно нелья, у Вас диапазоны не пересекаются. Например (маловерятно, но возможно) X окажется ровно 35. Тогда он у Вас вообще никак не скорректируется.

А вообще, я же Вас сказал, сделайте таблицу или формулу, лучше формулу.

tokima
Offline
Зарегистрирован: 29.08.2015

Не совсем понял какую таблицу? Вольты - единицы счета? Теореоретически можно завтра попробовать в сериал отправить и скопировать потом. А с каким шагом нужно? 

Про формулу совсем не понял.

tokima
Offline
Зарегистрирован: 29.08.2015

ua6em пишет:

можно через MAP, но это не очень точно:

Я не знаком с этим оператором, но что-то в этом есть.. По аналогии с электроникой можно организовать сдвиг диапазона и расширение (сужение) диапазона. Тоесть подобрать коэффицент умножения , где приведенная погрешность будет равной во всем диапазоне, а затем сузить весь диапазон. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

tokima пишет:

Не совсем понял какую таблицу? Вольты - единицы счета? Теореоретически можно завтра попробовать в сериал отправить и скопировать потом. А с каким шагом нужно? 

Про формулу совсем не понял.

Ну, чего Вы не поняли? У Вас есть преобразование. Ну, и сделайте таблицу. А потом на основе таблицу придумайте формулу, которая будет представлять Ваше преобразование как функцию от Х. И используйте эту формулу на здоровье.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

tokima пишет:

Не совсем понял какую таблицу? Вольты - единицы счета? Теореоретически можно завтра попробовать в сериал отправить и скопировать потом. А с каким шагом нужно? 

Про формулу совсем не понял.

Ну, чего Вы не поняли? У Вас есть преобразование. Ну, и сделайте таблицу. А потом на основе таблицу придумайте формулу, которая будет представлять Ваше преобразование как функцию от Х. И используйте эту формулу на здоровье.

ТС думает, что у него делитель нелинейный, если обычный резисторный то этого не может быть, потому что не может быть никогда )))
Входная последовательность X в диапазоне от 0 до 4095 у него умножается на коэффициент делителя который должен быть разным и уменьшаться с 20 до 15
Непонятно почему ТС так решил, но формула в принципе несложная

1. Вычислить значение коррекции на единицу АЦП: (20-15)/4095 = 0,001221
это наша поправка в мунус коэффициента K на каждую единицу значения АЦП

Получается:

void setup() {
 analogReadResolution(12);
}

void loop() {
  int x=analogRead(A0);// Напряжение
  float k=20 -x*0,001221;
float X = x*3.3/4095.0*k;//Напряжение
   g.printNumF( X, 1, 5, 45, '.', 4); //Напряжение

}

 

nik182
Offline
Зарегистрирован: 04.05.2015

ua6em пишет:

ТС думает, что у него делитель нелинейный, если обычный резисторный то этого не может быть, потому что не может быть никогда )))

Со всей пролетарской ненавистью (С) присоединяюсь к докладчику. Не может быть нелинейности при правильно собранном делителе. Схему очень хочется посмотреть. Проблемы в ней. А программно компенсировать неправильно собранную схему это как то не хорошо.

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

nik182 пишет:

А программно компенсировать неправильно собранную схему это как то не хорошо.

Ну так вся IT отрасль на этом живет...

tokima
Offline
Зарегистрирован: 29.08.2015

Схему.. Да не вопрос..

https://yadi.sk/i/sbPB2a6s3GLK9p

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Поправлю код:
 

void setup() {
 analogReadResolution(12);
}

void loop() {
  int x=analogRead(A0);// Напряжение
  float k=20 -x*0.001221;
float X = x*3.3/4095.0*k;//Напряжение
   g.printNumF( X, 1, 5, 45, '.', 4); //Напряжение

}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Я бы посмотрел осциллограмму по-переменке на входе АЦП. И кстати при одном вольте на входе напряжение после делителя будет 1000/16=62mV, о точности измерения тут речь можно не вести, это почти начало шкалы (LSB~13mV) ++ учитывая что ещё помех может набраться незнамо сколько.  Так что если откалибровать по середине диапазона как это обычно делают, то может не всё так и плохо будет..

PS Кстати емкостей на кренках только я не вижу? :)

tokima
Offline
Зарегистрирован: 29.08.2015

Фильтрующие и блокировочные конденсаторы не засоряют схему, в реальности они есть, SMD керамика и тантал.

Включен 12-битный режим ЦАП - АЦП, так что разрешающая способность вроде должна позволять мерять одно-вольтовые значения. Без всяких программных костылей(среднее из 50-ти выборок и срезания одиночных пиков) плавает на одном вольте до делителя  от 20 до 23 единиц на А0. Прикольно, что с датчика Холла малые токи меряются поиемлемо. А на нем ОУ А1.2 диапазон так же делает 0-3.3В  Попробую другую ДУЕ, подготовлю сегодня.   

ЗЫ Может в питании все дело, схема питается от 12В импульсника и испытуемый подключен импульсник..

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

tokima, для платы DUE нужно вешать внешний качественный ИОН (и перепаять перемычку на плате) , иначе в её АЦП сливаются все помои с шины питания.

tokima
Offline
Зарегистрирован: 29.08.2015

dimax, 

Ага, у меня этот момент на стадии осмысления. Засада с деньгами для поезди в ЧИПиДИП.  :-(

nik182
Offline
Зарегистрирован: 04.05.2015

Поставте усилетель-повторитель на вход А0 и будет вам счастье. Слишком большое сопротивление делителя. Или уменьшать или повторитель.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

Поставте усилетель-повторитель на вход А0 и будет вам счастье. Слишком большое сопротивление делителя. Или уменьшать или повторитель.

А сколько у DUE входное сопротивление по аналоговым входам?

tokima
Offline
Зарегистрирован: 29.08.2015

Проблемма решилась заменой ДУЕ, теперь нет такого разброса , на 1В честные 80 единиц. Не разбирался, этот глюк на конкретном входе или в целом. Полежит пока прежняя платка, пока этот проект не добью. Спасибо всем заинтересовавшимся за участие и советы, знаний по програмированию не хватает, так что еще буду обращаться.

nik182
Offline
Зарегистрирован: 04.05.2015

ua6em пишет:

nik182 пишет:

Поставте усилетель-повторитель на вход А0 и будет вам счастье. Слишком большое сопротивление делителя. Или уменьшать или повторитель.

А сколько у DUE входное сопротивление по аналоговым входам?

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

ua6em пишет:

nik182 пишет:

Поставте усилетель-повторитель на вход А0 и будет вам счастье. Слишком большое сопротивление делителя. Или уменьшать или повторитель.

А сколько у DUE входное сопротивление по аналоговым входам?

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

А библиотека разве это не делает? для нано вроде как 100 микросекунд время чтения

По АЦП не знаю, а вот у осциллографа чем меньше входная ёмкость и больше сопротивление было всегда лучше, 15 пф обычная величина как бы, сколько у аналогового входа дуины, не думаю, что обычный пользователь в состоянии сделать схему на ОУ с входной ёмкостью менее 15 пикушек, лучшее враг хорошего