0

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

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

磁性拾音器图像: MP - 自供电

我尝试使用二极管对信号进行整流,然后使用带有 .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(" ");
}

使用analogueReadLED 作为拾取器产生的脉冲的指示器。(测试使用小电机和小齿轮保护Arduino)。

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

LM139电路

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 的最佳方式或方法是什么?

4

1 回答 1

0

您对 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);
}
于 2017-08-13T17:50:08.003 回答