Сколько надо циклов, чтобы перейти с опорного напряжения ADC 5V на 1.1V

Приветствую Всех !

По сути вопрос уже в заголовке темы.

Небольшие пояснения.

Необходимо мерить значение с датчиков (относительно медленно меняющихся). Для некоторых датчиков диапазон 0 - 5В, для некоторых 0 - 1 В. Что бы не городить дополнительный усилитель, использую переключение опорного напряжения с 5В на 1.1В и наоборот.

Также переписал работу analogRead на прерывание. Кому интересно, тестовый код ниже

#define A0 0
#define A1 1
#define A2 2
#define A3 3
#define A4 4
#define A5 5
#define A6 6
#define A7 7

#define delay_ADC 50

byte chanel_mode_ADC[8] = { 0 };
int chanel_data_ADC[8] = { 0 };
volatile byte i_ADC_new = -1;
volatile byte i_ADC_old = -1;
volatile byte delay_counter_ADC = 0;

void analogReference(byte n, byte m) {
  chanel_mode_ADC[n] = (m << 6);
}

int analogRead(byte n) {

  if (chanel_mode_ADC[n] == 0) {
    chanel_mode_ADC[n] = (DEFAULT << 6);
  }

  if (i_ADC_new > 7) {
    i_ADC_new = n;
    ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (0 << ADIF) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
  }

  return chanel_data_ADC[n];
}

ISR(ADC_vect) {
  if (delay_counter_ADC == delay_ADC) {
    //чтение преобразования
    chanel_data_ADC[i_ADC_old] = ADC;
    i_ADC_old = i_ADC_new;
  }

  if (delay_counter_ADC == 0) {

    //чтение преобразования
    chanel_data_ADC[i_ADC_old] = ADC;

    //определение следующего канала
    i_ADC_old = i_ADC_new;
    do {
      i_ADC_new = (i_ADC_new + 1) & 0x07;
    } while (chanel_mode_ADC[i_ADC_new] == 0);

    // если изменилось опорное напряжение, то необходима задержка
    if ((ADMUX ^ chanel_mode_ADC[i_ADC_new]) & 0xC0) {
      delay_counter_ADC = delay_ADC;
    }

    //настраиваем канал
    ADMUX = chanel_mode_ADC[i_ADC_new] + i_ADC_new;

  } else --delay_counter_ADC;
}

void setup() {
  Serial.begin(115200);
  Serial.println("START");

  analogReference(A0, INTERNAL);
}

void loop() {
  delay(300);
  Serial.print(analogRead(A0));
  Serial.print("\t");
  Serial.print(analogRead(A1));
  Serial.print("\t");
  Serial.print(analogRead(A2));
  Serial.print("\t");
  Serial.print(analogRead(A3));
  Serial.print("\t");
  Serial.println();
}

При переходе с опорного напряжения 5В на 1.1В и обратно необходимо порядка 50 пропущенных измерений, что бы данные стали валидными. Я так понимаю это связанно с 100nF на выводе Aref. Не то что это напрягает, но…

Вопрос, как это количество измерений можно уменьшить ?

ИМХО тут или емкость снизить или резистором конденсатор зашунтировать (предположительно 10 кОм)

Может есть вариант разрядить этот конденсатор как то более изящно ?

После того как изменил REF, нужно один раз прочесть и подождать пока зарядится/разрядится конденсатор.

Если бы так просто было…

Про то что первое чтение после изменения опорного напряжения написано в много где…
В том числе в документации, но там ИМХО это описано, если в Aref не подключен конденсатор.

В реальности, что бы конденсатор разрядился до 1.1 надо не одно измерение.
Эксперимент показал, что только после 40 - 50 циклов измерений, данные становятся валидными.

Еще работает вариант, если после переключения опорного напряжения сделать паузу в 25 миллисекунд.

А чем не устраивает 1.0 В датчики мерять на опорном в 5В ?

Я не говорю, что там 1в, я говорю что там до 1в. Это шунт. Сигнал слабый, ставить усилитель ИМХО избыточно. Если опорное не переключить, я получу максимум 200 отсчетов. Очень мало…

Рома, читай внимательно! Ещё раз. В сетапе, после analogReference(A0, INTERNAL); нужно analogRead (с этого момента начинается разряд) и delay;

Два свободных пина, и два транзистора))).

P.S. Два, потому-что не только время , чтобы разрядить, но и чтобы зарядить)))

не надо усилитель ставить. Он уже есть в АЦП. х10, х20, х200( точно не помню,надо ДШ смотреть на МК)

В 328 Атмеге нет. Есть в некоторых Тиньках

в UNO (ATmega328) нет усилителей на АЦП каналах. там только компаратор есть…

не, транзисторы точно не вариант. попробую зашунтировать…

Транзисторы больше как шутка…

Это примерно то же, что уменьшить ёмкость.
Я бы так и сделал. А на 5В добавил, как можно ближе к МК.

1 лайк

Ещё одну ногу подключить к тому конденсатору. В обычном состоянии она настраивается на вход. Когда нужно разрядить - настраивается на выход и LOW и сразу настраивается на вход. Попробуй.

Фу тогда! Надо другой МК)
@roman2712 либо привести к общему знаменателю: сигнал 0-5в привести к 0-1в. Цена вопроса 2 резистора.

1 лайк

Не думаю, что ТС не знает об этом. Возможно, здесь идёт борьба за точность)))

Я бы тогда резистор ~100 Ом добавил, чтобы пин на землю не “коротить”.

При конденсаторе всего в 0.1uf это излишне.

и мега328(да ещё без усилителя АЦП,фу!) понятия несовместимые)) Иначе бы он прикручивал внешний АЦП.

А хотя… может быть ты и прав, надо пробовать.

Да я тоже, наугад сказал, сеичас занят, некогда считать, проще перестраховаться

Весь код не смотрел, нет времени, но здесь ошибка

2 лайка