Аналоговый вход и analogReference(INTERNAL);

Joiner
Offline
Зарегистрирован: 04.09.2014

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

Но.....до того момента, пока в скетче мне ни понадобился внутренний источник опорного напряжения. Т.Е. analogReference(INTERNAL); Ардуинка стала видеть только две кнопки.

Минут десять ломал голову - в чем дело? Догадался. С клавиатуры подается напряжение до пяти вольт, а налоговые входы настроены на напряжение 1.1 вольт.

Вопрос - Опасно ли это для Ардуинки? Возможно ли спалить аналоговый вход, или ни чего страшного?

Спасибо.

Datak
Offline
Зарегистрирован: 09.10.2014

Предельные значения указаны такие:

"Voltage on any Pin except RESET with respect to Ground: -0.5 to Vcc+0.5 V" 

Напряжение на любой ноге кроме RESET, относительно "земли": от -0.5 до Vcc+0.5 В

То есть, обещают что не сгорит, насколько я понял. Но, опять же, если что - я не виноват. :)

 
Joiner
Offline
Зарегистрирован: 04.09.2014

спасибо

А где это указано?

Datak
Offline
Зарегистрирован: 09.10.2014

http://www.atmel.com/Images/doc8161.pdf  (страница 313)

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Пока ни чё не понял по английски, но все равно спасибо. Попытаюсь перевести.

Спасибо

P.S. Подключил клавиатуру через делитель. Полет нормальный :)

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

Joiner, можно было и без делителя обойтись в принципе. Если перед чтением клавиатуры давать команду analogReference(DEFAULT), а потом обратно менять на INTERNAL .

Joiner
Offline
Зарегистрирован: 04.09.2014

Я где-то читал, что при работе с аналоговыми входами (и клавиатура тоже использует аналоговый) требуется какая-то задержка между переключениями, чтобы показания были поточнее. Мне кажется, что времени на все может не хватить. А делитетель работает без каких-либо переключений и как я проверил работает прекрасно. И всего-то всего дополнительно 2 резистора.

А еще, мне кажется есть вариант - подать на клавиатуру напряжение с выхода AREF, тогда вообще без делителя.

axill
Offline
Зарегистрирован: 05.09.2011

Об этом в даташите написано, что после смены референса или канала измерения нужно какое то число тактов подождать для стабилизации, но это совсем не много, delay(50) будет более чем достаточно

Logik
Offline
Зарегистрирован: 05.08.2014

Возможно и так. А в исходниках ардуино (...\arduino-1.0.6\hardware\arduino\cores\arduino\wiring_analog.c) -  ни как.

void analogReference(uint8_t mode)
{
        //..........
	analog_reference = mode;
}

int analogRead(uint8_t pin)
{
.....
#if defined(ADMUX)
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC)); 
....
}

Хоть попытка вписать Delay была, но передумали. Из приведенного кода видно, что делать Delay между установкой опорного напряжения и аналоговым вводом безсмысленно.

Logik
Offline
Зарегистрирован: 05.08.2014

Чем вобще закончилвсь попытка переключения опорного напряжения? А то я себе тоже такое вписал, но ещё не попробовал.

axill
Offline
Зарегистрирован: 05.09.2011

cпециально перечитал даташит, проблемы с переключением референса могут быть только если автотригеры использовать или если это значение менять внутри обработчика прерываний от ADC. Так как analogRead() не использует ни то ни то, то и проблеммы нет

Цитата:
ADMUX
can be safely updated in the following ways:
a. When ADATE or ADEN is cleared.
b. During conversion, minimum one ADC clock cycle after the trigger event.
c. After a conversion, before the Interrupt Flag used as trigger source is cleared.
When updating ADMUX in one of these conditions, the new settings will affect the next ADC conversion.

однако чуть дальше есть рекомендация "выбросить" первое считанное значение после смены опорного напряжения

Цитата:
The first ADC conversion result
after switching reference voltage source may be inaccurate, and the user is advised to discard this result.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Теперь уже попробовал.



         analogReference(INTERNAL); //встроенное опорное напряжение 1.1 В
          //Ucc цена разряда 0.01В
          Ucc=analogRead(ANALOG_INP_V12)*55/32; 
          Serial.println(Ucc);
          Ucc=analogRead(ANALOG_INP_V12)*55/32; 
          Serial.println(Ucc);
          Ucc=analogRead(ANALOG_INP_V12)*55/32; 
          Serial.println(Ucc);
          Ucc=analogRead(ANALOG_INP_V12)*55/32; 
          Serial.println(Ucc);
          Ucc=analogRead(ANALOG_INP_V12)*55/32; 
          Serial.println(Ucc);
          analogReference(DEFAULT);

Выдает в порт при стабильных 0.85В на входе такое

254
343
446
563
660

Выдает при каждом проходе почти стабильно. Хотя я ожидал  что то в раене 1360. 

Вероятно таки нада паузу после установки INTERNAL. Что интересно, после установки DEFAULT все (резистивный тачскрин например) как работало, так и работает, почти сразу без паузы. Вероятно разница внутреннего сопротивления источников опорного напряжения сказывается.

Logik
Offline
Зарегистрирован: 05.08.2014

Победил проблему таким кодом





          analogReference(INTERNAL); //встроенное опорное напряжение 1.1 В
          //Ucc цена разряда 0.01В
          Ucc=analogRead(ANALOG_INP_V12); 
          delay(50);
          Ucc=analogRead(ANALOG_INP_V12); 
          analogReference(DEFAULT);

                  ..........

            X=analogRead(PinX);

 

Без первого Ucc=analogRead не работает. Величену паузы не подбирал, 50 пошло с первого раза.