Arduino与磁性拾音器接口

时间:2017-08-13 14:11:53

标签: arduino microcontroller interfacing

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

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

磁性拾取图像:  MP - Self Powered

我试图用二极管整流信号,然后使用带有.1Uf电容的电阻限制电流来滤除噪声,然后通过观察Arduino中断将其连接到Optocopler 4N35和Opto到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的最佳方式或方法是什么?

1 个答案:

答案 0 :(得分: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);
}