Подсчет количества ВОСХОДЯЩИХ фронтов с использованием прерывания вообще не является точным

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

#define PWM 9
#define DINS 2
volatile int counter = 0;
int delaycounter = 0;
int lastcount = 0;
int newcount = 0;
int countCounter = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(PWM, OUTPUT);
  pinMode(DINS, INPUT);
  attachInterrupt(digitalPinToInterrupt(DINS), readEncoder, RISING);
}

void loop() {
  // put your main code here, to run repeatedly:
  analogWrite(PWM,50);
  int value = digitalRead(DINS);
  
  if (delaycounter == 1000){
    lastcount = counter;
    newcount = (newcount + counter) / 2;
    //Serial.print(counter);
    counter = 0;
    delaycounter = 0;
    countCounter++;
  }else{
    lastcount = 0;
  }
  delaycounter = delaycounter + 2 ;

  //Serial.print(delaycounter);
  //Serial.print(" ");
  Serial.print(value);
  Serial.print(" ");
  Serial.print(counter/2);
  Serial.print(" ");
  //Serial.print(lastcount);
  //Serial.print(" ");
  //Serial.print(newcount);
  Serial.println();
  delay(2);
}

void readEncoder(){
  counter++;
}

Проблема в том, что счетчик в ISR подсчитывает больше, чем количество ВОСХОДЯЩИХ фронтов, я просто хочу, чтобы значение счетчика увеличилось на единицу, но вместо этого оно увеличивается в несколько раз даже при ПАДАЮЩЕМ фронте импульса, как в этом серийном плоттере:

Я пробовал другие решения, такие как использование millis() и переменной last_time для отслеживания времени сброса счетчика, но результаты были теми же.

Редактирование 1: Я открыл последовательный монитор, и вот значения, которые он считывает, он добавляет на 1 или на 2 случайным образом по ПАДАЮЩЕМУ краю, в то время как он должен считать только единицы и по ВОСХОДЯЩЕМУ краю:

, 👍0

Обсуждение

Удаление лопасти может привести к разбалансировке вентилятора. Проверьте выходной сигнал вашего датчика с помощью измерительного прибора. Что происходит с напряжением, когда вы медленно поворачиваете вентилятор?, @Abel

Я проверю это сейчас, однако показания датчика находятся в нижней части графика, но они крошечные из-за масштабирования, и они показывают, что вентилятор работает стабильно, кроме того, я сделал деревянную раму для вентилятора, чтобы свести к минимуму тряску даже на высоких скоростях. @Абель, @Joubran Al-maarry

Итак, у вас есть вентилятор, у которого нет зазоров между лопастями? Так как же тогда это работает? Может быть, вам следует считать только * широкий * разрыв ...?, @Majenko

что ж, лопасти вентиляторов расположены под таким углом, что независимо от того, как расположен датчик, он будет показывать 0, что означает, что на его пути есть объект, что связано с природой обнаружения предметов, которые отражаются от инфракрасного луча, поэтому он может обнаруживать отражение со стороны лысого, а также вентиляторы вращаются достаточно быстро, чтобы датчик не смог их уловить. @Majenko, @Joubran Al-maarry

И подтвердили ли вы, что на практике это действительно так? Или ты просто предполагаешь, что это правда?, @Majenko

у вас тоже есть countCounter ++ в loop(), @Juraj

Да, я не думал, что это имеет значение в сообщении о типе вентилятора, который я использую, но это вентилятор охлаждения процессора, поэтому расстояние между 7 лопастями крошечное, должен ли я приложить изображение настройки для дальнейшего уточнения? @Majenko, @Joubran Al-maarry

этот счетчик предназначен для подсчета подсчетов, я знаю, что должен был назвать его как-то по-другому, но я хотел вычислить среднее значение, поэтому мне нужен счетчик для деления сумм. @Юрай, @Joubran Al-maarry

вы спросили, почему это "счет 2". Я предполагаю, вы задаетесь вопросом, почему он подскочил с 21 до 23, @Juraj

Я исправлю это, спасибо @Juraj, и извините за плохой английский., @Joubran Al-maarry

извлекать лезвие бессмысленно ... просто разделите количество импульсов на количество лопастей, @jsotola

хотя я ценю все ваши отзывы, я хочу сказать следующее: проблема связана с программным обеспечением, удаление лезвия не является проблемой по двум причинам: 1. вентилятор находится в деревянной раме, поэтому он стабилен, 2. отрезание лезвия было единственным способом получить какие-либо данные о пространстве между вентиляторы плотно прилегают, поэтому 30-градусный диапазон обнаружения ИК-датчика улавливает окружающие лопасти, я попробовал, и он продолжает выдавать нули даже при низкой скорости ~ 800 об / мин. @jsotola, @Joubran Al-maarry

положите кусок светоотражающей ленты на одно из лезвий ... кусок алюминиевой фольги должен подойти, @jsotola

Если это вентилятор охлаждения процессора, то, несомненно, он имеет встроенный импульсный выход от собственного датчика эффекта Холла..., @Majenko

Не могли бы вы проверить сигнал DINS на оптическом прицеле?, @Edgar Bonet