Аппаратное прерывание срабатывает случайным образом

Итак, есть довольно общая часть моего проекта, которая включает в себя запуск ISR, который переворачивает логическое значение. Я настроил программную часть следующим образом:

void setup() {
  attachInterrupt(digitalPinToInterrupt(2), displayConvergence, FALLING);
}

void loop() {
  if(flashConvergence) {
    //Делаем то, что занимает несколько секунд
    delay(3000);
    flashConvergence = false;
  }
}

void displayConvergence() {
  if (!flashConvergence) {
    flashConvergence = true;
  }
}

Схема выглядит следующим образом:

схема

Но поведение моей схемы меня удивило, так как прерывание контакта срабатывало случайным образом с частотой (примерно здесь) 3 раза в секунду.

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

Я изменил схему, добавив конденсатор на переключатель:

схема

Сначала я попробовал 1 мкФ, но это не помогло, как и 10 мкФ. Однако, когда я попробовал 100 мкФ (я думал, что развязывающие конденсаторы обычно имеют емкость от 0,1 мкФ до 1 мкФ, не слишком ли велико значение, которое я использую?), все работает, как и ожидалось, за исключением того, что когда я держу переключатель в замкнутом положении положении в течение длительного времени, затем дайте ему вернуться в открытое положение, служба прерывания может быть запущена случайным образом на короткий период сразу после того, как я отпущу переключатель.

Правильно ли мое первоначальное предположение, что ISR срабатывает случайным образом из-за электромагнитных помех от повышающего преобразователя? Возможно, есть другие причины, которые я не рассматриваю? Есть ли способ заставить эту работу работать на 100% (например, решить проблему сразу после того, как переключатель будет переведен в открытое положение)?

Спасибо за помощь!

, 👍0

Обсуждение

Вы можете попробовать; опускание подтягивающего резистора. Отодвиньте кнопку от повышающего преобразователя и его проводов. Переместите подтяжку ближе к контакту 2. Используйте систему подтягивания (поменяв местами R1 и SW1) вместо подтягивания. PS конденсатор здесь используется не для развязки, а как фильтр нижних частот., @Gerben

Почему вытягивающая система имеет большую помехозащищенность, чем вытягивающая?, @Alex H

Я не уверен, что это так, но, возможно, стоит попробовать., @Gerben

Преобразователи Buck-Boost довольно шумные. Если прерывание запускается случайным образом, даже если вы даже не касаетесь переключателя, это означает, что какой-то шум определенно вызывает проблему. Если у вас есть осциллограф, вы можете подключить его к D2, чтобы увидеть, что происходит. Попробуйте добавить 100 мкФ и 0,1 мкФ колпачок на 5 В, прежде чем он подключится к схеме Arduino., @Fahad

Я думаю, что если вы хотите только перевернуть значение логического значения, попробуйте использовать это только в ISR «flashConvergence = !flashConvergence;» это сэкономит массу места и будет менее сложным., @Shams M.Monem


3 ответа


Лучший ответ:

1

Мне стало известно, что я никогда не писал об этом, но на самом деле я смог решить эту проблему, экранировав провод, идущий от коммутатора к Arduino. Провод переключателя был длиной от 2 до 3 дюймов, и я обернул его алюминиевой фольгой, которая защитила сигнал от того, что, как я подозревал, было вызвано электромагнитными помехами, вызванными переключающими преобразователями.

Защита от электромагнитных помех для бедняков

,

-1

Альтернативный подход — отключить обработчик прерывания и использовать внутренний подтягивающий резистор вместо внешнего резистора (и конденсатора).

const int BUTTON = 2;
volatile bool flashConverage = false;

void setup() 
{
  setmode(BUTTON, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON), displayConvergence, FALLING);
}

void loop() 
{
  if (!flashConvergence) return;

  // Делаем то, что занимает несколько секунд
  delay(3000);
  flashConvergence = false;
  attachInterrupt(digitalPinToInterrupt(BUTTON), displayConvergence, FALLING);       
}

void displayConvergence() 
{
  detachInterrupt(digitalPinToInterrupt(BUTTON));
  flashConvergence = true;
}

Обработка ("вещи, которые занимают несколько секунд") устранят дребезг кнопки (или, по крайней мере, проигнорируют ее :).

Ура!

,

Проблема не (только) в дребезге переключателя. Это ложные срабатывания. Этот код не поможет с этим., @Gerben

Итак, мы предоставили несколько решений для тестирования. Я согласен, что шум от преобразователя может быть проблемой. Также может помочь перемещение конденсатора на 100 мкФ для фильтрации шума при питании (5 В)., @Mikael Patel


0

Если у вас нет большой емкости (100 мкФ или около того) на блоке питания логики, у вас будут проблемы с шумом. Вы также должны использовать меньше (1 мкФ и 0,1 мкФ), чтобы обеспечить обход высокочастотного шума в системе питания.

Гленн

,