【问题标题】:Arduino Interfacing with Magnetic PickupArduino 与磁性拾音器的接口
【发布时间】:2017-08-13 14:11:52
【问题描述】:

目前我有一台带有磁性拾音器的柴油发动机。我想使用 Arduino (Uno/Nano) 来测量发动机转速。

磁性拾音器 描述:磁性拾音器安装在齿轮上(最常见的是车辆钟形外壳内的飞轮),当齿轮转动时,拾音器将为齿轮上的每个齿产生一个电脉冲。然后仪器读取这些脉冲,将其解释为正确的 RPM 或速度。来自磁速传感器的信号,每秒齿数 (HZ),与发动机速度成正比。

磁性拾音器图像: MP - Self Powered

我尝试使用二极管对信号进行整流,然后使用带有 .1Uf 电容器的电阻器来限制电流以过滤噪声,然后将其连接到 Optocopler 4N35 以及从 Opto 到 Arduino 中断引脚的输出,只需观察 Arduino 中断ping受环境影响很大。

我还尝试将磁性拾音器直接连接到“A0”引脚并使用模拟读取并将 LED 连接到引脚 13 以监控 MP 的脉冲。

int sensorPin = A0;    
int ledPin = 13;      
int sensorValue = 0;  

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  digitalWrite(ledPin, HIGH);
  delay(sensorValue);
  digitalWrite(ledPin, LOW);
  Serial.println(sensorValue);
  Serial.println(" ");
}

使用analogueRead 与 LED 一起用作拾取器产生的脉冲的指示器。 (测试使用小电机和小齿轮保护Arduino)。

我也尝试使用 LM139 比较器,但读数没有意义 (例如:60 RPM、1500 RPM、2150 RPM、7150 RPM)。

LM139 Circuit

LM139 使用的代码:

// read RPM
volatile int rpmcount = 0;
//see http://arduino.cc/en/Reference/Volatile
int rpm = 0;
unsigned long lastmillis = 0;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, rpm_fan, RISING);
  //interrupt cero (0) is on pin two(2).
}

void loop() {
  if (millis() - lastmillis == 500) {
    /*Update every one second, this will be equal to reading frequency (Hz).*/
    detachInterrupt(0); //Disable interrupt when calculating
    rpm = rpmcount * 60;
    /* Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrupts per full rotation use rpmcount * 30.*/
    Serial.print(rpm); // print the rpm value.
    Serial.println(" ");
    rpmcount = 0; // Restart the RPM counter
    lastmillis = millis(); // Update lastmillis
    attachInterrupt(0, rpm_fan, RISING); //enable interrupt
  }
}

void rpm_fan() {
  /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmcount++;
}
// Elimelec Lopez - April 25th 2013

将磁性拾音器与 Arduino 连接以显示 RPM 的最佳方式或方法是什么?

【问题讨论】:

    标签: arduino microcontroller interfacing


    【解决方案1】:

    您对analogRead 的使用是错误的。此外,analogRead 不会让您接近您想要实现的目标。

    您想要的皮卡是清晰的 0-5v 数字信号。您可以通过使用光耦合器上的输入电阻来获得它。我会做一些测量,并在板上放置一个微调电位器+电阻器,以便在安装系统后调整实际值。

    一旦您获得尽可能干净的电信号,您就可以使用 Arduino 上的中断引脚来记录脉冲数。

    #define SENSOR_PIN  (2)    // using define instead of variable for constants save memory.
    #define LED_PIN     (13)
    
    #define READ_DELAY  (100)  // in milliseconds.
    
    // we'll get a reading every 100ms, so 8 bits are enough to keep
    // track of time.  You'd have to widen to unsigned int if you want 
    // READ_DELAY to exceed 255 ms.
    // 
    typedef delay_type unsigned char;
    
    typedef unsigned int counter_type;  // You may want to use 
                                        // unsigned long, if you 
                                        // experience overflows.
    
    volatile counter_type pulseCount = 0; // volatile is important here
    
    counter_type lastCount = 0;
    delay_type lastTime = 0;
    
    // pulse interrupt callback, keep short.
    void onSensorPulse()
    {
        ++pulseCount;
    
        // the following may already be too long.  Use for debugging only
        // digitalWrite() and digitalRead() are notoriously slow.
        // 
        // 
        // digitalWrite(LED_PIN, !digitalRead(LED_PIN));
        //
        // using fastest direct port access instead. (for ATMega)
        //
        if (pulseCount & 1)
            PORTB |= (1 << PB5);
        else
            PORTB &= ~(1 << PB5);
    }
    
    void setup() 
    {
        pinMode(SENSOR_PIN, INPUT);
        attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), onSensorPulse, RISING);
    
        pinMode(ledPin, OUTPUT);
        Serial.begin(9600);
    }
    
    void loop() 
    {
        // control frequency of readings
        //
        delay_type now = (delay_type)millis();
        if (now - lastTime < READ_DELAY)
        {
            return;
        }
        lastTime = now;
    
        // get a reading.  must disable interrupts while doing so.
        // because pulseCount is multi-bytes.
        //
        noInterrupts();
        counter_type curCount = pulseCount;
        interrupts();
    
        // get the number of pulses since last reading.
        //
        counter_type delta = curCount - lastCount;
        lastCount = curCount;
    
        // to convert to RPMs, you will need to use this formula:
        // note the use of long (UL) to avoid overflows in the
        // computation.  60000 = miliseconds per minute.
        //
        // RPM = delta * 60000UL / (READ_DELAY * TEETH_COUNT);
    
        // send delta to client for now.
        //
        Serial.println(delta);
    }
    

    【讨论】:

    • link 这是关于 MP 传感器输出信号的视频,我应该怎么做才能使其达到 0-5 V
    • 您提供的 LM319 原理图应该会给您很好的脉冲,但电噪声可能会给您带来不需要的短尖峰。您需要添加一个低通滤波器来去除那些与信号无关的尖峰。我认为你得到的读数可能是由于溢出。您问题中提供的代码没有考虑齿轮上的齿数,因此您获得的 RPM 被过度放大了。使用 ADC,使用analogRead() 太慢,无法提供可靠的计数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多