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

У меня есть схема, подключенная следующим образом

Мои концевые выключатели, прикрепленные к моей конструкции, иногда срабатывают ложно, поэтому я написал этот код, чтобы решить эту проблему. Мой двигатель должен опуститься, пропустив верхний концевой выключатель, сначала нажмите нижний, а затем вернитесь к верхнему. это хороший способ реализовать это? https://pastebin.com/qVU1Gp0q

//Переключатель нажат -> чтение ВЫСОКОЕ
//Переключатель не нажат -> чтение НИЗКОГО
//Направление двигателя 0 — вниз, 1 — вверх

const int uplimit = 32;
const int downlimit = 34;
const int motorspeed = 9;
const int motordirection = 28;
//const int pumpspeed=5;
//const int pumpdirection=6;
const int motorenable = 26;
//const int pumpenable=;
int Finishedcleaning = 0;
int Reachedup = 0;
int Motorinitialsetup = 0;
int Motorsecondsetup = 0;
int downfiltered = 0;
int upfiltered = 0;
void setup() {
  // поместите сюда свой код установки для однократного запуска:

  pinMode(motorspeed, OUTPUT);
  pinMode(motordirection, OUTPUT);
  pinMode(motorenable, OUTPUT);
  //pinMode(скорость насоса, ВЫХОД);
  //pinMode(pumpenable, OUTPUT);
  pinMode(uplimit, INPUT);
  pinMode(downlimit, INPUT);

}

void loop() {
  // поместите сюда свой основной код для многократного запуска:
  int average1 = 0;
  int average2 = 0;
  if (Motorinitialsetup == 0 ) // запуститься до нажатия начального переключателя
  { digitalWrite(motorenable, HIGH);
    analogWrite(motorspeed, 190);
    digitalWrite(motordirection, 0); // Остановить двигатель
    // digitalWrite(pumpenable,HIGH);
    // digitalWrite(pumpdirection,1);
    // AnalogWrite(pumpspeed,240);
    Motorinitialsetup = 1; //так что этот оператор if больше не запускается

  }

  for (int i = 1; i < 100; i++)
  { downfiltered = digitalRead(downlimit);
    average1 = average1 + downfiltered;
  }
  average1 = average1 / 100;

  if ((average1 > 0.9) && Finishedcleaning == 0 ) // Функция после нажатия переключателя
  {
    delay(1000); // ждем, пока мотор переключится
    analogWrite(motorspeed, 0); // остановка двигателя
    Finishedcleaning = 1; //указываем, что очистка окончена для следующего цикла
    delay(500); // ждем, пока мотор переключится
  }

  if ( (Finishedcleaning == 1) &&   (Reachedup == 0)  && (Motorsecondsetup == 0))
  {
    digitalWrite(motordirection, 1); // реверс направления двигателя
    analogWrite(motorspeed, 190); // снова запускаем двигатель
    Motorsecondsetup = 1;
  }


  if ( Motorsecondsetup == 1) // проверяет переключатель включения только после возобновления работы двигателей
  {

    for (int i = 1; i < 300; i++)
    { upfiltered = digitalRead(downlimit);
      average2 = average2 + downfiltered;

    }
    average2 = average2 / 300;
    if ((average2 > 0.9) && (Finishedcleaning == 1)) // Остановка двигателя после возврата
    { analogWrite(motorspeed, 0);
      delay(1000);
      Reachedup = 1; // указываем завершение возврата после цикла очистки
    }
  }
}


, 👍3

Обсуждение

Начните с повышения консистенции и качества. Почему у одного переключателя есть понижающий резистор сопротивлением 220 Ом, а у другого — 4 кОм? В вашем эскизе отступы и скобки повсюду. Попробуйте нажать ctrl+t в Arduino IDE. Пожалуйста, опишите словами, как вы хотите фильтровать всплески, прежде чем помещать это в код. В вопросе укажите, пожалуйста, сам эскиз, а не ссылку., @Jot

У них обоих 4к7. Кроме того, я использовал Pastebin для кода, потому что он имеет форматирование C. Я хочу отфильтровать его, взяв среднее цифровое показание по 100 точкам, чтобы убедиться, что оно действительно высокое., @hamad

@Jot Я добавил код в сообщение., @hamad

Это может быть и проводка. Шум двигателя может вызвать подачу сигнала на проводку концевого выключателя. В этом может помочь конденсатор, включенный параллельно каждому концевому выключателю., @sa_leinad

@sa_leinad Я думал, что конденсатор должен быть включен последовательно с резистором RC-фильтра? тогда я мог бы взять выходной сигнал с конденсатора? поскольку конденсатор представляет собой короткое замыкание на высокой частоте, это даст мне 0 вольт?, @hamad

Мне жаль говорить, что у вас неправильная проводка. Вот только одна ссылка https://electronics.stackexchange.com/q/237938/104097. Еще больше, если вы погуглите «переключить конденсатор для устранения дребезга»., @sa_leinad


1 ответ


1

Оборудование:

У вас есть переключатель на 5 В с понижающим резистором.
При использовании более длинных проводов или когда все сложено в коробку, возможно, безопаснее использовать провод GND к переключателю (с подтягивающим резистором) вместо провода 5 В. Если переключатель или кнопка подключены с помощью экранированного кабеля, лучше соединить один контакт переключателя с GND.

Если вы измените переключатель и подключите один контакт к GND с помощью подтягивающего резистора, вам также придется изменить скетч, потому что при нажатии переключателя контакт станет НИЗКИМ.

Вы можете добавить конденсатор емкостью от 1 до 100 нФ между цифровым входом и заземлением. Это поможет избежать скачков напряжения и шума.

Понижающие резисторы номиналом 4 к7 — это высокое значение для шумной среды. Я предлагаю использовать резисторы сопротивлением 470 Ом или 1 кОм.

Наземный путь очень важен. У вас есть GND драйвера двигателя, подключенный к макетной плате, и именно туда подключаются переключатели. Это означает, что вход (переключатели) и выход (драйвер двигателя) имеют общий заземляющий провод. Всегда избегайте подобных ситуаций.
Макетные платы часто имеют плохие контакты. Если земля на макетной плате не очень прочная, то вы вводите на входные контакты шум от выходных контактов платы Arduino.
Используйте две отдельные макетные платы для ввода и вывода. Или подключите GND драйвера двигателя непосредственно к плате Arduino.

Программное обеспечение:

Целое число не может быть равно 0,9, поэтому ваш фильтр не работает.

Функция digitalRead() возвращает HIGH или LOW. Вы добавляете эти значения, но я предпочитаю придерживаться ВЫСОКОГО или НИЗКОГО.

Хорошей идеей является взятие нескольких образцов и установление порогового значения. Вам действительно нужно 100 или 300 образцов? Кнопка может подпрыгивать в течение 10 мс, поэтому я предлагаю использовать около 20 сэмплов в течение 20 мс.

int digitalReadFiltered(int pin) {
  int result;
  const int n = 20;                // максимум 30
  int count = 0;                   // целое число может содержать 30 аналоговых выборок

  for (int i = 0; i < n; i++) {
    if (digitalRead(pin) == HIGH) {
      count++;
    }
    delay(1);        // 1 мс для выборки в течение 20 мс с 20 выборками
  }

  if (count > (n / 2)) {
    result = HIGH;   // насчитали достаточно ВЫСОКИХ значений
  } else {
    result = LOW;
  }

  return(result);
}

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

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

Когда кнопка не нажата, резистор удерживает входной контакт на низком (или высоком) уровне. Тогда электрический шум может вызвать всплески.

Цепь с низким импедансом меньше подвержена влиянию электрических шумов. Чем меньше номинал резистора, тем меньше проблем с шумами.

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

Понижающий (или повышающий) резистор номиналом 10 кОм можно использовать, когда к нему не подключены провода, выходящие за пределы печатной платы. Когда есть кнопка с проводами, то я бы предложил меньшее значение, например 2к2 или 4к7. Поскольку у вас проблемы с шумом, я предлагаю значение 470 Ом или 1 кОм.

,

Спасибо, это очень хороший и подробный ответ. Будут ли какие-либо опасения по поводу использования вместо этого конденсатора емкостью 47 мкФ просто для безопасности? Кроме того, я думаю, что мой фильтр работает, просто заменяя целое среднее на двойное среднее, или вы это хотели сказать?, @hamad

Также могу ли я спросить, почему более высокое сопротивление увеличивает шум? Я думал, что будет наоборот, если у меня будет (V+v_n)/R = V/R +vn/R, а vn/R будет равен нулю для высоких значений R, таким образом, будет менее шумный ток с высоким сопротивлением?, @hamad

Использование числа с плавающей запятой (в Arduino Uno нет двойного значения) для среднего значения также должно работать, но тогда вы все равно добавляете HIGH + HIGH + HIGH, я думаю, что это странно. Конденсатор емкостью 47 мкФ кажется слишком большим. Добавлю абзац к своему ответу про резистор., @Jot