Прерывание

Marchcat
Offline
Зарегистрирован: 06.05.2012

 Вот и я добрался до прерываний ! Объясните дураку , как в функцию прерывания засунуть таймер который считатет микросекунды с одной смены с LOW на HIGH до другой ! И вывести это время в эфир !

Смотрел много примеров ! Но от них сложновато оттолкнуться !!!(( Хотелось бы с самого начала )))

step962
Offline
Зарегистрирован: 23.05.2011

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

0-16 или
10-2000 или
100-25000 или
1000-30000000 или
... ну и так далее.

А уж потом думать дальше.

Почему?

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

... ну и так далее.

Marchcat
Offline
Зарегистрирован: 06.05.2012

 Допустим обработка сигнала !!! он в диапазоне от 10 до 2000 ..???

leshak
Offline
Зарегистрирован: 29.09.2011

 Заводите две глобальные переменные (не забываем про модификатор volatile). Что-то типа raiseTime и prevRaiseTime.

В обработчике

  1. Копируем значение переменной raiseTime в prevRaiseTime (что-бы не потерять время когда в прошлый раз прерывание возникло).
  2. Запоминаем новое время прерывания в raiseTime (  что-то типа raiseTime=micros())

В loop()

Проверяем, если raiseTime больше нуля и prevRaiseTime больше нуля (значит прерывание вызвалось минимум два раза). Выводим разницу raiseTime-prevRaiseTime и обнуляем их. 

Следующий выводе произойдет когда опять прийдут "два тика". То есть выведется время межну "первым и вторым, третим и четвертым, пятым и шестым".

Если нужно между "первым и вторым, вторым и третьим, треитим и четвертым" - обнуляем только prevRaiseTime при выводе.

Но это все будет "чуток не точно" :) Особенно на микросекундных интервалах. Повыстить точность можно используя аппаратную фичу Capture. Но тут уже "просто для новичка не получится". Либо вчитыватся в даташит в раздел таймеров и фичи Capture, либо нагуглить книгу "Arduino Cookbook" Michael Margolis. Издательство O'REILYY Глава 18.8 "Measuring Pulses More Accurately"

 

 

Marchcat
Offline
Зарегистрирован: 06.05.2012
int pin = 3;
volatile unsigned long raiseTime, prevRaiseTime;
unsigned long T;
void setup (){
  Serial.begin(115200);
  pinMode(pin, INPUT);
  attachInterrupt(0, Time, CHANGE);
}
void Time (){
  raiseTime  = prevRaiseTime ;
  raiseTime = micros();
}
void loop (){
  if (0 < prevRaiseTime & 0 < raiseTime){
    T = raiseTime - prevRaiseTime ;
    Serial.print(T);
    raiseTime = 0;
    prevRaiseTime = 0;
  }}

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну вы-бы хоть пару слов добавили к коду, что это "пример который заработал", пример который не заработал? Если есть проблемы, то "в чем проявляются".

Не беглый взгляд выглядить как вполне грамотная реализация кодом того что я описал словами.

Кроме одного "но" (хотя возможно вы этого и хотели): в строке 7-мь. Нужно не на CHANGE вешатся, а на RISING раз вы хотели "" с одной смены с LOW на HIGH до другой". CHANGE будет дергать обратботчик при любом изменении и LOW на HIGH, и с HIGH на LOW. То есть вы, фактически, начнете замерять длину самого импульса. Или паузу между импульсами, в зависимости от состояния в момент старта.

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

 

Ну, еще, из второспенного: Я бы использовал не print, а println (иначе все же сольется в сериал мониторе). Ну и условие в строке 14 можно короче записать: if(prevRaiseTime & raiseTime)

В C/C++ любое значение переменной отличное от нуля воспринимается как "истина", поэтому сравнение с нулем - можно опустить (или оставить, по собственному вкусу. как лично вам код более понятным-красивым кажется)

Marchcat
Offline
Зарегистрирован: 06.05.2012

 Код поправил ! Но все равно в Сериал ни чего не идет ((

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну еще можно & (битовый оператор) заменить на && (логический оператор). По идее тут и "битовый должен прокатить", но лучне не превыкать их путать.

ну а дальше - уже на подключение смотреть.

Например есть сильное подозрение что вы все это дело подключили на третий  цифровой пин.

Почитайте http://arduino.ru/Reference/AttachInterrupt какой пин соотвествует нулевому прерыванию.

 

Vanovich
Offline
Зарегистрирован: 16.05.2012

 Почему происходит зависание программы при отправке символа "z" в порт?
 

void setup()
{
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  attachInterrupt(0, handler, RISING);
}
void loop()
{
  Serial.println("loop");
  if(Serial.read()==122)
    digitalWrite(2, HIGH);
}
void handler()
{
  Serial.println("INT");
  digitalWrite(2, LOW);
}

 Если строку 09 закомметировать, то все работает.
Это скетч абстрактный, написан для описания проблемы. В реале столкнулся с проблемой записи данных в порт, получаемых в обработчике прерывания  

step962
Offline
Зарегистрирован: 23.05.2011

 А реальный скетч не можете представить?

Прерывание INT0, к которому вы цепляете обработчик, "слушает" пин PD2 (или 2 в терминах Arduino). Этот же пин вы определяете как выход. Непоследовательно как-то...

Vanovich
Offline
Зарегистрирован: 16.05.2012

 Прерывание 0 слушает пин 2, так? Определив его как выход, я программно меняю его состояние на HIGH командой digitalWrite, что вызывает вызов обработчика. Чего тут непоследовательного? Реальный скетч картины не изменит. Прошу пояснить именно указанную проблему. Возможно, разобраться поможет еще тот факт, что добавление задержки в loop делает скетч работоспособным...
 

void setup()
{
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  attachInterrupt(0, handler, RISING);
}
void loop()
{
  Serial.println("loop");
  if(Serial.read()==122)
    digitalWrite(2, HIGH);
  delay(10);
}
void handler()
{
  Serial.println("INT");
  digitalWrite(2, LOW);
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

>Прерывание 0 слушает пин 2, так

А зачем же, тогда вы второй пин на OUTPUT включили?

Ну и прочитайте документацию на фунцию attachInterrupt внимательно. Особенно выделенный раздел "Замечание по использованию". Одно из двух "нельзя", вы все-таки сделали.

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Когда начинает выполняться обработчик прерывания (любой) глобальные прерывания (все прерывания) временно запрещаются. Как только он отработает прерывания разрешаются опять. Для выполнения Serial.println("INT") нужны разрешенные глобальные прерываня, а они как раз запрещены так как выполняется обработчик прерывания. Поэтому программа зависает как только начинает выполняться обработчик. Вобщем Serial.print использовать в обработчике прерывания нельзя.

leshak
Offline
Зарегистрирован: 29.09.2011

 Кстати, не знаю, переключает-ли, внутри себя, attachInterrupt пин на вход. Но если не переключает, то в зависимости от схемы подключения, можно выпалить ногу, или весь камень. Если вы пину включенному на выход, начнете подавать импульсы без ограничения по току.

А вообще, как-то диже странно вы пользуете второй пин. Вы все-таки решите вы хотите его "как вход" или "как выход".

Если цель была "потестировать", то сделай второй на Input, а, к примеру пятый, на Output. Соедините эти два пина проводком (но после того как зальете скетч) и делайте свой digitalWrite(5,HIGH)

leshak
Offline
Зарегистрирован: 29.09.2011

Evgen пишет:

Вобщем Serial.print использовать в обработчике прерывания нельзя.

Вы не поверите, но именно это и написанно в документации :) 

Просто хотелось что-бы человек сам нашел-прочитал. Глядишь и еще чего полезного узнает. Например про volatile. Оно тоже пригодится.

Vanovich
Offline
Зарегистрирован: 16.05.2012

Понятно, спасибо. Но откровенно говоря, не могу понять, как же работает пример по приведенной ссылке:

int pin = 13;
volatile int state = LOW;
 
void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}
 
void loop()
{
  digitalWrite(pin, state);
}
 
void blink()
{
  state = !state;
}

Здесь используется прерывание 0, которое слушает пин 2. А где в программе вообще фигурирует этот пин...Тут ведь в 13-й пин digitalWrite идет...И еще. А почему здесь такая же логика - digitalWrite в пин, настроенным как OUTPUT, а вроде как все верно и никто не грозит сожжением камня? Простите за возможную наивность, но все мы же в любом случае были новичками и задавали неудобные вопросы :)

step962
Offline
Зарегистрирован: 23.05.2011

Vanovich пишет:

Понятно, спасибо. Но откровенно говоря, не могу понять, как же работает пример по приведенной ссылке:

[...]

Здесь используется прерывание 0, которое слушает пин 2. А где в программе вообще фигурирует этот пин..

Этот пин "фигурирует" не в программе, а в железе. Прерывание INT0 жестко связано с выводом PD2 микроконтроллера. Все, что вы можете сделать - либо использовать этот вывод в качестве обычного ввода/вывода, запретив (не инициализировав) прерывание INT0, либо написать обработчик этого прерывания, разрешить это прерывание и - слушать, слушать, слушать изменения сигналов на выводе PD2...

Есть еще третий вариант использования этой ноги, но о нем лучше пока не заикаться.

 

Vanovich
Offline
Зарегистрирован: 16.05.2012

 Хорошо. Где в приведенной программе происходит изменение состояния PD2? Вернее, в "железе"? Что здесь меняет состояние PD2?

Вот тот скетч, который не работает:

#include <I2Cdev.h>
#include <Wire.h>
#include <ADXL345.h>
#include <TimerOne.h>

ADXL345 accel;
int16_t ax, ay, az;

void setup()
{
  Serial.begin(38400);
  // initialize device at 100 Hz; +- 2G Range
  Serial.println("Initializing I2C devices...");
  accel.initialize();
  accel.setRate(ADXL345_RATE_100);
  accel.setRange(ADXL345_RANGE_2G);
  delay(1000);
  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed");
  // initialize timer at 100 Hz
  Timer1.initialize(10000);
  Timer1.attachInterrupt(ISR_handler);
}

void loop()
{
     Serial.print("raw data:\t x \t");
    Serial.print(ax); 
    Serial.print("\t y \t");
    Serial.print(ay); 
    Serial.print("\t z \t");
    Serial.println(az);
}

void ISR_handler()
{
    accel.getAcceleration(&ax, &ay, &az);
}



Задача - опрашивать датчик акселерометра с определенной частотой. Опрос реализуется в обработчике по таймеру. Программа виснет уже на выводе первого сообщения в порт (Initializing)

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

В программе не происходит изменение состояния PD2, это делает подключенная к этой ноге кнопка :) Любой пример состоит из программной и железной части, вторую, кажется, Вы проигнорировали.

Vanovich
Offline
Зарегистрирован: 16.05.2012

AlexFisher пишет:

В программе не происходит изменение состояния PD2, это делает подключенная к этой ноге кнопка :) Любой пример состоит из программной и железной части, вторую, кажется, Вы проигнорировали.

Спасибо, да, так и есть. А разве в этом случае не должно стоять инструкции pinMode(2, INPUT)?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Все входы по умолчанию настроены на вход. Поэтому эта инструкция излишна.

step962
Offline
Зарегистрирован: 23.05.2011

1) А вы можете в ручном режиме что-нибудь от акселерометра получить?

2) Сообщение "Testing device connections..." вы уже не получаете?

Vanovich
Offline
Зарегистрирован: 16.05.2012

 1) и 2) - да
Появляются буквы Ini.....и привет

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

step962 пишет:

1) А вы можете в ручном режиме что-нибудь от акселерометра получить?

2) Сообщение "Testing device connections..." вы уже не получаете?

Это вы о чем? Мы тут про прерывание... Если сообщение было давно, то хоть цитируйте...

Vanovich
Offline
Зарегистрирован: 16.05.2012

AlexFisher пишет:

step962 пишет:

1) А вы можете в ручном режиме что-нибудь от акселерометра получить?

2) Сообщение "Testing device connections..." вы уже не получаете?

Это вы о чем? Мы тут про прерывание... Если сообщение было давно, то хоть цитируйте...

Да о нем и речь..пост #17 посмотрите

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Vanovich пишет:

Да о нем и речь..пост #17 посмотрите

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Vanovich пишет:

Да о нем и речь..пост #17 посмотрите

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Vanovich пишет:

Да о нем и речь..пост #17 посмотрите

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Vanovich пишет:

Да о нем и речь..пост #17 посмотрите

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Извините, канал глючил :(

Marchcat
Offline
Зарегистрирован: 06.05.2012

 у меня вот такой сигнал :

 

на осциле с антены ! подключаю к ардуине ну не как она не хочет принимать сигнал ( 11000 ) (((

Подскажите начинающему через какие процедуры можно arduino адаптировать к моей антене !\

Частота аля Rfid 125Khz. логический 0 длится от 140 до 180 мкс . Единица от 200 до 260 мкс.

 

carduino.ru
Offline
Зарегистрирован: 06.12.2011

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

Marchcat
Offline
Зарегистрирован: 06.05.2012

 В м чем ошибка :

#define r 3 
volatile unsigned int time,oldtime,count;
byte data[8];
void setup(){
  pinMode(r,INPUT);
  attachInterrupt(1,pinint,RISING);
  Serial.begin(115200);
  Serial.println("Analizator pcf 7936");
  interrupts();
}
void pinint(){
     oldtime = time;
     time=micros()-oldtime;     
    if(time <=140 && time >= 180)savebit(false);
    else if(time <= 200 && time >= 260)savebit(true);
    else{
      count=0;
     }
   }
void savebit(boolean val){
  for(int i=1;i<=8;i++){
    data[i]=data[i]<<1;
    if(i<8)if(bitRead(data[i+1],7))bitSet(data[i],0);
  }
  if(val)bitSet(data[8],0);
  count++;
  if(count == 5){
    Serial.print("Pcf 7936 ");
    for(int i=1;i<=8;i++)printhex(data[i]);
    Serial.println("");
  }
}
void printhex(byte val){
 if(val<=0x0F)Serial.print("0");
  Serial.print(val,HEX);
}
void loop(){
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

 2Marchcat : а можно поинтересоваться что за устройство вы собираете? Что оно должно делать?

Marchcat
Offline
Зарегистрирован: 06.05.2012

 оно должно логировать обмен данных ! для проверки правильности работы !!!

Marchcat
Offline
Зарегистрирован: 06.05.2012

 2leshak Можно както с вами связаться ( icq , skype. )

leshak
Offline
Зарегистрирован: 29.09.2011

Диклаймер: все что будет ниже - сугубо мои домыслы. Просьба не обижатся если я "попал пальцем в небо".

Я понял что "оно должно логгировать". Вопрос был "что за устройство?". Какова область применения?

Выражусь по другому: у меня сложилось впечатление что речь идет о каком-то снифере автосигнализаций или работе с ключами для pegeot 308 и 4008  (машине примерно 4-ре месяца ;)

Если мое впечателние не ложное, то, даже если ваши помыслы "кристально чисты" и все это не более чем "исследовательский зуд" или вполне легальная работа с собственным автомобилем, не хотелось-бы что-бы подобные темы/контент были на этом сайте.

Сами понимаете - слишком уж велик соблазн, для неокрепших умов, начать изучение микроконтроллеров именно с этого подраздела :)

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

>2leshak Можно както с вами связаться ( icq , skype. )

Можете написать сюда

void setup(){
  Serial.begin(9600);
  Serial.print("alxarduino");
  Serial.print("@");
  Serial.println("gmail.com");
}

void loop(){}

Но, к сведению:

  • Бесплатные консультации: я даю только на форуме.
  • Работа за деньги:  проекты типа "грабер сигнализации" и т.п. - даже обсуждать не буду.
Marchcat
Offline
Зарегистрирован: 06.05.2012

 2Leshak я ват отправил письмо !!!

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Даже не знаю как сформулировать...

В общем, при нажатии кнопки или срабатывании энкодера в обработчике прерывания выставляется соответствующий флаг (какая кнопка нажата или в какую сторону повернут энкодер). Все, больше в этом обработчике ничего нет.

А вот дальше этот флаг надо немедленно передать в функцию X, которая что-то там делает - выводит нужное меню или выполняет действие, назначенное на кнопку.

Но ведь при завершении прерывания работа программы продолжается с того места, где было прерывание. И по loop до этой функции X когда еще доберемся - там и чтение десятка датчиков и прочее - задержка может быть до 2-х секунд.

А вызов этой функции прямо из обработчика будет являться неправильным, ведь пока функция не выполнится, прерывание будет считаться незавершенным, так?





void readButton() {
flagButtonX = true;
inputHandler (flagButtonX);  // в прерывании вызывать другие тяжелые функции - это плохо.
}

Как можно по завершении прерывания максимально быстро передать управление функции X, а уж потом продолжить loop?

Vlad_Juika
Offline
Зарегистрирован: 15.07.2014

Ребят, помогите с проблемой. Выполняется прерывание по 3 pin через кнопку (с обвязкой через резистор). Как только в программе срабатывает реле(на 220В прибор включен) или в других розетках (параллельных на 220) вкл/выкл прибор выполняется прерываение без помощи кнопки. Почему? Заранее благодарен!

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Кондёрчик 10 -100 нан  повесьте на 3 пин... Не поможет- резистор привязки на 1 килоом поставьте...

ИгорьУ
Offline
Зарегистрирован: 24.04.2016

Подскажите пожалуйста. Работаю с  прерыванием. Функция delay() в основной прграме перестает работать. Что делать, как организовать контролируемые задержки в програме. Я уже и такое чудо пробовал while((millis() - oldTime)<=1000)  {} так милис тоже не работает. И вообщем получается чтоб пользоваться этими функциями необходимо отключать прерывание  функцией detachInterrupt(1); Или делать задержку какой то рутиной?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ИгорьУ пишет:

как организовать контролируемые задержки в програме. 

никак - тебе этого не нужно будет делать, если ты поймёшь, что вместо

while(millis() - oldTime <= 1000)  {} 

можно использовать

if (millis() - oldTime <= 1000)  {/*здесь что-то происходит, когда "задержка" действует*/} 
// и/или
if (millis() - oldTime >  1000)  {/*здесь что-то происходит, когда "задержка" перестала действовать*/} 
ИгорьУ
Offline
Зарегистрирован: 24.04.2016

Клапауций 112 пишет:

if (millis() - oldTime <= 1000)  {/*здесь что-то происходит, когда "задержка" действует*/} 
// и/или
if (millis() - oldTime >  1000)  {/*здесь что-то происходит, когда "задержка" перестала действовать*/} 

Это равносильно. Главное что милис как и дилай могут не работать когда задействованы прерывания. И это уже интересно. В каких случаях и почему? Конечно можно создать рутину, замерить ее время выполнения ардуиной а затем использовать как эталонную, но это конечно костыли. При том что прерывания тоже внесут коррекцию в скорость роботы рутины.

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

ИгорьУ пишет:

милис как и дилай могут не работать когда задействованы прерывания. 

Кто Вам это сказал? И что Вы понимаете под выражением "задействованы прерывания"? Вы что в них безвылазно по часу сидите? Показыватке код, без кода - это болтовня в пользу бедных.

Только по возможности короткий код, который работает и демонстрирует проблему. А то тут часто проблема в каком-нибудь локальном преобразовании типа, а код как вывалят на тыщщу строк со всеми там опросами датчиков и выводами в эти ваши народные мониторинги. По возможности подготовьте короткий пример иллюстрирующий Вашу проблему.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

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

Кто Вам это сказал? 

та, это свидетели церкви Святого Цикла - фанатики.

ИгорьУ
Offline
Зарегистрирован: 24.04.2016

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

Кто Вам это сказал? И что Вы понимаете под выражением "задействованы прерывания"? Вы что в них безвылазно по часу сидите? Показыватке код, без кода - это болтовня в пользу бедных.

Хуже не то что они вообще не работают а то что они как то странно то работают то нет, вообщем есть муха. Чтобы упростить приведу самый простой случай из того что я пробовал. Замечу у меня нет опыта в рабое с прерываниями на ардуине, так что не судите. Но не в этом суть.

Задача ставилась постоянно измерять напряжение на аналоговом входе. Поэтому додумался применить прерывания. Взял прерывание 1. И загнал на диджитал ножку 3 LOW и в инициацию прерывания тоже LOW чтоб все время срабатывала. К самой ножке ничего не подключал.  Вот тривиальный скеч.

byte VoltadeSensorPin =2;
byte DigitalPin    = 3;
volatile int Voltage;
 
void setup()
{
    pinMode(DigitalPin, INPUT);
   digitalWrite(DigitalPin, LOW);
 
   attachInterrupt(1, voltagemesure, LOW);
    Serial.begin(9600); 
}
void loop()
{
 Serial.println (Voltage);
  digitalWrite(DigitalPin, LOW);
 delay(1000); 
 }
 
void voltagemesure()
{Voltage=analogRead(VoltadeSensorPin);} 

И все хороше работает, меряет напряжение и выводит на экран через секунду, пока на диджитал ножку 2 (это уже прерывание 0) не попадает сигнал от датчика Холла. Вот просто так стал крутить прибор случайно подключенный к ножке 2 и на экране все поползло как будто дилей вовсе нет. Перестает попадать сигнал, опять все хороше. Все остальные случаи просто производные от этого. 

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

На этом форуме строго обязательно - http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

ИгорьУ пишет:

Взял прерывание 1. И загнал на диджитал ножку 3 LOW и в инициацию прерывания тоже LOW чтоб все время срабатывала. К самой ножке ничего не подключал.

Ваша ножка работает антенной и ловит все помехи, какие мимо пролетают. Если Вы (вместо включения другой части схемы) просто поднесёте к ней палец, то тоже увидите много интересного.

Если Вам надо, чтобы она всегда была LOW, соедините её резистором в 1 килоом с землёй. Тoлько всё время срабатывать она всё равно не будет. Прерывание срабатывает при переходе из одного состояния в другое, а не "всё время".

ИгорьУ пишет:
Задача ставилась постоянно измерять напряжение на аналоговом входе. Поэтому додумался применить прерывания.
И напрасно. Для постоянного измерения есть специальный режим АЦП - называется "Free Running". Вы не написали, что у Вас за контроллер. Если 328P, то см. раздел 24 (стр. 237) даташита.

 

 

ИгорьУ
Offline
Зарегистрирован: 24.04.2016

Спасибо Евгений за замечания и советы. Нашел пример на Инте как войти в режим Free Running    https://github.com/VinnieM-3/Arduino/blob/master/ADC_FreeRunning.ino. Прграма действительно работает и измеряет постоянно напряжение. Разбираюсь Пока мутновато, потому что все это как-то сложно организовано.

Когда завел на 3 ногу землю тоже все работает

Теперь сижу и думаю как лучше

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

delay & millis  дуреют, когда не срабатывает прерывание от Timer0.  Например, прерывания запрещены.  А они запрещены, когда выполняется обработчик другого прерывания, если на входе мануально sei() не скажешь.