Не получается инициализировать несколько датчиков одновременно для ардуинки

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Так ADMUX надо переключать в прерывании, а не в loop()

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

Да я и в прерывании пробовал переключать. Не работает и все. Зато analogRead() работает прекрасно и с A0, и с A1, адекватно отображая поочередно показания с обеих портов. И я подозреваю, что analogRead() работает не от внешнего АЦП, который незримым образом подключен с центра Вселенной к микроконтроллеру. Мне из любопытства хочется узнать, как в кастомном analogRead() настроено АЦП, может кто подсказать, пожалуйста, как и где можно найти библиотеку для этой функции?  Где-то в папках Arduino или скачать нужно, но откуда?  

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

Ух ты. К пятидесятому сообщению пришла мысль что надо в святцы заглянуть? В программ файлс папка ардуино поискать файл начинающийся c analog.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Snova_Sumerki пишет:

  Где-то в папках Arduino или скачать нужно, но откуда?  

Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_analog.c

Если убрать не относящееся к атмеге 328 то получится

int analogRead(uint8_t pin)
{
	uint8_t low, high;
	pin = analogPinToChannel(pin);

	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).

	ADMUX = (analog_reference << 6) | (pin & 0x07);

	// start the conversion
	sbi(ADCSRA, ADSC);

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

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;

	// combine the two bytes
	return (high << 8) | low;
}

 

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

Спасибо большое, позже попробую разобраться) 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Snova_Sumerki пишет:

Спасибо большое, позже попробую разобраться) 

Чего там разбираться? Все просто как 3 копейки. Да, для справки, что такое sbi()

 

#define sbi(port,bit) 	(port) |= (1 << (bit)) 
Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

sbi я знаю, что такое, просто фрагмент кода с переключением между портами не понял пока

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

А что может быть непонятного в

ADMUX = (analog_reference << 6) | (pin & 0x07);

?

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

Не знаю, analog_reference - это же опорное напряжение, вроде.. почему тут сдвигают 6 битов влево? pin & 0x07 - это начало чтения с A0 пина, почему между analog_reference и pin & 0x07 стоит или?... какой-то темный лес, по-моему я не туда забрел

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

а, я понял, это установка опорного напряжения + установка начального пина, а где переключение между ними? 

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

Пин может быть от нуля до семи, соответственно вход A0-A7

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

Snova_Sumerki пишет:

Я написал чистую программу для работы с несколькими каналами, ничерта не работает. 

Я Вас просил сделать это вчера. Помните? Вчера я мог бы посмотреть на неё, попробовать и т.п. Сегодня не могу. Смогу, возможно, вечером или завтра/послезавтра. Вас устраивает? Или будет слишком поздно? Напишите, а то без пользы мне тоже не хочется фигнёй страдать.

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

Нет, будет поздно. Мне надо принципиальную схему дорисовать и сдать уже. Все равно спасибо за помощь.

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

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

А так, надо было вчера скетч выкладывать, когда я просил :(

Snova_Sumerki
Offline
Зарегистрирован: 04.01.2020

Ну да, не отличник. Да тему можно клоз, я уже сделал, все получилось! Всем спасибо! Все дело в обработчике прерываний неправильно настроенном, выкладываю код для страждущих, кто забредет случайно сюда в поиске решения для подобной проблемы: 

 

volatile bool trueValue = false;    //Для пропуска первой после переключения портов обработки
                                  
ISR(ADC_vect) {
  if (trueValue) {
   int result = ADCH;          //Записываем первые восемь бит ADCH, 2 шумных из ADLR отсекаем      
    if (analogPin == A0) {            
      value1 = result;
    }
    if (analogPin == A1) {
      value2 = result;
    }
    if (analogPin == A2) {
      value3 = result;
    }

    analogPin += 1;                   // Перебираем входные пины по кругу (А0...А1 - их может быть больше)
    if (analogPin > A2) {             // Все нужные перебрали...
      analogPin = A0;                 // ...возвращаемся к первому
    };

    int pin = analogPin;              // Приводим пин вида A0 (14) к удобному для регистра ADMUX - 0. A0=14, A1=15, ...
    if (pin >= 14) pin -= 14;

    ADMUX = analog_ref | (pin & 0x07);  // Устанавливаем новый вход для преобразования
    trueValue = false;                  // Устанавливаем флаг смены входного пина - следующее прерывание пропускаем
  }
  else {
    trueValue = true; // Первый раз пропускаем считывание и устанавливаем флаг на чтение в следующий раз
  }
  ADCSRA |=(1<<ADSC); //запускаем преобразование снова (для Single Conversion Mode, см. Datasheet Atmega 328b
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

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

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

Та ладна, здесь вроде нормально все, сам шукает, ток направление просит подсказать. Все мы не святые, иногда и забывали на занятие прибыть, а искали в тех же, чужих конспектах.))))

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

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

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

А так, надо было вчера скетч выкладывать, когда я просил :(

Хорошие преподаватели двойки не ставят, они ставят колы, их легче исправлять на 4-ки )))

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