Измерение оборотов в секунду с помощью геркона

Я пытаюсь измерить скорость маховика герконом с одним магнитом (1 импульс на полный оборот). У меня есть крышка 100nf, подключенная к переключателю, чтобы помочь с устранением дребезга.

#include <Arduino.h>

int speedPin = 2; // переключатель подключен к контакту 2
int ledPin = 13;

int debounceTime = 7;

long speedPulseTime = 0;
int speedPulseCount = 0;
int speed = 0;
long speedLastSample = 0;

long serialLastReport = 0;
int serialReportFreq = 40;

void speedPulse()
{
  long time = millis();
  if ((speedPulseTime + debounceTime) < time)
  {
    speedPulseCount++;
    speedPulseTime = time;
  }
}

void setup()
{
  pinMode(ledPin, OUTPUT);

  pinMode(speedPin, INPUT_PULLUP);     // Устанавливаем контакт переключателя в качестве входа
  attachInterrupt(digitalPinToInterrupt(speedPin), speedPulse, HIGH);

  Serial.begin(115200);
  Serial.println("Ready...");
}


void loop()
{
  long time = micros();
  if (speedPulseCount >= 4 || (speedLastSample + 1500000) < time)
  {
    detachInterrupt(speedPin);
    int tempSpeed = 1000000 / ((time - speedLastSample) / speedPulseCount);
    if (tempSpeed < 0)
    {
      speed = 0;
    }
    else
    {
      speed = tempSpeed;
    }

    //сбросить образец
    speedLastSample = time;
    speedPulseCount = 0;
    attachInterrupt(digitalPinToInterrupt(speedPin), speedPulse, HIGH);
  }

  if ((serialLastReport + serialReportFreq) < millis())
  {
    Serial.print(millis());
    Serial.print(",");
    Serial.println(speed);
    serialLastReport = millis();
  }
}

Вот код, который у меня есть. Проблема у меня немного прыгает. Что я могу изменить, чтобы обеспечить более точные показания?

, 👍1

Обсуждение

Можете ли вы более точно указать (отредактировав свой пост), что «немного прыгает»? Как написано, можно предположить, что это был ваш код, который прыгал., @MichaelT


1 ответ


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

2

Похоже на случайные промахи. Возможные причины включают:

  • магнит проходит достаточно далеко от геркона, чтобы «всего лишь» вызвать его [уменьшить зазор.];
  • проход магнита слишком короткий для срабатывания геркона/конденсатора [используйте более широкий магнит или переместите его ближе к центру вращения];
  • Слишком большая емкость [уменьшите ее или устраните дребезг в программном обеспечении];

Обновление:

Не лучше ли устранить дребезг в программном обеспечении и как лучше всего это сделать.

Если у вас есть осциллограф, вы можете посмотреть на необработанный сигнал переключателя (без конденсатора), чтобы узнать, как долго он дребезжит. Я предполагаю, что для такого маленького переключателя это будет около 10 мс. Если вся последовательность [make/break/make/break....] занимает менее 50 % (при консервативном подходе) времени вращения колеса (1/max_RPS), вы, вероятно, можете подсчитать первый импульс и игнорировать переключатель в течение ( 0,5/max_RPS), или 1/2 от самой быстрой ротации. Похоже, вы уже занимаетесь чем-то подобным. Если вы хотите быть немного более строгим, вы можете сделать следующее:

see a HIGH;
ignore switch for debounce_time;
if still HIGH,
   count++;

Кроме того, не забывайте, что переменные, общие для вашей функции прерывания и основного кода, должны быть:

  1. объявлено как volatile, чтобы компилятор не ожидал, что эта переменная имеет значение, которое она имела в прошлый раз, когда основной код читал ее; и

  2. Ненадолго отключите прерывания при чтении или записи такой переменной (если она многобайтовая) в вашей основной ветке, чтобы предотвратить ее изменение функцией прерывания между операциями чтения/записи байтов основной веткой.

,

Будет ли лучше устранить дребезг в программном обеспечении и как это лучше всего сделать. У меня уже есть небольшое устранение дребезга в программном обеспечении, подойдет ли оно?, @Samuel Taylor